Merge
authoramurillo
Tue, 05 Jan 2016 13:08:02 -0800
changeset 35083 74806cb88a69
parent 34859 4379223f8806 (current diff)
parent 35082 48c95c24f175 (diff)
child 35161 2429124c1755
child 35455 5c91d153e9da
Merge
hotspot/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetCount.java
hotspot/src/share/vm/gc/g1/g1ErgoVerbose.cpp
hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp
hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp
hotspot/src/share/vm/gc/g1/g1Log.cpp
hotspot/src/share/vm/gc/g1/g1Log.hpp
hotspot/test/gc/6941923/Test6941923.java
hotspot/test/gc/TestGCLogRotationViaJcmd.java
hotspot/test/gc/g1/TestPrintGCDetails.java
hotspot/test/gc/g1/TestSummarizeRSetStats.java
hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java
hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java
hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Jan 05 13:08:02 2016 -0800
@@ -49,7 +49,7 @@
 #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
 #endif
 
-#ifdef ppc64
+#if defined(ppc64) || defined(ppc64le)
 #include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
 #endif
 
@@ -223,9 +223,12 @@
   verifyBitness(env, (char *) &buf);
   CHECK_EXCEPTION;
 
+  char err_buf[200];
   struct ps_prochandle* ph;
-  if ( (ph = Pgrab(jpid)) == NULL) {
-    THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+  if ( (ph = Pgrab(jpid, err_buf, sizeof(err_buf))) == NULL) {
+    char msg[230];
+    snprintf(msg, sizeof(msg), "Can't attach to the process: %s", err_buf);
+    THROW_NEW_DEBUGGER_EXCEPTION(msg);
   }
   (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
   fillThreadsAndLoadObjects(env, this_obj, ph);
@@ -349,7 +352,7 @@
   return (err == PS_OK)? array : 0;
 }
 
-#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(aarch64)
+#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) || defined(ppc64le) || defined(aarch64)
 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
   (JNIEnv *env, jobject this_obj, jint lwp_id) {
 
@@ -377,7 +380,7 @@
 #if defined(sparc) || defined(sparcv9)
 #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
 #endif
-#ifdef ppc64
+#if defined(ppc64) || defined(ppc64le)
 #define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG
 #endif
 
@@ -486,7 +489,7 @@
   }
 #endif /* aarch64 */
 
-#ifdef ppc64
+#if defined(ppc64) || defined(ppc64le)
 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg
 
   regs[REG_INDEX(LR)] = gregs.link;
--- a/hotspot/agent/src/os/linux/libproc.h	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/os/linux/libproc.h	Tue Jan 05 13:08:02 2016 -0800
@@ -68,7 +68,8 @@
 *************************************************************************************/
 
 
-#if defined(sparc) || defined(sparcv9) || defined(ppc64)
+#if defined(sparc) || defined(sparcv9) || defined(ppc64) || defined(ppc64le)
+#include <asm/ptrace.h>
 #define user_regs_struct  pt_regs
 #endif
 #if defined(aarch64)
@@ -86,7 +87,7 @@
 struct ps_prochandle;
 
 // attach to a process
-struct ps_prochandle* Pgrab(pid_t pid);
+struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len);
 
 // attach to a core dump
 struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
--- a/hotspot/agent/src/os/linux/ps_proc.c	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/os/linux/ps_proc.c	Tue Jan 05 13:08:02 2016 -0800
@@ -215,9 +215,12 @@
 }
 
 // attach to a process/thread specified by "pid"
-static bool ptrace_attach(pid_t pid) {
+static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) {
   if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
-    print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
+    char buf[200];
+    char* msg = strerror_r(errno, buf, sizeof(buf));
+    snprintf(err_buf, err_buf_len, "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, msg);
+    print_debug("%s\n", err_buf);
     return false;
   } else {
     return ptrace_waitpid(pid);
@@ -370,16 +373,17 @@
 };
 
 // attach to the process. One and only one exposed stuff
-struct ps_prochandle* Pgrab(pid_t pid) {
+struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
   struct ps_prochandle* ph = NULL;
   thread_info* thr = NULL;
 
   if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
-     print_debug("can't allocate memory for ps_prochandle\n");
+     snprintf(err_buf, err_buf_len, "can't allocate memory for ps_prochandle");
+     print_debug("%s\n", err_buf);
      return NULL;
   }
 
-  if (ptrace_attach(pid) != true) {
+  if (ptrace_attach(pid, err_buf, err_buf_len) != true) {
      free(ph);
      return NULL;
   }
@@ -402,7 +406,7 @@
   thr = ph->threads;
   while (thr) {
      // don't attach to the main thread again
-     if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id) != true) {
+    if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
         // even if one attach fails, we get return NULL
         Prelease(ph);
         return NULL;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Tue Jan 05 13:08:02 2016 -0800
@@ -125,10 +125,14 @@
     }
   }
 
-  // close this tool without calling System.exit
-  protected void closeUI() {
-      workerThread.shutdown();
-      frame.dispose();
+  private class CloseUI extends WindowAdapter {
+
+      @Override
+      public void windowClosing(WindowEvent e) {
+          workerThread.shutdown();
+          frame.dispose();
+      }
+
   }
 
   public void run() {
@@ -144,7 +148,8 @@
 
     frame = new JFrame("HSDB - HotSpot Debugger");
     frame.setSize(800, 600);
-    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+    frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+    frame.addWindowListener(new CloseUI());
 
     JMenuBar menuBar = new JMenuBar();
 
@@ -207,7 +212,8 @@
     item = createMenuItem("Exit",
                             new ActionListener() {
                                 public void actionPerformed(ActionEvent e) {
-                                  closeUI();
+                                  workerThread.shutdown();
+                                  frame.dispose();
                                 }
                               });
     item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK));
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/SAGetopt.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/SAGetopt.java	Tue Jan 05 13:08:02 2016 -0800
@@ -37,7 +37,7 @@
     private boolean _optreset; // special handling of first call
 
     public SAGetopt(String[] args) {
-        _argv  = args;
+        _argv  = args.clone();
         _optind   = 0;
         _optopt   = 1;
         _optarg   = null;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetBase.java	Tue Jan 05 13:08:02 2016 -0800
@@ -41,7 +41,8 @@
 
 public class HeapRegionSetBase extends VMObject {
 
-    static private long countField;
+    // uint _length
+    static private CIntegerField lengthField;
 
     static {
         VM.registerVMInitializedObserver(new Observer() {
@@ -54,13 +55,11 @@
     static private synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("HeapRegionSetBase");
 
-        countField = type.getField("_count").getOffset();
+        lengthField = type.getCIntegerField("_length");
     }
 
-
-    public HeapRegionSetCount count() {
-        Address countFieldAddr = addr.addOffsetTo(countField);
-        return (HeapRegionSetCount) VMObjectFactory.newObject(HeapRegionSetCount.class, countFieldAddr);
+    public long length() {
+        return lengthField.getValue(addr);
     }
 
     public HeapRegionSetBase(Address addr) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionSetCount.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2014, 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.
- *
- */
-
-package sun.jvm.hotspot.gc.g1;
-
-import java.util.Iterator;
-import java.util.Observable;
-import java.util.Observer;
-
-import sun.jvm.hotspot.debugger.Address;
-import sun.jvm.hotspot.runtime.VM;
-import sun.jvm.hotspot.runtime.VMObject;
-import sun.jvm.hotspot.runtime.VMObjectFactory;
-import sun.jvm.hotspot.types.AddressField;
-import sun.jvm.hotspot.types.CIntegerField;
-import sun.jvm.hotspot.types.Type;
-import sun.jvm.hotspot.types.TypeDataBase;
-
-// Mirror class for HeapRegionSetCount. Represents a group of regions.
-
-public class HeapRegionSetCount extends VMObject {
-
-    static private CIntegerField lengthField;
-    static private CIntegerField capacityField;
-
-    static {
-        VM.registerVMInitializedObserver(new Observer() {
-                public void update(Observable o, Object data) {
-                    initialize(VM.getVM().getTypeDataBase());
-                }
-            });
-    }
-
-    static private synchronized void initialize(TypeDataBase db) {
-        Type type = db.lookupType("HeapRegionSetCount");
-
-        lengthField   = type.getCIntegerField("_length");
-        capacityField = type.getCIntegerField("_capacity");
-    }
-
-    public long length() {
-        return lengthField.getValue(addr);
-    }
-
-    public long capacity() {
-        return capacityField.getValue(addr);
-    }
-
-    public HeapRegionSetCount(Address addr) {
-        super(addr);
-    }
-}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Tue Jan 05 13:08:02 2016 -0800
@@ -229,17 +229,17 @@
 
      public String getValue() {
         if (isBool()) {
-           return new Boolean(getBool()).toString();
+           return Boolean.toString(getBool());
         } else if (isInt()) {
-           return new Long(getInt()).toString();
+           return Long.toString(getInt());
         } else if (isUInt()) {
-           return new Long(getUInt()).toString();
+           return Long.toString(getUInt());
         } else if (isIntx()) {
-           return new Long(getIntx()).toString();
+           return Long.toString(getIntx());
         } else if (isUIntx()) {
-           return new Long(getUIntx()).toString();
+           return Long.toString(getUIntx());
         } else if (isSizet()) {
-            return new Long(getSizet()).toString();
+            return Long.toString(getSizet());
         } else {
            return null;
         }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Tue Jan 05 13:08:02 2016 -0800
@@ -112,8 +112,7 @@
           long survivorRegionNum = g1mm.survivorRegionNum();
           HeapRegionSetBase oldSet = g1h.oldSet();
           HeapRegionSetBase humongousSet = g1h.humongousSet();
-          long oldRegionNum = oldSet.count().length()
-                       + humongousSet.count().capacity() / HeapRegion.grainBytes();
+          long oldRegionNum = oldSet.length() + humongousSet.length();
           printG1Space("G1 Heap:", g1h.n_regions(),
                        g1h.used(), g1h.capacity());
           System.out.println("G1 Young Generation:");
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Tue Jan 05 13:08:02 2016 -0800
@@ -1921,6 +1921,15 @@
             buf.link(genPCHref(addressToLong(pc)), pc.toString());
          }
 
+         if (!method.isStatic() && !method.isNative()) {
+            OopHandle oopHandle = vf.getLocals().oopHandleAt(0);
+
+            if (oopHandle != null) {
+               buf.append(", oop = ");
+               buf.append(oopHandle.toString());
+            }
+         }
+
          if (vf.isCompiledFrame()) {
             buf.append(" (Compiled");
          }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java	Tue Jan 05 13:08:02 2016 -0800
@@ -54,7 +54,7 @@
 
   public static boolean knownCPU(String cpu) {
     final String[] KNOWN =
-        new String[] {"i386", "x86", "x86_64", "amd64", "sparc", "sparcv9", "ppc64", "aarch64"};
+        new String[] {"i386", "x86", "x86_64", "amd64", "sparc", "sparcv9", "ppc64", "ppc64le", "aarch64"};
 
     for(String s : KNOWN) {
       if(s.equals(cpu))
@@ -98,6 +98,9 @@
     if (cpu.equals("x86_64"))
       return "amd64";
 
+    if (cpu.equals("ppc64le"))
+      return "ppc64";
+
     return cpu;
 
   }
--- a/hotspot/make/defs.make	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/make/defs.make	Tue Jan 05 13:08:02 2016 -0800
@@ -277,7 +277,7 @@
 
   # Use uname output for SRCARCH, but deal with platform differences. If ARCH
   # is not explicitly listed below, it is treated as x86.
-  SRCARCH    ?= $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 ppc ppc64 aarch64 zero,$(ARCH)))
+  SRCARCH    ?= $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 ppc ppc64 ppc64le aarch64 zero,$(ARCH)))
   ARCH/       = x86
   ARCH/sparc  = sparc
   ARCH/sparc64= sparc
@@ -285,6 +285,7 @@
   ARCH/amd64  = x86
   ARCH/x86_64 = x86
   ARCH/ppc64  = ppc
+  ARCH/ppc64le= ppc
   ARCH/ppc    = ppc
   ARCH/aarch64= aarch64
   ARCH/zero   = zero
@@ -309,8 +310,13 @@
     endif
   endif
 
-  # LIBARCH is 1:1 mapping from BUILDARCH
-  LIBARCH        ?= $(LIBARCH/$(BUILDARCH))
+  # LIBARCH is 1:1 mapping from BUILDARCH, except for ARCH=ppc64le
+  ifeq ($(ARCH),ppc64le)
+    LIBARCH      ?= ppc64le
+  else
+    LIBARCH      ?= $(LIBARCH/$(BUILDARCH))
+  endif
+
   LIBARCH/i486    = i386
   LIBARCH/amd64   = amd64
   LIBARCH/sparc   = sparc
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -58,14 +58,17 @@
 #define DEFAULT_STACK_YELLOW_PAGES (2)
 #define DEFAULT_STACK_RED_PAGES (1)
 #define DEFAULT_STACK_SHADOW_PAGES (4 DEBUG_ONLY(+5))
+#define DEFAULT_STACK_RESERVED_PAGES (0)
 
 #define MIN_STACK_YELLOW_PAGES 1
 #define MIN_STACK_RED_PAGES    1
 #define MIN_STACK_SHADOW_PAGES 1
+#define MIN_STACK_RESERVED_PAGES (0)
 
 define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
 define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES);
 define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES);
+define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES);
 
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
--- a/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/globalDefinitions_ppc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -36,4 +36,9 @@
 // The PPC CPUs are NOT multiple-copy-atomic.
 #define CPU_NOT_MULTIPLE_COPY_ATOMIC
 
+#if defined(COMPILER2) && defined(AIX)
+// Include Transactional Memory lock eliding optimization
+#define INCLUDE_RTM_OPT 1
+#endif
+
 #endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -44,14 +44,17 @@
 #define DEFAULT_STACK_YELLOW_PAGES (6)
 #define DEFAULT_STACK_RED_PAGES (1)
 #define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
+#define DEFAULT_STACK_RESERVED_PAGES (0)
 
 #define MIN_STACK_YELLOW_PAGES (1)
 #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
 #define MIN_STACK_SHADOW_PAGES (1)
+#define MIN_STACK_RESERVED_PAGES (0)
 
 define_pd_global(intx, StackYellowPages,      DEFAULT_STACK_YELLOW_PAGES);
 define_pd_global(intx, StackRedPages,         DEFAULT_STACK_RED_PAGES);
 define_pd_global(intx, StackShadowPages,      DEFAULT_STACK_SHADOW_PAGES);
+define_pd_global(intx, StackReservedPages,    DEFAULT_STACK_RESERVED_PAGES);
 
 // Use large code-entry alignment.
 define_pd_global(intx, CodeEntryAlignment,    128);
--- a/hotspot/src/cpu/ppc/vm/metaspaceShared_ppc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/metaspaceShared_ppc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -50,12 +50,29 @@
 // to be 'vtbl_list_size' instances of the vtable in order to
 // differentiate between the 'vtable_list_size' original Klass objects.
 
+#define __ masm->
+
 void MetaspaceShared::generate_vtable_methods(void** vtbl_list,
                                               void** vtable,
                                               char** md_top,
                                               char* md_end,
                                               char** mc_top,
                                               char* mc_end) {
-  Unimplemented();
+  intptr_t vtable_bytes = (num_virtuals * vtbl_list_size) * sizeof(void*);
+  *(intptr_t *)(*md_top) = vtable_bytes;
+  *md_top += sizeof(intptr_t);
+  void** dummy_vtable = (void**)*md_top;
+  *vtable = dummy_vtable;
+  *md_top += vtable_bytes;
+
+  // Get ready to generate dummy methods.
+
+  CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
+  MacroAssembler* masm = new MacroAssembler(&cb);
+
+  // There are more general problems with CDS on ppc, so I can not
+  // really test this. But having this instead of Unimplementd() allows
+  // us to pass TestOptionsWithRanges.java.
+  __ unimplemented();
 }
 
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -210,12 +210,27 @@
   }
 
   // Adjust RTM (Restricted Transactional Memory) flags.
-  if (!has_tcheck() && UseRTMLocking) {
+  if (UseRTMLocking) {
+    // If CPU or OS are too old:
     // Can't continue because UseRTMLocking affects UseBiasedLocking flag
     // setting during arguments processing. See use_biased_locking().
     // VM_Version_init() is executed after UseBiasedLocking is used
     // in Thread::allocate().
-    vm_exit_during_initialization("RTM instructions are not available on this CPU");
+    if (!has_tcheck()) {
+      vm_exit_during_initialization("RTM instructions are not available on this CPU");
+    }
+    bool os_too_old = true;
+#ifdef AIX
+    if (os::Aix::os_version() >= 0x0701031e) { // at least AIX 7.1.3.30
+      os_too_old = false;
+    }
+#endif
+#ifdef linux
+    // TODO: check kernel version (we currently have too old versions only)
+#endif
+    if (os_too_old) {
+      vm_exit_during_initialization("RTM is not supported on this OS version.");
+    }
   }
 
   if (UseRTMLocking) {
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1453,6 +1453,9 @@
 
 
 void LIR_Assembler::return_op(LIR_Opr result) {
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
   // the poll may need a register so just pick one that isn't the return register
 #if defined(TIERED) && !defined(_LP64)
   if (result->type_field() == LIR_OprDesc::long_type) {
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -632,7 +632,7 @@
 
   // stack frames shouldn't be much larger than max_stack elements
 
-  if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
+  if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
     return false;
   }
 
--- a/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/globalDefinitions_sparc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -54,4 +54,8 @@
   #endif
 #endif
 
+#if defined(SOLARIS)
+#define SUPPORT_RESERVED_STACK_AREA
+#endif
+
 #endif // CPU_SPARC_VM_GLOBALDEFINITIONS_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -54,6 +54,7 @@
 
 #define DEFAULT_STACK_YELLOW_PAGES (2)
 #define DEFAULT_STACK_RED_PAGES (1)
+#define DEFAULT_STACK_RESERVED_PAGES (SOLARIS_ONLY(1) NOT_SOLARIS(0))
 
 #ifdef _LP64
 // Stack slots are 2X larger in LP64 than in the 32 bit VM.
@@ -69,10 +70,12 @@
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
 #define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
+#define MIN_STACK_RESERVED_PAGES (0)
 
 define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
 define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES);
 define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES);
+define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES);
 
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1140,6 +1140,19 @@
   // save result (push state before jvmti call and pop it afterwards) and notify jvmti
   notify_method_exit(false, state, NotifyJVMTI);
 
+  if (StackReservedPages > 0) {
+    // testing if Stack Reserved Area needs to be re-enabled
+    Label no_reserved_zone_enabling;
+    ld_ptr(G2_thread, JavaThread::reserved_stack_activation_offset(), G3_scratch);
+    cmp_and_brx_short(SP, G3_scratch, Assembler::lessUnsigned, Assembler::pt, no_reserved_zone_enabling);
+
+    call_VM_leaf(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), G2_thread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError), G2_thread);
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
+
   interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
   verify_thread();
 
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -3601,6 +3601,24 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check() {
+  // testing if reserved zone needs to be enabled
+  Label no_reserved_zone_enabling;
+
+  ld_ptr(G2_thread, JavaThread::reserved_stack_activation_offset(), G4_scratch);
+  cmp_and_brx_short(SP, G4_scratch, Assembler::lessUnsigned, Assembler::pt, no_reserved_zone_enabling);
+
+  call_VM_leaf(L0, CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), G2_thread);
+
+  AddressLiteral stub(StubRoutines::throw_delayed_StackOverflowError_entry());
+  jump_to(stub, G4_scratch);
+  delayed()->restore();
+
+  should_not_reach_here();
+
+  bind(no_reserved_zone_enabling);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////
 #if INCLUDE_ALL_GCS
 
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1422,6 +1422,9 @@
   // stack overflow + shadow pages.  Clobbers tsp and scratch registers.
   void bang_stack_size(Register Rsize, Register Rtsp, Register Rscratch);
 
+  // Check for reserved stack access in method being exited (for JIT)
+  void reserved_stack_check();
+
   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset);
 
   void verify_tlab();
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Jan 05 13:08:02 2016 -0800
@@ -1294,6 +1294,10 @@
 
   __ verify_thread();
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   // If this does safepoint polling, then do it here
   if(do_polling() && ra_->C->is_method_compilation()) {
     AddressLiteral polling_page(os::get_polling_page());
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -5355,7 +5355,12 @@
 #endif  // COMPILER2 !=> _LP64
 
     // Build this early so it's available for the interpreter.
-    StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",           CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_StackOverflowError_entry =
+            generate_throw_exception("StackOverflowError throw_exception",
+            CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_delayed_StackOverflowError_entry =
+            generate_throw_exception("delayed StackOverflowError throw_exception",
+            CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError));
 
     if (UseCRC32Intrinsics) {
       // set table address before stub generation which use it
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,7 +35,10 @@
 unsigned int VM_Version::_L2_data_cache_line_size = 0;
 
 void VM_Version::initialize() {
-  _features = determine_features();
+
+  assert(_features != VM_Version::unknown_m, "System pre-initialization is not complete.");
+  guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
+
   PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
   PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
   PrefetchFieldsAhead         = prefetch_fields_ahead();
@@ -60,8 +63,6 @@
     FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
   }
 
-  guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
-
   UseSSE = 0; // Only on x86 and x64
 
   _supports_cx8 = has_v9();
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -127,6 +127,8 @@
   // Initialization
   static void initialize();
 
+  static void init_before_ergo()        { _features = determine_features(); }
+
   // Instruction support
   static bool has_v8()                  { return (_features & v8_instructions_m) != 0; }
   static bool has_v9()                  { return (_features & v9_instructions_m) != 0; }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -518,6 +518,10 @@
   // Pop the stack before the safepoint code
   __ remove_frame(initial_frame_size_in_bytes());
 
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   bool result_is_oop = result->is_valid() ? result->is_oop() : false;
 
   // Note: we do not need to round double result; float result has the right precision
--- a/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/globalDefinitions_x86.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -57,4 +57,8 @@
 #define INCLUDE_RTM_OPT 1
 #endif
 
+#if defined(LINUX) || defined(SOLARIS) || defined(__APPLE__)
+#define SUPPORT_RESERVED_STACK_AREA
+#endif
+
 #endif // CPU_X86_VM_GLOBALDEFINITIONS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -57,9 +57,11 @@
 
 #define DEFAULT_STACK_YELLOW_PAGES (NOT_WINDOWS(2) WINDOWS_ONLY(3))
 #define DEFAULT_STACK_RED_PAGES (1)
+#define DEFAULT_STACK_RESERVED_PAGES (NOT_WINDOWS(1) WINDOWS_ONLY(0))
 
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
+#define MIN_STACK_RESERVED_PAGES (0)
 
 #ifdef AMD64
 // Very large C++ stack frames using solaris-amd64 optimized builds
@@ -76,6 +78,7 @@
 define_pd_global(intx, StackYellowPages, DEFAULT_STACK_YELLOW_PAGES);
 define_pd_global(intx, StackRedPages, DEFAULT_STACK_RED_PAGES);
 define_pd_global(intx, StackShadowPages, DEFAULT_STACK_SHADOW_PAGES);
+define_pd_global(intx, StackReservedPages, DEFAULT_STACK_RESERVED_PAGES);
 
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1023,6 +1023,25 @@
   // get sender sp
   movptr(rbx,
          Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));
+  if (StackReservedPages > 0) {
+    // testing if reserved zone needs to be re-enabled
+    Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
+    Label no_reserved_zone_enabling;
+
+    NOT_LP64(get_thread(rthread);)
+
+    cmpptr(rbx, Address(rthread, JavaThread::reserved_stack_activation_offset()));
+    jcc(Assembler::lessEqual, no_reserved_zone_enabling);
+
+    call_VM_leaf(
+      CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
+    push(rthread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address,
+                   InterpreterRuntime::throw_delayed_StackOverflowError));
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
   leave();                           // remove frame anchor
   pop(ret_addr);                     // get return address
   mov(rsp, rbx);                     // set sp to sender sp
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1067,6 +1067,22 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check() {
+    // testing if reserved zone needs to be enabled
+    Label no_reserved_zone_enabling;
+    Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread);
+    NOT_LP64(get_thread(rsi);)
+
+    cmpptr(rsp, Address(thread, JavaThread::reserved_stack_activation_offset()));
+    jcc(Assembler::below, no_reserved_zone_enabling);
+
+    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), thread);
+    jump(RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()));
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+}
+
 int MacroAssembler::biased_locking_enter(Register lock_reg,
                                          Register obj_reg,
                                          Register swap_reg,
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -641,6 +641,9 @@
   // stack overflow + shadow pages.  Also, clobbers tmp
   void bang_stack_size(Register size, Register tmp);
 
+  // Check for reserved stack access in method being exited (for JIT)
+  void reserved_stack_check();
+
   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
                                                 Register tmp,
                                                 int offset);
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -3290,7 +3290,10 @@
                                                                                    CAST_FROM_FN_PTR(address, SharedRuntime::d2l));
 
     // Build this early so it's available for the interpreter
-    StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",           CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",
+                                                                                      CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_delayed_StackOverflowError_entry  = generate_throw_exception("delayed StackOverflowError throw_exception",
+                                                                                      CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError));
 
     if (UseCRC32Intrinsics) {
       // set table address before stub generation which use it
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -4410,6 +4410,11 @@
                                CAST_FROM_FN_PTR(address,
                                                 SharedRuntime::
                                                 throw_StackOverflowError));
+    StubRoutines::_throw_delayed_StackOverflowError_entry =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address,
+                                                SharedRuntime::
+                                                throw_delayed_StackOverflowError));
     if (UseCRC32Intrinsics) {
       // set table address before stub generation which use it
       StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -541,8 +541,8 @@
   __ subptr(rax, stack_size);
 
   // Use the maximum number of pages we might bang.
-  const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages :
-                                                                              (StackRedPages+StackYellowPages);
+  const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages+StackReservedPages) ? StackShadowPages :
+                        (StackRedPages+StackYellowPages+StackReservedPages);
 
   // add in the red and yellow zone sizes
   __ addptr(rax, max_pages * page_size);
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Jan 05 13:08:02 2016 -0800
@@ -670,17 +670,16 @@
 
 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   Compile *C = ra_->C;
+  MacroAssembler _masm(&cbuf);
 
   if (C->max_vector_size() > 16) {
     // Clear upper bits of YMM registers when current compiled code uses
     // wide vectors to avoid AVX <-> SSE transition penalty during call.
-    MacroAssembler masm(&cbuf);
-    masm.vzeroupper();
+    _masm.vzeroupper();
   }
   // If method set FPU control word, restore to standard control word
   if (C->in_24_bit_fp_mode()) {
-    MacroAssembler masm(&cbuf);
-    masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
+    _masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
   }
 
   int framesize = C->frame_size_in_bytes();
@@ -702,6 +701,10 @@
 
   emit_opcode(cbuf, 0x58 | EBP_enc);
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   if (do_polling() && C->is_method_compilation()) {
     cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
     emit_opcode(cbuf,0x85);
@@ -729,6 +732,7 @@
   } else {
     size += framesize ? 3 : 0;
   }
+  size += 64; // added to support ReservedStackAccess
   return size;
 }
 
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Jan 05 13:08:02 2016 -0800
@@ -953,10 +953,11 @@
 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
 {
   Compile* C = ra_->C;
+  MacroAssembler _masm(&cbuf);
+
   if (C->max_vector_size() > 16) {
     // Clear upper bits of YMM registers when current compiled code uses
     // wide vectors to avoid AVX <-> SSE transition penalty during call.
-    MacroAssembler _masm(&cbuf);
     __ vzeroupper();
   }
 
@@ -984,6 +985,10 @@
   // popq rbp
   emit_opcode(cbuf, 0x58 | RBP_enc);
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check(); 
+  }
+
   if (do_polling() && C->is_method_compilation()) {
     MacroAssembler _masm(&cbuf);
     AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -48,14 +48,17 @@
 #define DEFAULT_STACK_YELLOW_PAGES (2)
 #define DEFAULT_STACK_RED_PAGES (1)
 #define DEFAULT_STACK_SHADOW_PAGES (5 LP64_ONLY(+1) DEBUG_ONLY(+3))
+#define DEFAULT_STACK_RESERVED_PAGES (0)
 
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES DEFAULT_STACK_RED_PAGES
 #define MIN_STACK_SHADOW_PAGES DEFAULT_STACK_SHADOW_PAGES
+#define MIN_STACK_RESERVED_PAGES (0)
 
 define_pd_global(intx,  StackYellowPages,     DEFAULT_STACK_YELLOW_PAGES);
 define_pd_global(intx,  StackRedPages,        DEFAULT_STACK_RED_PAGES);
 define_pd_global(intx,  StackShadowPages,     DEFAULT_STACK_SHADOW_PAGES);
+define_pd_global(intx,  StackReservedPages,   DEFAULT_STACK_RESERVED_PAGES);
 
 define_pd_global(bool,  RewriteBytecodes,     true);
 define_pd_global(bool,  RewriteFrequentPairs, true);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -170,7 +170,7 @@
      * @return flags of this method
      */
     private int getFlags() {
-        return UNSAFE.getByte(metaspaceMethod + config().methodFlagsOffset);
+        return UNSAFE.getShort(metaspaceMethod + config().methodFlagsOffset);
     }
 
     /**
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Tue Jan 05 13:08:02 2016 -0800
@@ -1244,7 +1244,7 @@
     @HotSpotVMField(name = "Method::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int methodAccessFlagsOffset;
     @HotSpotVMField(name = "Method::_constMethod", type = "ConstMethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodConstMethodOffset;
     @HotSpotVMField(name = "Method::_intrinsic_id", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int methodIntrinsicIdOffset;
-    @HotSpotVMField(name = "Method::_flags", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodFlagsOffset;
+    @HotSpotVMField(name = "Method::_flags", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int methodFlagsOffset;
     @HotSpotVMField(name = "Method::_vtable_index", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodVtableIndexOffset;
 
     @HotSpotVMConstant(name = "Method::_jfr_towrite") @Stable public int methodFlagsJfrTowrite;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/aix/vm/libodm_aix.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015, 2015 SAP AG. 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 "libodm_aix.hpp"
+#include "misc_aix.hpp"
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include "runtime/arguments.hpp"
+
+
+dynamicOdm::dynamicOdm() {
+  const char *libodmname = "/usr/lib/libodm.a(shr_64.o)";
+  _libhandle = dlopen(libodmname, RTLD_MEMBER | RTLD_NOW);
+  if (!_libhandle) {
+    trcVerbose("Couldn't open %s", libodmname);
+    return;
+  }
+  _odm_initialize  = (fun_odm_initialize )dlsym(_libhandle, "odm_initialize" );
+  _odm_set_path    = (fun_odm_set_path   )dlsym(_libhandle, "odm_set_path"   );
+  _odm_mount_class = (fun_odm_mount_class)dlsym(_libhandle, "odm_mount_class");
+  _odm_get_obj     = (fun_odm_get_obj    )dlsym(_libhandle, "odm_get_obj"    );
+  _odm_terminate   = (fun_odm_terminate  )dlsym(_libhandle, "odm_terminate"  );
+  if (!_odm_initialize || !_odm_set_path || !_odm_mount_class || !_odm_get_obj || !_odm_terminate) {
+    trcVerbose("Couldn't find all required odm symbols from %s", libodmname);
+    dlclose(_libhandle);
+    _libhandle = NULL;
+    return;
+  }
+}
+
+dynamicOdm::~dynamicOdm() {
+  if (_libhandle) { dlclose(_libhandle); }
+}
+
+
+void odmWrapper::clean_data() { if (_data) { free(_data); _data = NULL; } }
+
+
+int odmWrapper::class_offset(char *field, bool is_aix_5)
+{
+  assert(has_class(), "initialization");
+  for (int i = 0; i < odm_class()->nelem; i++) {
+    if (strcmp(odm_class()->elem[i].elemname, field) == 0) {
+      int offset = odm_class()->elem[i].offset;
+      if (is_aix_5) { offset += LINK_VAL_OFFSET; }
+      return offset;
+    }
+  }
+  return -1;
+}
+
+
+void odmWrapper::determine_os_kernel_version(uint32_t* p_ver) {
+  int major_aix_version = ((*p_ver) >> 24) & 0xFF,
+      minor_aix_version = ((*p_ver) >> 16) & 0xFF;
+  assert(*p_ver, "must be initialized");
+
+  odmWrapper odm("product", "/usr/lib/objrepos"); // could also use "lpp"
+  if (!odm.has_class()) {
+    trcVerbose("try_determine_os_kernel_version: odm init problem");
+    return;
+  }
+  int voff, roff, moff, foff;
+  bool is_aix_5 = (major_aix_version == 5);
+  voff = odm.class_offset("ver", is_aix_5);
+  roff = odm.class_offset("rel", is_aix_5);
+  moff = odm.class_offset("mod", is_aix_5);
+  foff = odm.class_offset("fix", is_aix_5);
+  if (voff == -1 || roff == -1 || moff == -1 || foff == -1) {
+    trcVerbose("try_determine_os_kernel_version: could not get offsets");
+    return;
+  }
+  if (!odm.retrieve_obj("name='bos.mp64'")) {
+    trcVerbose("try_determine_os_kernel_version: odm_get_obj failed");
+    return;
+  }
+  int version, release, modification, fix_level;
+  do {
+    version      = odm.read_short(voff);
+    release      = odm.read_short(roff);
+    modification = odm.read_short(moff);
+    fix_level    = odm.read_short(foff);
+    trcVerbose("odm found version: %d.%d.%d.%d", version, release, modification, fix_level);
+    if (version >> 8 != 0 || release >> 8 != 0 || modification >> 8 != 0 || fix_level >> 8 != 0) {
+      trcVerbose("8 bit numbers expected");
+      return;
+    }
+  } while (odm.retrieve_obj());
+
+  if (version != major_aix_version || release != minor_aix_version) {
+    trcVerbose("version determined by odm does not match uname");
+    return;
+  }
+  *p_ver = version << 24 | release << 16 | modification << 8 | fix_level;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/aix/vm/libodm_aix.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015, 2015 SAP AG. 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.
+ *
+ */
+
+// Encapsulates the libodm library and provides more convenient interfaces.
+
+#ifndef OS_AIX_VM_LIBODM_AIX_HPP
+#define OS_AIX_VM_LIBODM_AIX_HPP
+
+#include <odmi.h>
+
+
+// The purpose of this code is to dynamically load the libodm library
+// instead of statically linking against it. The library is AIX-specific.
+// It only exists on AIX, not on PASE. In order to share binaries
+// between AIX and PASE, we can't directly link against it.
+
+typedef int          (*fun_odm_initialize )(void);
+typedef char*        (*fun_odm_set_path   )(char*);
+typedef CLASS_SYMBOL (*fun_odm_mount_class)(char*);
+typedef void*        (*fun_odm_get_obj    )(CLASS_SYMBOL, char*, void*, int);
+typedef int          (*fun_odm_terminate  )(void);
+
+class dynamicOdm {
+  void *_libhandle;
+ protected:
+  fun_odm_initialize  _odm_initialize;
+  fun_odm_set_path    _odm_set_path;
+  fun_odm_mount_class _odm_mount_class;
+  fun_odm_get_obj     _odm_get_obj;
+  fun_odm_terminate   _odm_terminate;
+ public:
+  dynamicOdm();
+  ~dynamicOdm();
+  bool odm_loaded() {return _libhandle != NULL; }
+};
+
+
+// We provide a more convenient interface for odm access and
+// especially to determine the exact AIX kernel version.
+
+class odmWrapper : private dynamicOdm {
+  CLASS_SYMBOL _odm_class;
+  char *_data;
+  bool _initialized;
+  void clean_data();
+
+ public:
+  // Make sure everything gets initialized and cleaned up properly.
+  explicit odmWrapper(char* odm_class_name, char* odm_path = NULL) : _odm_class((CLASS_SYMBOL)-1),
+                                                                     _data(NULL), _initialized(false) {
+    if (!odm_loaded()) { return; }
+    _initialized = ((*_odm_initialize)() != -1);
+    if (_initialized) {
+      if (odm_path) { (*_odm_set_path)(odm_path); }
+      _odm_class = (*_odm_mount_class)(odm_class_name);
+    }
+  }
+  ~odmWrapper() {
+    if (_initialized) { (*_odm_terminate)(); clean_data(); }
+  }
+
+  CLASS_SYMBOL odm_class() { return _odm_class; }
+  bool has_class() { return odm_class() != (CLASS_SYMBOL)-1; }
+  int class_offset(char *field, bool is_aix_5);
+  char* data() { return _data; }
+
+  char* retrieve_obj(char* name = NULL) {
+    clean_data();
+    char *cnp = (char*)(void*)(*_odm_get_obj)(odm_class(), name, NULL, (name == NULL) ? ODM_NEXT : ODM_FIRST);
+    if (cnp != (char*)-1) { _data = cnp; }
+    return data();
+  }
+
+  int read_short(int offs) {
+    short *addr = (short*)(data() + offs);
+    return *addr;
+  }
+
+  // Determine the exact AIX kernel version as 4 byte value.
+  // The high order 2 bytes must be initialized already. They can be determined by uname.
+  static void determine_os_kernel_version(uint32_t* p_ver);
+};
+
+#endif // OS_AIX_VM_LIBODM_AIX_HPP
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -38,6 +38,7 @@
 #include "jvm_aix.h"
 #include "libo4.hpp"
 #include "libperfstat_aix.hpp"
+#include "libodm_aix.hpp"
 #include "loadlib_aix.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
@@ -197,9 +198,13 @@
 // -1 = uninitialized, 0 if AIX, 1 if OS/400 pase
 int       os::Aix::_on_pase = -1;
 
-// -1 = uninitialized, otherwise os version in the form 0xMMmm - MM:major, mm:minor
-//  E.g. 0x0601 for  AIX 6.1 or 0x0504 for OS/400 V5R4
-int       os::Aix::_os_version = -1;
+// 0 = uninitialized, otherwise 32 bit number:
+//  0xVVRRTTSS
+//  VV - major version
+//  RR - minor version
+//  TT - tech level, if known, 0 otherwise
+//  SS - service pack, if known, 0 otherwise
+uint32_t  os::Aix::_os_version = 0;
 
 int       os::Aix::_stack_page_size = -1;
 
@@ -358,7 +363,7 @@
 
 // Wrap the function "vmgetinfo" which is not available on older OS releases.
 static int checked_vmgetinfo(void *out, int command, int arg) {
-  if (os::Aix::on_pase() && os::Aix::os_version() < 0x0601) {
+  if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {
     guarantee(false, "cannot call vmgetinfo on AS/400 older than V6R1");
   }
   return ::vmgetinfo(out, command, arg);
@@ -367,7 +372,7 @@
 // Given an address, returns the size of the page backing that address.
 size_t os::Aix::query_pagesize(void* addr) {
 
-  if (os::Aix::on_pase() && os::Aix::os_version() < 0x0601) {
+  if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {
     // AS/400 older than V6R1: no vmgetinfo here, default to 4K
     return SIZE_4K;
   }
@@ -1211,7 +1216,7 @@
 // Note: os::abort() might be called very early during initialization, or
 // called from signal handler. Before adding something to os::abort(), make
 // sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core, void* siginfo, void* context) {
+void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
 #ifndef PRODUCT
@@ -1491,6 +1496,10 @@
   st->print(name.machine);
   st->cr();
 
+  uint32_t ver = os::Aix::os_version();
+  st->print_cr("AIX kernel version %u.%u.%u.%u",
+               (ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
+
   // rlimit
   st->print("rlimit:");
   struct rlimit rlim;
@@ -3806,7 +3815,7 @@
   Thread* thread = context.thread();
   OSThread* osthread = thread->osthread();
   if (osthread->ucontext() != NULL) {
-    _epc = os::Aix::ucontext_get_pc((ucontext_t *) context.ucontext());
+    _epc = os::Aix::ucontext_get_pc((const ucontext_t *) context.ucontext());
   } else {
     // NULL context is unexpected, double-check this is the VMThread.
     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
@@ -4255,7 +4264,7 @@
 // one of Aix::on_pase(), Aix::os_version() static
 void os::Aix::initialize_os_info() {
 
-  assert(_on_pase == -1 && _os_version == -1, "already called.");
+  assert(_on_pase == -1 && _os_version == 0, "already called.");
 
   struct utsname uts;
   memset(&uts, 0, sizeof(uts));
@@ -4271,28 +4280,34 @@
     assert(major > 0, "invalid OS version");
     const int minor = atoi(uts.release);
     assert(minor > 0, "invalid OS release");
-    _os_version = (major << 8) | minor;
+    _os_version = (major << 24) | (minor << 16);
+    char ver_str[20] = {0};
+    char *name_str = "unknown OS";
     if (strcmp(uts.sysname, "OS400") == 0) {
       // We run on AS/400 PASE. We do not support versions older than V5R4M0.
       _on_pase = 1;
-      if (_os_version < 0x0504) {
+      if (os_version_short() < 0x0504) {
         trcVerbose("OS/400 releases older than V5R4M0 not supported.");
         assert(false, "OS/400 release too old.");
-      } else {
-        trcVerbose("We run on OS/400 (pase) V%dR%d", major, minor);
       }
+      name_str = "OS/400 (pase)";
+      jio_snprintf(ver_str, sizeof(ver_str), "%u.%u", major, minor);
     } else if (strcmp(uts.sysname, "AIX") == 0) {
       // We run on AIX. We do not support versions older than AIX 5.3.
       _on_pase = 0;
-      if (_os_version < 0x0503) {
+      // Determine detailed AIX version: Version, Release, Modification, Fix Level.
+      odmWrapper::determine_os_kernel_version(&_os_version);
+      if (os_version_short() < 0x0503) {
         trcVerbose("AIX release older than AIX 5.3 not supported.");
         assert(false, "AIX release too old.");
-      } else {
-        trcVerbose("We run on AIX %d.%d", major, minor);
       }
+      name_str = "AIX";
+      jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",
+                   major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);
     } else {
-      assert(false, "unknown OS");
+      assert(false, name_str);
     }
+    trcVerbose("We run on %s %s", name_str, ver_str);
   }
 
   guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release");
@@ -4357,7 +4372,7 @@
 
   p = ::getenv("LDR_CNTRL");
   trcVerbose("LDR_CNTRL=%s.", p ? p : "<unset>");
-  if (os::Aix::on_pase() && os::Aix::os_version() == 0x0701) {
+  if (os::Aix::on_pase() && os::Aix::os_version_short() == 0x0701) {
     if (p && ::strstr(p, "TEXTPSIZE")) {
       trcVerbose("*** WARNING - LDR_CNTRL contains TEXTPSIZE. "
         "you may experience hangs or crashes on OS/400 V7R1.");
@@ -5016,7 +5031,7 @@
 }
 #endif
 
-bool os::start_debugging(char *buf, int buflen) {
+bool os::start_debugging(char *buf, int buflen) {
   int len = (int)strlen(buf);
   char *p = &buf[len];
 
--- a/hotspot/src/os/aix/vm/os_aix.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/aix/vm/os_aix.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -55,15 +55,12 @@
   // -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
   static int _on_pase;
 
-  // -1 = uninitialized, otherwise 16 bit number:
+  // 0 = uninitialized, otherwise 16 bit number:
   //  lower 8 bit - minor version
   //  higher 8 bit - major version
   //  For AIX, e.g. 0x0601 for AIX 6.1
   //  for OS/400 e.g. 0x0504 for OS/400 V5R4
-  static int _os_version;
-
-  // 4 Byte kernel version: Version, Release, Tech Level, Service Pack.
-  static unsigned int _os_kernel_version;
+  static uint32_t _os_version;
 
   // -1 = uninitialized,
   //  0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set)
@@ -126,8 +123,8 @@
   static int vm_default_page_size(void ) { return 8*K; }
 
   static address   ucontext_get_pc(const ucontext_t* uc);
-  static intptr_t* ucontext_get_sp(ucontext_t* uc);
-  static intptr_t* ucontext_get_fp(ucontext_t* uc);
+  static intptr_t* ucontext_get_sp(const ucontext_t* uc);
+  static intptr_t* ucontext_get_fp(const ucontext_t* uc);
   // Set PC into context. Needed for continuation after signal.
   static void ucontext_set_pc(ucontext_t* uc, address pc);
 
@@ -175,32 +172,31 @@
     return _on_pase ? false : true;
   }
 
-  // -1 = uninitialized, otherwise 16 bit number:
+  // Get 4 byte AIX kernel version number:
+  // highest 2 bytes: Version, Release
+  // if available: lowest 2 bytes: Tech Level, Service Pack.
+  static uint32_t os_version() {
+    assert(_os_version != 0, "not initialized");
+    return _os_version;
+  }
+
+  // 0 = uninitialized, otherwise 16 bit number:
   // lower 8 bit - minor version
   // higher 8 bit - major version
   // For AIX, e.g. 0x0601 for AIX 6.1
   // for OS/400 e.g. 0x0504 for OS/400 V5R4
-  static int os_version () {
-    assert(_os_version != -1, "not initialized");
-    return _os_version;
-  }
-
-  // Get 4 byte AIX kernel version number:
-  // highest 2 bytes: Version, Release
-  // if available: lowest 2 bytes: Tech Level, Service Pack.
-  static unsigned int os_kernel_version() {
-    if (_os_kernel_version) return _os_kernel_version;
-    return os_version() << 16;
+  static int os_version_short() {
+    return os_version() >> 16;
   }
 
   // Convenience method: returns true if running on PASE V5R4 or older.
   static bool on_pase_V5R4_or_older() {
-    return on_pase() && os_version() <= 0x0504;
+    return on_pase() && os_version_short() <= 0x0504;
   }
 
   // Convenience method: returns true if running on AIX 5.3 or older.
   static bool on_aix_53_or_older() {
-    return on_aix() && os_version() <= 0x0503;
+    return on_aix() && os_version_short() <= 0x0503;
   }
 
   // Returns true if we run in SPEC1170 compliant mode (XPG_SUS_ENV=ON).
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1077,7 +1077,7 @@
 // Note: os::abort() might be called very early during initialization, or
 // called from signal handler. Before adding something to os::abort(), make
 // sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core, void* siginfo, void* context) {
+void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
 #ifndef PRODUCT
@@ -3497,7 +3497,7 @@
   // Add in 2*BytesPerWord times page size to account for VM stack during
   // class initialization depending on 32 or 64 bit VM.
   os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed,
-                                    (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
+                                    (size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages+
                                     2*BytesPerWord COMPILER2_PRESENT(+1)) * Bsd::page_size());
 
   size_t threadStackSizeInBytes = ThreadStackSize * K;
@@ -3643,7 +3643,7 @@
   Thread* thread = context.thread();
   OSThread* osthread = thread->osthread();
   if (osthread->ucontext() != NULL) {
-    _epc = os::Bsd::ucontext_get_pc((ucontext_t *) context.ucontext());
+    _epc = os::Bsd::ucontext_get_pc((const ucontext_t *) context.ucontext());
   } else {
     // NULL context is unexpected, double-check this is the VMThread
     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
--- a/hotspot/src/os/bsd/vm/os_bsd.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -86,19 +86,21 @@
   static int page_size(void)                                        { return _page_size; }
   static void set_page_size(int val)                                { _page_size = val; }
 
-  static address   ucontext_get_pc(ucontext_t* uc);
+  static address   ucontext_get_pc(const ucontext_t* uc);
   static void ucontext_set_pc(ucontext_t* uc, address pc);
-  static intptr_t* ucontext_get_sp(ucontext_t* uc);
-  static intptr_t* ucontext_get_fp(ucontext_t* uc);
+  static intptr_t* ucontext_get_sp(const ucontext_t* uc);
+  static intptr_t* ucontext_get_fp(const ucontext_t* uc);
 
   // For Analyzer Forte AsyncGetCallTrace profiling support:
   //
   // This interface should be declared in os_bsd_i486.hpp, but
   // that file provides extensions to the os class and not the
   // Bsd class.
-  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,
+  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, const ucontext_t* uc,
                                               intptr_t** ret_sp, intptr_t** ret_fp);
 
+  static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
+
   // This boolean allows users to forward their own non-matching signals
   // to JVM_handle_bsd_signal, harmlessly.
   static bool signal_handlers_are_installed;
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1341,7 +1341,7 @@
 // Note: os::abort() might be called very early during initialization, or
 // called from signal handler. Before adding something to os::abort(), make
 // sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core, void* siginfo, void* context) {
+void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
 #ifndef PRODUCT
@@ -1733,7 +1733,7 @@
 #if defined(VM_LITTLE_ENDIAN)
     {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2LSB, (char*)"Power PC 64"},
 #else
-    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
+    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64 LE"},
 #endif
     {EM_ARM,         EM_ARM,     ELFCLASS32,   ELFDATA2LSB, (char*)"ARM"},
     {EM_S390,        EM_S390,    ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
@@ -1861,8 +1861,8 @@
     JavaThread *jt = Threads::first();
 
     while (jt) {
-      if (!jt->stack_guard_zone_unused() &&        // Stack not yet fully initialized
-          jt->stack_yellow_zone_enabled()) {       // No pending stack overflow exceptions
+      if (!jt->stack_guard_zone_unused() &&     // Stack not yet fully initialized
+          jt->stack_guards_enabled()) {         // No pending stack overflow exceptions
         if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
                               jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
           warning("Attempt to reguard stack yellow zone failed.");
@@ -2177,6 +2177,8 @@
 const char* search_string = "model name";
 #elif defined(SPARC)
 const char* search_string = "cpu";
+#elif defined(PPC64)
+const char* search_string = "cpu";
 #else
 const char* search_string = "Processor";
 #endif
@@ -4603,6 +4605,11 @@
   if (vm_page_size() > (int)Linux::vm_default_page_size()) {
     StackYellowPages = 1;
     StackRedPages = 1;
+#if defined(IA32) || defined(IA64)
+    StackReservedPages = 1;
+#else
+    StackReservedPages = 0;
+#endif
     StackShadowPages = round_to((StackShadowPages*Linux::vm_default_page_size()), vm_page_size()) / vm_page_size();
   }
 
@@ -4664,7 +4671,7 @@
   // Add in 2*BytesPerWord times page size to account for VM stack during
   // class initialization depending on 32 or 64 bit VM.
   os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
-                                      (size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() +
+                                      (size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() +
                                       (2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size());
 
   size_t threadStackSizeInBytes = ThreadStackSize * K;
@@ -4846,7 +4853,7 @@
   Thread* thread = context.thread();
   OSThread* osthread = thread->osthread();
   if (osthread->ucontext() != NULL) {
-    _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
+    _epc = os::Linux::ucontext_get_pc((const ucontext_t *) context.ucontext());
   } else {
     // NULL context is unexpected, double-check this is the VMThread
     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
--- a/hotspot/src/os/linux/vm/os_linux.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -123,19 +123,21 @@
 
   static int vm_default_page_size(void)                             { return _vm_default_page_size; }
 
-  static address   ucontext_get_pc(ucontext_t* uc);
+  static address   ucontext_get_pc(const ucontext_t* uc);
   static void ucontext_set_pc(ucontext_t* uc, address pc);
-  static intptr_t* ucontext_get_sp(ucontext_t* uc);
-  static intptr_t* ucontext_get_fp(ucontext_t* uc);
+  static intptr_t* ucontext_get_sp(const ucontext_t* uc);
+  static intptr_t* ucontext_get_fp(const ucontext_t* uc);
 
   // For Analyzer Forte AsyncGetCallTrace profiling support:
   //
   // This interface should be declared in os_linux_i486.hpp, but
   // that file provides extensions to the os class and not the
   // Linux class.
-  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,
+  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, const ucontext_t* uc,
                                               intptr_t** ret_sp, intptr_t** ret_fp);
 
+  static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
+
   // This boolean allows users to forward their own non-matching signals
   // to JVM_handle_linux_signal, harmlessly.
   static bool signal_handlers_are_installed;
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -736,12 +736,12 @@
 }
 
 // Returns:
-// "invalid (<num>)" for an invalid signal number
+// NULL for an invalid signal number
 // "SIG<num>" for a valid but unknown signal number
 // signal name otherwise.
 const char* os::exception_name(int sig, char* buf, size_t size) {
   if (!os::Posix::is_valid_signal(sig)) {
-    jio_snprintf(buf, size, "invalid (%d)", sig);
+    return NULL;
   }
   const char* const name = os::Posix::get_signal_name(sig, buf, size);
   if (strcmp(name, "UNKNOWN") == 0) {
@@ -1031,7 +1031,7 @@
   return pthread_sigmask(SIG_UNBLOCK, set, NULL);
 }
 
-address os::Posix::ucontext_get_pc(ucontext_t* ctx) {
+address os::Posix::ucontext_get_pc(const ucontext_t* ctx) {
 #ifdef TARGET_OS_FAMILY_linux
    return Linux::ucontext_get_pc(ctx);
 #elif defined(TARGET_OS_FAMILY_solaris)
--- a/hotspot/src/os/posix/vm/os_posix.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -76,7 +76,7 @@
   // A POSIX conform, platform-independend siginfo print routine.
   static void print_siginfo_brief(outputStream* os, const siginfo_t* si);
 
-  static address ucontext_get_pc(ucontext_t* ctx);
+  static address ucontext_get_pc(const ucontext_t* ctx);
   // Set PC into context. Needed for continuation after signal.
   static void ucontext_set_pc(ucontext_t* ctx, address pc);
 };
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1380,7 +1380,7 @@
 // Note: os::abort() might be called very early during initialization, or
 // called from signal handler. Before adding something to os::abort(), make
 // sure it is async-safe and can handle partially initialized VM.
-void os::abort(bool dump_core, void* siginfo, void* context) {
+void os::abort(bool dump_core, void* siginfo, const void* context) {
   os::shutdown();
   if (dump_core) {
 #ifndef PRODUCT
@@ -3736,7 +3736,7 @@
   Thread* thread = context.thread();
   OSThread* osthread = thread->osthread();
   if (osthread->ucontext() != NULL) {
-    _epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext());
+    _epc = os::Solaris::ucontext_get_pc((const ucontext_t *) context.ucontext());
   } else {
     // NULL context is unexpected, double-check this is the VMThread
     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
@@ -4382,6 +4382,7 @@
   if (vm_page_size() > 8*K) {
     StackYellowPages = 1;
     StackRedPages = 1;
+    StackReservedPages = 1;
     StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size();
   }
 }
@@ -4438,7 +4439,7 @@
   // Add in 2*BytesPerWord times page size to account for VM stack during
   // class initialization depending on 32 or 64 bit VM.
   os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed,
-                                        (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
+                                        (size_t)(StackReservedPages+StackYellowPages+StackRedPages+StackShadowPages+
                                         2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size);
 
   size_t threadStackSizeInBytes = ThreadStackSize * K;
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,15 +130,15 @@
   static address handler_start, handler_end; // start and end pc of thr_sighndlrinfo
 
   static bool valid_stack_address(Thread* thread, address sp);
-  static bool valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect);
-  static ucontext_t* get_valid_uc_in_signal_handler(Thread* thread,
-                                                    ucontext_t* uc);
+  static bool valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect);
+  static const ucontext_t* get_valid_uc_in_signal_handler(Thread* thread,
+                                                    const ucontext_t* uc);
 
-  static ExtendedPC  ucontext_get_ExtendedPC(ucontext_t* uc);
-  static intptr_t*   ucontext_get_sp(ucontext_t* uc);
+  static ExtendedPC  ucontext_get_ExtendedPC(const ucontext_t* uc);
+  static intptr_t*   ucontext_get_sp(const ucontext_t* uc);
   // ucontext_get_fp() is only used by Solaris X86 (see note below)
-  static intptr_t*   ucontext_get_fp(ucontext_t* uc);
-  static address    ucontext_get_pc(ucontext_t* uc);
+  static intptr_t*   ucontext_get_fp(const ucontext_t* uc);
+  static address    ucontext_get_pc(const ucontext_t* uc);
   static void ucontext_set_pc(ucontext_t* uc, address pc);
 
   // For Analyzer Forte AsyncGetCallTrace profiling support:
@@ -147,9 +147,11 @@
   // We should have different declarations of this interface in
   // os_solaris_i486.hpp and os_solaris_sparc.hpp, but that file
   // provides extensions to the os class and not the Solaris class.
-  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,
+  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, const ucontext_t* uc,
                                               intptr_t** ret_sp, intptr_t** ret_fp);
 
+  static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
+
   static void hotspot_sigmask(Thread* thread);
 
   // SR_handler
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1028,7 +1028,7 @@
   VMError::record_coredump_status(buffer, status);
 }
 
-void os::abort(bool dump_core, void* siginfo, void* context) {
+void os::abort(bool dump_core, void* siginfo, const void* context) {
   HINSTANCE dbghelp;
   EXCEPTION_POINTERS ep;
   MINIDUMP_EXCEPTION_INFORMATION mei;
@@ -2374,6 +2374,39 @@
   // somewhere where we can find it in the minidump.
 }
 
+bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
+        struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
+  PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
+  address addr = (address) exceptionRecord->ExceptionInformation[1];
+  if (Interpreter::contains(pc)) {
+    *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
+      // in compiled code, the stack banging is performed just after the return pc
+      // has been pushed on the stack
+      *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 //-----------------------------------------------------------------------------
 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
   if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH;
@@ -2550,7 +2583,16 @@
                                   SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW));
         }
 #endif
-        if (thread->stack_yellow_zone_enabled()) {
+        if (thread->stack_guards_enabled()) {
+          if (_thread_in_Java) {
+            frame fr;
+            PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
+            address addr = (address) exceptionRecord->ExceptionInformation[1];
+            if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) {
+              assert(fr.is_java_frame(), "Must be a Java frame");
+              SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+            }
+          }
           // Yellow zone violation.  The o/s has unprotected the first yellow
           // zone page for us.  Note:  must call disable_stack_yellow_zone to
           // update the enabled status, even if the zone contains only one page.
@@ -5529,8 +5571,6 @@
   return yes;
 }
 
-#ifndef JDK6_OR_EARLIER
-
 void os::Kernel32Dll::initialize() {
   initializeCommon();
 }
@@ -5705,261 +5745,6 @@
   return agent_entry_name;
 }
 
-#else
-// Kernel32 API
-typedef BOOL (WINAPI* SwitchToThread_Fn)(void);
-typedef HANDLE (WINAPI* CreateToolhelp32Snapshot_Fn)(DWORD, DWORD);
-typedef BOOL (WINAPI* Module32First_Fn)(HANDLE, LPMODULEENTRY32);
-typedef BOOL (WINAPI* Module32Next_Fn)(HANDLE, LPMODULEENTRY32);
-typedef void (WINAPI* GetNativeSystemInfo_Fn)(LPSYSTEM_INFO);
-
-SwitchToThread_Fn           os::Kernel32Dll::_SwitchToThread = NULL;
-CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;
-Module32First_Fn            os::Kernel32Dll::_Module32First = NULL;
-Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
-GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
-
-void os::Kernel32Dll::initialize() {
-  if (!initialized) {
-    HMODULE handle = ::GetModuleHandle("Kernel32.dll");
-    assert(handle != NULL, "Just check");
-
-    _SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
-    _CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
-      ::GetProcAddress(handle, "CreateToolhelp32Snapshot");
-    _Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
-    _Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
-    _GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
-    initializeCommon();  // resolve the functions that always need resolving
-
-    initialized = TRUE;
-  }
-}
-
-BOOL os::Kernel32Dll::SwitchToThread() {
-  assert(initialized && _SwitchToThread != NULL,
-         "SwitchToThreadAvailable() not yet called");
-  return _SwitchToThread();
-}
-
-
-BOOL os::Kernel32Dll::SwitchToThreadAvailable() {
-  if (!initialized) {
-    initialize();
-  }
-  return _SwitchToThread != NULL;
-}
-
-// Help tools
-BOOL os::Kernel32Dll::HelpToolsAvailable() {
-  if (!initialized) {
-    initialize();
-  }
-  return _CreateToolhelp32Snapshot != NULL &&
-         _Module32First != NULL &&
-         _Module32Next != NULL;
-}
-
-HANDLE os::Kernel32Dll::CreateToolhelp32Snapshot(DWORD dwFlags,
-                                                 DWORD th32ProcessId) {
-  assert(initialized && _CreateToolhelp32Snapshot != NULL,
-         "HelpToolsAvailable() not yet called");
-
-  return _CreateToolhelp32Snapshot(dwFlags, th32ProcessId);
-}
-
-BOOL os::Kernel32Dll::Module32First(HANDLE hSnapshot,LPMODULEENTRY32 lpme) {
-  assert(initialized && _Module32First != NULL,
-         "HelpToolsAvailable() not yet called");
-
-  return _Module32First(hSnapshot, lpme);
-}
-
-inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,
-                                          LPMODULEENTRY32 lpme) {
-  assert(initialized && _Module32Next != NULL,
-         "HelpToolsAvailable() not yet called");
-
-  return _Module32Next(hSnapshot, lpme);
-}
-
-
-BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
-  if (!initialized) {
-    initialize();
-  }
-  return _GetNativeSystemInfo != NULL;
-}
-
-void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
-  assert(initialized && _GetNativeSystemInfo != NULL,
-         "GetNativeSystemInfoAvailable() not yet called");
-
-  _GetNativeSystemInfo(lpSystemInfo);
-}
-
-// PSAPI API
-
-
-typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);
-typedef BOOL (WINAPI *GetModuleFileNameEx_Fn)(HANDLE, HMODULE, LPTSTR, DWORD);
-typedef BOOL (WINAPI *GetModuleInformation_Fn)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
-
-EnumProcessModules_Fn   os::PSApiDll::_EnumProcessModules = NULL;
-GetModuleFileNameEx_Fn  os::PSApiDll::_GetModuleFileNameEx = NULL;
-GetModuleInformation_Fn os::PSApiDll::_GetModuleInformation = NULL;
-BOOL                    os::PSApiDll::initialized = FALSE;
-
-void os::PSApiDll::initialize() {
-  if (!initialized) {
-    HMODULE handle = os::win32::load_Windows_dll("PSAPI.DLL", NULL, 0);
-    if (handle != NULL) {
-      _EnumProcessModules = (EnumProcessModules_Fn)::GetProcAddress(handle,
-                                                                    "EnumProcessModules");
-      _GetModuleFileNameEx = (GetModuleFileNameEx_Fn)::GetProcAddress(handle,
-                                                                      "GetModuleFileNameExA");
-      _GetModuleInformation = (GetModuleInformation_Fn)::GetProcAddress(handle,
-                                                                        "GetModuleInformation");
-    }
-    initialized = TRUE;
-  }
-}
-
-
-
-BOOL os::PSApiDll::EnumProcessModules(HANDLE hProcess, HMODULE *lpModule,
-                                      DWORD cb, LPDWORD lpcbNeeded) {
-  assert(initialized && _EnumProcessModules != NULL,
-         "PSApiAvailable() not yet called");
-  return _EnumProcessModules(hProcess, lpModule, cb, lpcbNeeded);
-}
-
-DWORD os::PSApiDll::GetModuleFileNameEx(HANDLE hProcess, HMODULE hModule,
-                                        LPTSTR lpFilename, DWORD nSize) {
-  assert(initialized && _GetModuleFileNameEx != NULL,
-         "PSApiAvailable() not yet called");
-  return _GetModuleFileNameEx(hProcess, hModule, lpFilename, nSize);
-}
-
-BOOL os::PSApiDll::GetModuleInformation(HANDLE hProcess, HMODULE hModule,
-                                        LPMODULEINFO lpmodinfo, DWORD cb) {
-  assert(initialized && _GetModuleInformation != NULL,
-         "PSApiAvailable() not yet called");
-  return _GetModuleInformation(hProcess, hModule, lpmodinfo, cb);
-}
-
-BOOL os::PSApiDll::PSApiAvailable() {
-  if (!initialized) {
-    initialize();
-  }
-  return _EnumProcessModules != NULL &&
-    _GetModuleFileNameEx != NULL &&
-    _GetModuleInformation != NULL;
-}
-
-
-// WinSock2 API
-typedef int (PASCAL FAR* WSAStartup_Fn)(WORD, LPWSADATA);
-typedef struct hostent *(PASCAL FAR *gethostbyname_Fn)(...);
-
-WSAStartup_Fn    os::WinSock2Dll::_WSAStartup = NULL;
-gethostbyname_Fn os::WinSock2Dll::_gethostbyname = NULL;
-BOOL             os::WinSock2Dll::initialized = FALSE;
-
-void os::WinSock2Dll::initialize() {
-  if (!initialized) {
-    HMODULE handle = os::win32::load_Windows_dll("ws2_32.dll", NULL, 0);
-    if (handle != NULL) {
-      _WSAStartup = (WSAStartup_Fn)::GetProcAddress(handle, "WSAStartup");
-      _gethostbyname = (gethostbyname_Fn)::GetProcAddress(handle, "gethostbyname");
-    }
-    initialized = TRUE;
-  }
-}
-
-
-BOOL os::WinSock2Dll::WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
-  assert(initialized && _WSAStartup != NULL,
-         "WinSock2Available() not yet called");
-  return _WSAStartup(wVersionRequested, lpWSAData);
-}
-
-struct hostent* os::WinSock2Dll::gethostbyname(const char *name) {
-  assert(initialized && _gethostbyname != NULL,
-         "WinSock2Available() not yet called");
-  return _gethostbyname(name);
-}
-
-BOOL os::WinSock2Dll::WinSock2Available() {
-  if (!initialized) {
-    initialize();
-  }
-  return _WSAStartup != NULL &&
-    _gethostbyname != NULL;
-}
-
-typedef BOOL (WINAPI *AdjustTokenPrivileges_Fn)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
-typedef BOOL (WINAPI *OpenProcessToken_Fn)(HANDLE, DWORD, PHANDLE);
-typedef BOOL (WINAPI *LookupPrivilegeValue_Fn)(LPCTSTR, LPCTSTR, PLUID);
-
-AdjustTokenPrivileges_Fn os::Advapi32Dll::_AdjustTokenPrivileges = NULL;
-OpenProcessToken_Fn      os::Advapi32Dll::_OpenProcessToken = NULL;
-LookupPrivilegeValue_Fn  os::Advapi32Dll::_LookupPrivilegeValue = NULL;
-BOOL                     os::Advapi32Dll::initialized = FALSE;
-
-void os::Advapi32Dll::initialize() {
-  if (!initialized) {
-    HMODULE handle = os::win32::load_Windows_dll("advapi32.dll", NULL, 0);
-    if (handle != NULL) {
-      _AdjustTokenPrivileges = (AdjustTokenPrivileges_Fn)::GetProcAddress(handle,
-                                                                          "AdjustTokenPrivileges");
-      _OpenProcessToken = (OpenProcessToken_Fn)::GetProcAddress(handle,
-                                                                "OpenProcessToken");
-      _LookupPrivilegeValue = (LookupPrivilegeValue_Fn)::GetProcAddress(handle,
-                                                                        "LookupPrivilegeValueA");
-    }
-    initialized = TRUE;
-  }
-}
-
-BOOL os::Advapi32Dll::AdjustTokenPrivileges(HANDLE TokenHandle,
-                                            BOOL DisableAllPrivileges,
-                                            PTOKEN_PRIVILEGES NewState,
-                                            DWORD BufferLength,
-                                            PTOKEN_PRIVILEGES PreviousState,
-                                            PDWORD ReturnLength) {
-  assert(initialized && _AdjustTokenPrivileges != NULL,
-         "AdvapiAvailable() not yet called");
-  return _AdjustTokenPrivileges(TokenHandle, DisableAllPrivileges, NewState,
-                                BufferLength, PreviousState, ReturnLength);
-}
-
-BOOL os::Advapi32Dll::OpenProcessToken(HANDLE ProcessHandle,
-                                       DWORD DesiredAccess,
-                                       PHANDLE TokenHandle) {
-  assert(initialized && _OpenProcessToken != NULL,
-         "AdvapiAvailable() not yet called");
-  return _OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle);
-}
-
-BOOL os::Advapi32Dll::LookupPrivilegeValue(LPCTSTR lpSystemName,
-                                           LPCTSTR lpName, PLUID lpLuid) {
-  assert(initialized && _LookupPrivilegeValue != NULL,
-         "AdvapiAvailable() not yet called");
-  return _LookupPrivilegeValue(lpSystemName, lpName, lpLuid);
-}
-
-BOOL os::Advapi32Dll::AdvapiAvailable() {
-  if (!initialized) {
-    initialize();
-  }
-  return _AdjustTokenPrivileges != NULL &&
-    _OpenProcessToken != NULL &&
-    _LookupPrivilegeValue != NULL;
-}
-
-#endif
-
 #ifndef PRODUCT
 
 // test the code path in reserve_memory_special() that tries to allocate memory in a single
@@ -5976,7 +5761,7 @@
 void TestReserveMemorySpecial_test() {
   if (!UseLargePages) {
     if (VerboseInternalVMTests) {
-      gclog_or_tty->print("Skipping test because large pages are disabled");
+      tty->print("Skipping test because large pages are disabled");
     }
     return;
   }
@@ -5992,7 +5777,7 @@
   char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
   if (result == NULL) {
     if (VerboseInternalVMTests) {
-      gclog_or_tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",
+      tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",
                           large_allocation_size);
     }
   } else {
@@ -6005,7 +5790,7 @@
     char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
     if (actual_location == NULL) {
       if (VerboseInternalVMTests) {
-        gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
+        tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
                             expected_location, large_allocation_size);
       }
     } else {
--- a/hotspot/src/os/windows/vm/os_windows.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -110,6 +110,10 @@
   // Default stack size for the current process.
   static size_t default_stack_size() { return _default_stack_size; }
 
+  static bool get_frame_at_stack_banging_point(JavaThread* thread,
+                          struct _EXCEPTION_POINTERS* exceptionInfo,
+                          address pc, frame* fr);
+
 #ifndef _WIN64
   // A wrapper to install a structured exception handler for fast JNI accesors.
   static address fast_jni_accessor_wrapper(BasicType);
@@ -183,26 +187,11 @@
 
 } ;
 
-// JDK7 requires VS2010
-#if _MSC_VER < 1600
-#define JDK6_OR_EARLIER 1
-#endif
-
-
-
 class WinSock2Dll: AllStatic {
 public:
   static BOOL WSAStartup(WORD, LPWSADATA);
   static struct hostent* gethostbyname(const char *name);
   static BOOL WinSock2Available();
-#ifdef JDK6_OR_EARLIER
-private:
-  static int (PASCAL FAR* _WSAStartup)(WORD, LPWSADATA);
-  static struct hostent *(PASCAL FAR *_gethostbyname)(...);
-  static BOOL initialized;
-
-  static void initialize();
-#endif
 };
 
 class Kernel32Dll: AllStatic {
@@ -244,16 +233,6 @@
 
   static void initialize();
   static void initializeCommon();
-
-#ifdef JDK6_OR_EARLIER
-private:
-  static BOOL (WINAPI *_SwitchToThread)(void);
-  static HANDLE (WINAPI* _CreateToolhelp32Snapshot)(DWORD,DWORD);
-  static BOOL (WINAPI* _Module32First)(HANDLE,LPMODULEENTRY32);
-  static BOOL (WINAPI* _Module32Next)(HANDLE,LPMODULEENTRY32);
-  static void (WINAPI *_GetNativeSystemInfo)(LPSYSTEM_INFO);
-#endif
-
 };
 
 class Advapi32Dll: AllStatic {
@@ -263,16 +242,6 @@
   static BOOL LookupPrivilegeValue(LPCTSTR, LPCTSTR, PLUID);
 
   static BOOL AdvapiAvailable();
-
-#ifdef JDK6_OR_EARLIER
-private:
-  static BOOL (WINAPI *_AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
-  static BOOL (WINAPI *_OpenProcessToken)(HANDLE, DWORD, PHANDLE);
-  static BOOL (WINAPI *_LookupPrivilegeValue)(LPCTSTR, LPCTSTR, PLUID);
-  static BOOL initialized;
-
-  static void initialize();
-#endif
 };
 
 class PSApiDll: AllStatic {
@@ -282,16 +251,6 @@
   static BOOL GetModuleInformation(HANDLE, HMODULE, LPMODULEINFO, DWORD);
 
   static BOOL PSApiAvailable();
-
-#ifdef JDK6_OR_EARLIER
-private:
-  static BOOL (WINAPI *_EnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD);
-  static BOOL (WINAPI *_GetModuleFileNameEx)(HANDLE, HMODULE, LPTSTR, DWORD);;
-  static BOOL (WINAPI *_GetModuleInformation)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
-  static BOOL initialized;
-
-  static void initialize();
-#endif
 };
 
 #endif // OS_WINDOWS_VM_OS_WINDOWS_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os/windows/vm/sharedRuntimeRem.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,162 @@
+/*
+* Copyright (c) 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"
+
+#ifdef _WIN64
+// These are copied defines from fdlibm.h, this allows us to keep the code
+// the same as in the JDK, for easier maintenance.
+
+#define __HI(x) *(1+(int*)&x)
+#define __LO(x) *(int*)&x
+
+// This code is a copy of __ieee754_fmod() from the JDK's libfdlibm and is
+// used as a workaround for issues with the Windows x64 CRT implementation
+// of fmod. Microsoft has acknowledged that this is an issue in Visual Studio
+// 2012 and forward, but has not provided a time frame for a fix other than that
+// it'll not be fixed in Visual Studio 2013 or 2015.
+
+static const double one = 1.0, Zero[] = { 0.0, -0.0, };
+
+double SharedRuntime::fmod_winx64(double x, double y)
+{
+  int n, hx, hy, hz, ix, iy, sx, i;
+  unsigned lx, ly, lz;
+
+  hx = __HI(x);           /* high word of x */
+  lx = __LO(x);           /* low  word of x */
+  hy = __HI(y);           /* high word of y */
+  ly = __LO(y);           /* low  word of y */
+  sx = hx & 0x80000000;             /* sign of x */
+  hx ^= sx;                /* |x| */
+  hy &= 0x7fffffff;       /* |y| */
+
+#pragma warning( disable : 4146 )
+  /* purge off exception values */
+  if ((hy | ly) == 0 || (hx >= 0x7ff00000) ||       /* y=0,or x not finite */
+    ((hy | ((ly | -ly) >> 31))>0x7ff00000))     /* or y is NaN */
+#pragma warning( default : 4146 )
+    return (x*y) / (x*y);
+  if (hx <= hy) {
+    if ((hx<hy) || (lx<ly)) return x;      /* |x|<|y| return x */
+    if (lx == ly)
+      return Zero[(unsigned)sx >> 31];  /* |x|=|y| return x*0*/
+  }
+
+  /* determine ix = ilogb(x) */
+  if (hx<0x00100000) {     /* subnormal x */
+    if (hx == 0) {
+      for (ix = -1043, i = lx; i>0; i <<= 1) ix -= 1;
+    }
+    else {
+      for (ix = -1022, i = (hx << 11); i>0; i <<= 1) ix -= 1;
+    }
+  }
+  else ix = (hx >> 20) - 1023;
+
+  /* determine iy = ilogb(y) */
+  if (hy<0x00100000) {     /* subnormal y */
+    if (hy == 0) {
+      for (iy = -1043, i = ly; i>0; i <<= 1) iy -= 1;
+    }
+    else {
+      for (iy = -1022, i = (hy << 11); i>0; i <<= 1) iy -= 1;
+    }
+  }
+  else iy = (hy >> 20) - 1023;
+
+  /* set up {hx,lx}, {hy,ly} and align y to x */
+  if (ix >= -1022)
+    hx = 0x00100000 | (0x000fffff & hx);
+  else {          /* subnormal x, shift x to normal */
+    n = -1022 - ix;
+    if (n <= 31) {
+      hx = (hx << n) | (lx >> (32 - n));
+      lx <<= n;
+    }
+    else {
+      hx = lx << (n - 32);
+      lx = 0;
+    }
+  }
+  if (iy >= -1022)
+    hy = 0x00100000 | (0x000fffff & hy);
+  else {          /* subnormal y, shift y to normal */
+    n = -1022 - iy;
+    if (n <= 31) {
+      hy = (hy << n) | (ly >> (32 - n));
+      ly <<= n;
+    }
+    else {
+      hy = ly << (n - 32);
+      ly = 0;
+    }
+  }
+
+  /* fix point fmod */
+  n = ix - iy;
+  while (n--) {
+    hz = hx - hy; lz = lx - ly; if (lx<ly) hz -= 1;
+    if (hz<0){ hx = hx + hx + (lx >> 31); lx = lx + lx; }
+    else {
+      if ((hz | lz) == 0)          /* return sign(x)*0 */
+        return Zero[(unsigned)sx >> 31];
+      hx = hz + hz + (lz >> 31); lx = lz + lz;
+    }
+  }
+  hz = hx - hy; lz = lx - ly; if (lx<ly) hz -= 1;
+  if (hz >= 0) { hx = hz; lx = lz; }
+
+  /* convert back to floating value and restore the sign */
+  if ((hx | lx) == 0)                  /* return sign(x)*0 */
+    return Zero[(unsigned)sx >> 31];
+  while (hx<0x00100000) {          /* normalize x */
+    hx = hx + hx + (lx >> 31); lx = lx + lx;
+    iy -= 1;
+  }
+  if (iy >= -1022) {        /* normalize output */
+    hx = ((hx - 0x00100000) | ((iy + 1023) << 20));
+    __HI(x) = hx | sx;
+    __LO(x) = lx;
+  }
+  else {                /* subnormal output */
+    n = -1022 - iy;
+    if (n <= 20) {
+      lx = (lx >> n) | ((unsigned)hx << (32 - n));
+      hx >>= n;
+    }
+    else if (n <= 31) {
+      lx = (hx << (32 - n)) | (lx >> n); hx = sx;
+    }
+    else {
+      lx = hx >> (n - 32); hx = sx;
+    }
+    __HI(x) = hx | sx;
+    __LO(x) = lx;
+    x *= one;           /* create necessary signal */
+  }
+  return x;               /* exact output */
+}
+
+#endif
--- a/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -291,6 +291,71 @@
   return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
 }
 
+#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
+inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
+
+  // Note that cmpxchg guarantees a two-way memory barrier across
+  // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire'
+  // (see atomic.hpp).
+
+  // Using 32 bit internally.
+  volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3);
+
+#ifdef VM_LITTLE_ENDIAN
+  const unsigned int shift_amount        = ((uintptr_t)dest & 3) * 8;
+#else
+  const unsigned int shift_amount        = ((~(uintptr_t)dest) & 3) * 8;
+#endif
+  const unsigned int masked_compare_val  = ((unsigned int)(unsigned char)compare_value),
+                     masked_exchange_val = ((unsigned int)(unsigned char)exchange_value),
+                     xor_value           = (masked_compare_val ^ masked_exchange_val) << shift_amount;
+
+  unsigned int old_value, value32;
+
+  __asm__ __volatile__ (
+    /* fence */
+    strasm_sync
+    /* simple guard */
+    "   lbz     %[old_value], 0(%[dest])                  \n"
+    "   cmpw    %[masked_compare_val], %[old_value]       \n"
+    "   bne-    2f                                        \n"
+    /* atomic loop */
+    "1:                                                   \n"
+    "   lwarx   %[value32], 0, %[dest_base]               \n"
+    /* extract byte and compare */
+    "   srd     %[old_value], %[value32], %[shift_amount] \n"
+    "   clrldi  %[old_value], %[old_value], 56            \n"
+    "   cmpw    %[masked_compare_val], %[old_value]       \n"
+    "   bne-    2f                                        \n"
+    /* replace byte and try to store */
+    "   xor     %[value32], %[xor_value], %[value32]      \n"
+    "   stwcx.  %[value32], 0, %[dest_base]               \n"
+    "   bne-    1b                                        \n"
+    /* acquire */
+    strasm_sync
+    /* exit */
+    "2:                                                   \n"
+    /* out */
+    : [old_value]           "=&r"   (old_value),
+      [value32]             "=&r"   (value32),
+                            "=m"    (*dest),
+                            "=m"    (*dest_base)
+    /* in */
+    : [dest]                "b"     (dest),
+      [dest_base]           "b"     (dest_base),
+      [shift_amount]        "r"     (shift_amount),
+      [masked_compare_val]  "r"     (masked_compare_val),
+      [xor_value]           "r"     (xor_value),
+                            "m"     (*dest),
+                            "m"     (*dest_base)
+    /* clobber */
+    : "cc",
+      "memory"
+    );
+
+  return (jbyte)(unsigned char)old_value;
+}
+
 inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
 
   // Note that cmpxchg guarantees a two-way memory barrier across
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -98,12 +98,12 @@
   return (address)uc->uc_mcontext.jmp_context.iar;
 }
 
-intptr_t* os::Aix::ucontext_get_sp(ucontext_t * uc) {
+intptr_t* os::Aix::ucontext_get_sp(const ucontext_t * uc) {
   // gpr1 holds the stack pointer on aix
   return (intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/];
 }
 
-intptr_t* os::Aix::ucontext_get_fp(ucontext_t * uc) {
+intptr_t* os::Aix::ucontext_get_fp(const ucontext_t * uc) {
   return NULL;
 }
 
@@ -111,11 +111,11 @@
   uc->uc_mcontext.jmp_context.iar = (uint64_t) new_pc;
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                                         intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t* uc = (ucontext_t*)ucVoid;
+  const ucontext_t* uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = ExtendedPC(os::Aix::ucontext_get_pc(uc));
@@ -131,7 +131,7 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
@@ -507,10 +507,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t* uc = (ucontext_t*)context;
+  const ucontext_t* uc = (const ucontext_t*)context;
 
   st->print_cr("Registers:");
   st->print("pc =" INTPTR_FORMAT "  ", uc->uc_mcontext.jmp_context.iar);
@@ -544,9 +544,23 @@
   st->cr();
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
-  st->print("Not ported - print_register_info\n");
+
+  ucontext_t *uc = (ucontext_t*)context;
+
+  st->print_cr("Register to memory mapping:");
+  st->cr();
+
+  st->print("pc ="); print_location(st, (intptr_t)uc->uc_mcontext.jmp_context.iar);
+  st->print("lr ="); print_location(st, (intptr_t)uc->uc_mcontext.jmp_context.lr);
+  st->print("sp ="); print_location(st, (intptr_t)os::Aix::ucontext_get_sp(uc));
+  for (int i = 0; i < 32; i++) {
+    st->print("r%-2d=", i);
+    print_location(st, (intptr_t)uc->uc_mcontext.jmp_context.gpr[i]);
+  }
+
+  st->cr();
 }
 
 extern "C" {
@@ -565,3 +579,4 @@
   // PPC does not require the additional stack bang.
   return 0;
 }
+
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -304,7 +304,7 @@
 // Nothing to do.
 }
 
-address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
+address os::Bsd::ucontext_get_pc(const ucontext_t * uc) {
   return (address)uc->context_pc;
 }
 
@@ -312,11 +312,11 @@
   uc->context_pc = (intptr_t)pc ;
 }
 
-intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
+intptr_t* os::Bsd::ucontext_get_sp(const ucontext_t * uc) {
   return (intptr_t*)uc->context_sp;
 }
 
-intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
+intptr_t* os::Bsd::ucontext_get_fp(const ucontext_t * uc) {
   return (intptr_t*)uc->context_fp;
 }
 
@@ -325,8 +325,9 @@
 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
 // frames. Currently we don't do that on Bsd, so it's the same as
 // os::fetch_frame_from_context().
+// This method is also used for stack overflow signal handling.
 ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread,
-  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+  const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 
   assert(thread != NULL, "just checking");
   assert(ret_sp != NULL, "just checking");
@@ -335,11 +336,11 @@
   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t* uc = (ucontext_t*)ucVoid;
+  const ucontext_t* uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc));
@@ -355,13 +356,55 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   return frame(sp, fp, epc.pc());
 }
 
+frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
+  intptr_t* sp;
+  intptr_t* fp;
+  ExtendedPC epc = os::Bsd::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
+  return frame(sp, fp, epc.pc());
+}
+
+bool os::Bsd::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Bsd::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_ucontext(thread, uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      *fr = os::fetch_frame_from_ucontext(thread, uc);
+      // in compiled code, the stack banging is performed just after the return pc
+      // has been pushed on the stack
+      *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get
 // turned off by -fomit-frame-pointer,
 frame os::get_sender_for_C_frame(frame* fr) {
@@ -479,13 +522,31 @@
           addr >= thread->stack_base() - thread->stack_size()) {
         // stack overflow
         if (thread->in_stack_yellow_zone(addr)) {
-          thread->disable_stack_yellow_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Bsd::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Java frame");
+                frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)(
+                      activation.fp() + frame::interpreter_frame_initial_sp_offset));
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.  Guard pages will be reenabled
             // while unwinding the stack.
+            thread->disable_stack_yellow_zone();
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           } else {
             // Thread was in the vm or native code.  Return and try to finish.
+            thread->disable_stack_yellow_zone();
             return 1;
           }
         } else if (thread->in_stack_red_zone(addr)) {
@@ -910,10 +971,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   st->print_cr("Registers:");
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->context_rax);
@@ -971,10 +1032,10 @@
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -106,7 +106,7 @@
   // Nothing to do.
 }
 
-address os::Bsd::ucontext_get_pc(ucontext_t* uc) {
+address os::Bsd::ucontext_get_pc(const ucontext_t* uc) {
   ShouldNotCallThis();
   return NULL;
 }
@@ -115,14 +115,14 @@
   ShouldNotCallThis();
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                                         intptr_t** ret_sp,
                                         intptr_t** ret_fp) {
   ShouldNotCallThis();
   return ExtendedPC();
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   ShouldNotCallThis();
   return frame();
 }
@@ -374,11 +374,11 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream* st, void* context) {
+void os::print_context(outputStream* st, const void* context) {
   ShouldNotCallThis();
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   ShouldNotCallThis();
 }
 
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -109,7 +109,7 @@
 void os::initialize_thread(Thread *thr) {
 }
 
-address os::Linux::ucontext_get_pc(ucontext_t * uc) {
+address os::Linux::ucontext_get_pc(const ucontext_t * uc) {
 #ifdef BUILTIN_SIM
   return (address)uc->uc_mcontext.gregs[REG_PC];
 #else
@@ -125,7 +125,7 @@
 #endif
 }
 
-intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) {
 #ifdef BUILTIN_SIM
   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
 #else
@@ -133,7 +133,7 @@
 #endif
 }
 
-intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) {
 #ifdef BUILTIN_SIM
   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 #else
@@ -147,7 +147,7 @@
 // frames. Currently we don't do that on Linux, so it's the same as
 // os::fetch_frame_from_context().
 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
-  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+  const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 
   assert(thread != NULL, "just checking");
   assert(ret_sp != NULL, "just checking");
@@ -156,11 +156,11 @@
   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t* uc = (ucontext_t*)ucVoid;
+  const ucontext_t* uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
@@ -176,7 +176,7 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
@@ -591,10 +591,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   st->print_cr("Registers:");
 #ifdef BUILTIN_SIM
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
@@ -643,10 +643,10 @@
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
--- a/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -291,6 +291,71 @@
   return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
 }
 
+#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
+inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
+
+  // Note that cmpxchg guarantees a two-way memory barrier across
+  // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire'
+  // (see atomic.hpp).
+
+  // Using 32 bit internally.
+  volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3);
+
+#ifdef VM_LITTLE_ENDIAN
+  const unsigned int shift_amount        = ((uintptr_t)dest & 3) * 8;
+#else
+  const unsigned int shift_amount        = ((~(uintptr_t)dest) & 3) * 8;
+#endif
+  const unsigned int masked_compare_val  = ((unsigned int)(unsigned char)compare_value),
+                     masked_exchange_val = ((unsigned int)(unsigned char)exchange_value),
+                     xor_value           = (masked_compare_val ^ masked_exchange_val) << shift_amount;
+
+  unsigned int old_value, value32;
+
+  __asm__ __volatile__ (
+    /* fence */
+    strasm_sync
+    /* simple guard */
+    "   lbz     %[old_value], 0(%[dest])                  \n"
+    "   cmpw    %[masked_compare_val], %[old_value]       \n"
+    "   bne-    2f                                        \n"
+    /* atomic loop */
+    "1:                                                   \n"
+    "   lwarx   %[value32], 0, %[dest_base]               \n"
+    /* extract byte and compare */
+    "   srd     %[old_value], %[value32], %[shift_amount] \n"
+    "   clrldi  %[old_value], %[old_value], 56            \n"
+    "   cmpw    %[masked_compare_val], %[old_value]       \n"
+    "   bne-    2f                                        \n"
+    /* replace byte and try to store */
+    "   xor     %[value32], %[xor_value], %[value32]      \n"
+    "   stwcx.  %[value32], 0, %[dest_base]               \n"
+    "   bne-    1b                                        \n"
+    /* acquire */
+    strasm_sync
+    /* exit */
+    "2:                                                   \n"
+    /* out */
+    : [old_value]           "=&r"   (old_value),
+      [value32]             "=&r"   (value32),
+                            "=m"    (*dest),
+                            "=m"    (*dest_base)
+    /* in */
+    : [dest]                "b"     (dest),
+      [dest_base]           "b"     (dest_base),
+      [shift_amount]        "r"     (shift_amount),
+      [masked_compare_val]  "r"     (masked_compare_val),
+      [xor_value]           "r"     (xor_value),
+                            "m"     (*dest),
+                            "m"     (*dest_base)
+    /* clobber */
+    : "cc",
+      "memory"
+    );
+
+  return (jbyte)(unsigned char)old_value;
+}
+
 inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
 
   // Note that cmpxchg guarantees a two-way memory barrier across
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -99,7 +99,7 @@
 // Frame information (pc, sp, fp) retrieved via ucontext
 // always looks like a C-frame according to the frame
 // conventions in frame_ppc64.hpp.
-address os::Linux::ucontext_get_pc(ucontext_t * uc) {
+address os::Linux::ucontext_get_pc(const ucontext_t * uc) {
   // On powerpc64, ucontext_t is not selfcontained but contains
   // a pointer to an optional substructure (mcontext_t.regs) containing the volatile
   // registers - NIP, among others.
@@ -122,19 +122,19 @@
   uc->uc_mcontext.regs->nip = (unsigned long)pc;
 }
 
-intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) {
   return (intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/];
 }
 
-intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) {
   return NULL;
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t* uc = (ucontext_t*)ucVoid;
+  const ucontext_t* uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
@@ -150,7 +150,7 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
@@ -564,10 +564,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t* uc = (ucontext_t*)context;
+  const ucontext_t* uc = (const ucontext_t*)context;
 
   st->print_cr("Registers:");
   st->print("pc =" INTPTR_FORMAT "  ", uc->uc_mcontext.regs->nip);
@@ -595,10 +595,10 @@
   st->cr();
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -92,7 +92,7 @@
 // signal frames. Currently we don't do that on Linux, so it's the
 // same as os::fetch_frame_from_context().
 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
-                                                ucontext_t* uc,
+                                                const ucontext_t* uc,
                                                 intptr_t** ret_sp,
                                                 intptr_t** ret_fp) {
   assert(thread != NULL, "just checking");
@@ -102,10 +102,10 @@
   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                                         intptr_t** ret_sp,
                                         intptr_t** ret_fp) {
-  ucontext_t* uc = (ucontext_t*) ucVoid;
+  const ucontext_t* uc = (const ucontext_t*) ucVoid;
   ExtendedPC  epc;
 
   if (uc != NULL) {
@@ -130,7 +130,7 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, NULL);
   return frame(sp, frame::unpatchable, epc.pc());
@@ -213,10 +213,10 @@
 
 void os::initialize_thread(Thread* thr) {}
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t* uc = (ucontext_t*)context;
+  const ucontext_t* uc = (const ucontext_t*)context;
   sigcontext* sc = (sigcontext*)context;
   st->print_cr("Registers:");
 
@@ -291,11 +291,11 @@
 }
 
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
-  sigcontext* sc = (sigcontext*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
+  const sigcontext* sc = (const sigcontext*)context;
   intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
 
   st->print_cr("Register to memory mapping:");
@@ -343,7 +343,7 @@
 }
 
 
-address os::Linux::ucontext_get_pc(ucontext_t* uc) {
+address os::Linux::ucontext_get_pc(const ucontext_t* uc) {
   return (address) SIG_PC((sigcontext*)uc);
 }
 
@@ -353,13 +353,13 @@
   SIG_NPC(ctx) = (intptr_t)(pc+4);
 }
 
-intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
+intptr_t* os::Linux::ucontext_get_sp(const ucontext_t *uc) {
   return (intptr_t*)
     ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS);
 }
 
 // not used on Sparc
-intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) {
+intptr_t* os::Linux::ucontext_get_fp(const ucontext_t *uc) {
   ShouldNotReachHere();
   return NULL;
 }
@@ -684,7 +684,7 @@
   }
 
   if (pc == NULL && uc != NULL) {
-    pc = os::Linux::ucontext_get_pc((ucontext_t*)uc);
+    pc = os::Linux::ucontext_get_pc((const ucontext_t*)uc);
   }
 
   // unmask current signal
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -117,7 +117,7 @@
 // Nothing to do.
 }
 
-address os::Linux::ucontext_get_pc(ucontext_t * uc) {
+address os::Linux::ucontext_get_pc(const ucontext_t * uc) {
   return (address)uc->uc_mcontext.gregs[REG_PC];
 }
 
@@ -125,11 +125,11 @@
   uc->uc_mcontext.gregs[REG_PC] = (intptr_t)pc;
 }
 
-intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) {
   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
 }
 
-intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
+intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) {
   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 }
 
@@ -138,8 +138,9 @@
 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
 // frames. Currently we don't do that on Linux, so it's the same as
 // os::fetch_frame_from_context().
+// This method is also used for stack overflow signal handling.
 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
-  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+  const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 
   assert(thread != NULL, "just checking");
   assert(ret_sp != NULL, "just checking");
@@ -148,11 +149,11 @@
   return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t* uc = (ucontext_t*)ucVoid;
+  const ucontext_t* uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
@@ -168,13 +169,57 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   return frame(sp, fp, epc.pc());
 }
 
+frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
+  intptr_t* sp;
+  intptr_t* fp;
+  ExtendedPC epc = os::Linux::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
+  return frame(sp, fp, epc.pc());
+}
+
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_ucontext(thread, uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      // in compiled code, the stack banging is performed just after the return pc
+      // has been pushed on the stack
+      intptr_t* fp = os::Linux::ucontext_get_fp(uc);
+      intptr_t* sp = os::Linux::ucontext_get_sp(uc);
+      *fr = frame(sp + 1, fp, (address)*sp);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get
 // turned off by -fomit-frame-pointer,
 frame os::get_sender_for_C_frame(frame* fr) {
@@ -305,13 +350,32 @@
           addr >= thread->stack_base() - thread->stack_size()) {
         // stack overflow
         if (thread->in_stack_yellow_zone(addr)) {
-          thread->disable_stack_yellow_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Java frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)(
+                      activation.fp() + frame::interpreter_frame_initial_sp_offset));
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.  Guard pages will be reenabled
             // while unwinding the stack.
+            thread->disable_stack_yellow_zone();
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           } else {
             // Thread was in the vm or native code.  Return and try to finish.
+            thread->disable_stack_yellow_zone();
             return 1;
           }
         } else if (thread->in_stack_red_zone(addr)) {
@@ -720,10 +784,10 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   st->print_cr("Registers:");
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, (intptr_t)uc->uc_mcontext.gregs[REG_RAX]);
@@ -783,10 +847,10 @@
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
@@ -868,7 +932,7 @@
    * we don't have much control or understanding of the address space, just let it slide.
    */
   char* hint = (char*) (Linux::initial_thread_stack_bottom() -
-                        ((StackYellowPages + StackRedPages + 1) * page_size));
+                        ((StackReservedPages + StackYellowPages + StackRedPages + 1) * page_size));
   char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
   if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
     return; // No matter, we tried, best effort.
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -100,7 +100,7 @@
   // Nothing to do.
 }
 
-address os::Linux::ucontext_get_pc(ucontext_t* uc) {
+address os::Linux::ucontext_get_pc(const ucontext_t* uc) {
   ShouldNotCallThis();
 }
 
@@ -108,13 +108,13 @@
   ShouldNotCallThis();
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                                         intptr_t** ret_sp,
                                         intptr_t** ret_fp) {
   ShouldNotCallThis();
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   ShouldNotCallThis();
 }
 
@@ -406,11 +406,11 @@
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
-void os::print_context(outputStream* st, void* context) {
+void os::print_context(outputStream* st, const void* context) {
   ShouldNotCallThis();
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   ShouldNotCallThis();
 }
 
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,7 +121,7 @@
 // There are issues with libthread giving out uc_links for different threads
 // on the same uc_link chain and bad or circular links.
 //
-bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
+bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect) {
   if (valid >= suspect ||
       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
@@ -148,10 +148,10 @@
 // We will only follow one level of uc_link since there are libthread
 // issues with ucontext linking and it is better to be safe and just
 // let caller retry later.
-ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
-  ucontext_t *uc) {
+const ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
+  const ucontext_t *uc) {
 
-  ucontext_t *retuc = NULL;
+  const ucontext_t *retuc = NULL;
 
   // Sometimes the topmost register windows are not properly flushed.
   // i.e., if the kernel would have needed to take a page fault
@@ -179,7 +179,7 @@
 }
 
 // Assumes ucontext is valid
-ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
+ExtendedPC os::Solaris::ucontext_get_ExtendedPC(const ucontext_t *uc) {
   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
   // set npc to zero to avoid using it for safepoint, good for profiling only
   return ExtendedPC(pc);
@@ -191,17 +191,17 @@
 }
 
 // Assumes ucontext is valid
-intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
+intptr_t* os::Solaris::ucontext_get_sp(const ucontext_t *uc) {
   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
 }
 
 // Solaris X86 only
-intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
+intptr_t* os::Solaris::ucontext_get_fp(const ucontext_t *uc) {
   ShouldNotReachHere();
   return NULL;
 }
 
-address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+address os::Solaris::ucontext_get_pc(const ucontext_t *uc) {
   return (address) uc->uc_mcontext.gregs[REG_PC];
 }
 
@@ -213,25 +213,26 @@
 //
 // The difference between this and os::fetch_frame_from_context() is that
 // here we try to skip nested signal frames.
+// This method is also used for stack overflow signal handling.
 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
-  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+  const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 
   assert(thread != NULL, "just checking");
   assert(ret_sp != NULL, "just checking");
   assert(ret_fp == NULL, "just checking");
 
-  ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
+  const ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
 
   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 }
 
 
 // ret_fp parameter is only used by Solaris X86.
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t *uc = (ucontext_t*)ucVoid;
+  const ucontext_t *uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
@@ -245,13 +246,48 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   return frame(sp, frame::unpatchable, epc.pc());
 }
 
+frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
+  intptr_t* sp;
+  ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, NULL);
+  return frame(sp, frame::unpatchable, epc.pc());
+}
+
+bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Solaris::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    *fr = os::fetch_frame_from_ucontext(thread, uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      *fr = os::fetch_frame_from_ucontext(thread, uc);
+      *fr = frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 frame os::get_sender_for_C_frame(frame* fr) {
   return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
 }
@@ -367,17 +403,32 @@
     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
       address addr = (address) info->si_addr;
       if (thread->in_stack_yellow_zone(addr)) {
-        thread->disable_stack_yellow_zone();
         // Sometimes the register windows are not properly flushed.
         if(uc->uc_mcontext.gwins != NULL) {
           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
         }
         if (thread->thread_state() == _thread_in_Java) {
+          if (thread->in_stack_reserved_zone(addr)) {
+            frame fr;
+            if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+              assert(fr.is_java_frame(), "Must be a Java frame");
+              frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+              if (activation.sp() != NULL) {
+                thread->disable_stack_reserved_zone();
+                RegisterMap map(thread);
+                int frame_size = activation.frame_size(&map);
+                thread->set_reserved_stack_activation((address)(((address)activation.sp()) - STACK_BIAS));
+                return true;
+              }
+            }
+          }
           // Throw a stack overflow exception.  Guard pages will be reenabled
           // while unwinding the stack.
+          thread->disable_stack_yellow_zone();
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
         } else {
           // Thread was in the vm or native code.  Return and try to finish.
+          thread->disable_stack_yellow_zone();
           return true;
         }
       } else if (thread->in_stack_red_zone(addr)) {
@@ -554,10 +605,10 @@
   return false;
 }
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   st->print_cr("Registers:");
 
   st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
@@ -631,10 +682,10 @@
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
 
   st->print_cr("Register to memory mapping:");
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -121,7 +121,7 @@
 // There are issues with libthread giving out uc_links for different threads
 // on the same uc_link chain and bad or circular links.
 //
-bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
+bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect) {
   if (valid >= suspect ||
       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
@@ -146,10 +146,10 @@
 // We will only follow one level of uc_link since there are libthread
 // issues with ucontext linking and it is better to be safe and just
 // let caller retry later.
-ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
-  ucontext_t *uc) {
+const ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
+  const ucontext_t *uc) {
 
-  ucontext_t *retuc = NULL;
+  const ucontext_t *retuc = NULL;
 
   if (uc != NULL) {
     if (uc->uc_link == NULL) {
@@ -171,7 +171,7 @@
 }
 
 // Assumes ucontext is valid
-ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
+ExtendedPC os::Solaris::ucontext_get_ExtendedPC(const ucontext_t *uc) {
   return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]);
 }
 
@@ -180,16 +180,16 @@
 }
 
 // Assumes ucontext is valid
-intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
+intptr_t* os::Solaris::ucontext_get_sp(const ucontext_t *uc) {
   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
 }
 
 // Assumes ucontext is valid
-intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
+intptr_t* os::Solaris::ucontext_get_fp(const ucontext_t *uc) {
   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 }
 
-address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+address os::Solaris::ucontext_get_pc(const ucontext_t *uc) {
   return (address) uc->uc_mcontext.gregs[REG_PC];
 }
 
@@ -198,22 +198,23 @@
 //
 // The difference between this and os::fetch_frame_from_context() is that
 // here we try to skip nested signal frames.
+// This method is also used for stack overflow signal handling.
 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
-  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+  const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 
   assert(thread != NULL, "just checking");
   assert(ret_sp != NULL, "just checking");
   assert(ret_fp != NULL, "just checking");
 
-  ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
+  const ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 }
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
-  ucontext_t *uc = (ucontext_t*)ucVoid;
+  const ucontext_t *uc = (const ucontext_t*)ucVoid;
 
   if (uc != NULL) {
     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
@@ -229,13 +230,56 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   return frame(sp, fp, epc.pc());
 }
 
+frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
+  intptr_t* sp;
+  intptr_t* fp;
+  ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
+  return frame(sp, fp, epc.pc());
+}
+
+bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+ address pc = (address) os::Solaris::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_ucontext(thread, uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      // in compiled code, the stack banging is performed just after the return pc
+      // has been pushed on the stack
+      intptr_t* fp = os::Solaris::ucontext_get_fp(uc);
+      intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
+      *fr = frame(sp + 1, fp, (address)*sp);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 frame os::get_sender_for_C_frame(frame* fr) {
   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 }
@@ -422,13 +466,31 @@
     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
       address addr = (address) info->si_addr;
       if (thread->in_stack_yellow_zone(addr)) {
-        thread->disable_stack_yellow_zone();
         if (thread->thread_state() == _thread_in_Java) {
+          if (thread->in_stack_reserved_zone(addr)) {
+            frame fr;
+            if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+              assert(fr.is_java_frame(), "Must be Java frame");
+              frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+              if (activation.sp() != NULL) {
+                thread->disable_stack_reserved_zone();
+                if (activation.is_interpreted_frame()) {
+                  thread->set_reserved_stack_activation((address)(
+                    activation.fp() + frame::interpreter_frame_initial_sp_offset));
+                } else {
+                  thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                }
+                return true;
+              }
+            }
+          }
           // Throw a stack overflow exception.  Guard pages will be reenabled
           // while unwinding the stack.
+          thread->disable_stack_yellow_zone();
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
         } else {
           // Thread was in the vm or native code.  Return and try to finish.
+          thread->disable_stack_yellow_zone();
           return true;
         }
       } else if (thread->in_stack_red_zone(addr)) {
@@ -712,10 +774,10 @@
   return false;
 }
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
   st->print_cr("Registers:");
 #ifdef AMD64
   st->print(  "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
@@ -771,10 +833,10 @@
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 }
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  ucontext_t *uc = (ucontext_t*)context;
+  const ucontext_t *uc = (const ucontext_t*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -359,7 +359,7 @@
  *     while (...) {...  fr = os::get_sender_for_C_frame(&fr); }
  * loop in vmError.cpp. We need to roll our own loop.
  */
-bool os::platform_print_native_stack(outputStream* st, void* context,
+bool os::platform_print_native_stack(outputStream* st, const void* context,
                                      char *buf, int buf_size)
 {
   CONTEXT ctx;
@@ -435,7 +435,7 @@
 }
 #endif // AMD64
 
-ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
                     intptr_t** ret_sp, intptr_t** ret_fp) {
 
   ExtendedPC  epc;
@@ -455,7 +455,7 @@
   return epc;
 }
 
-frame os::fetch_frame_from_context(void* ucVoid) {
+frame os::fetch_frame_from_context(const void* ucVoid) {
   intptr_t* sp;
   intptr_t* fp;
   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
@@ -527,10 +527,10 @@
   }
 }
 
-void os::print_context(outputStream *st, void *context) {
+void os::print_context(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  CONTEXT* uc = (CONTEXT*)context;
+  const CONTEXT* uc = (const CONTEXT*)context;
 
   st->print_cr("Registers:");
 #ifdef AMD64
@@ -588,10 +588,10 @@
 }
 
 
-void os::print_register_info(outputStream *st, void *context) {
+void os::print_register_info(outputStream *st, const void *context) {
   if (context == NULL) return;
 
-  CONTEXT* uc = (CONTEXT*)context;
+  const CONTEXT* uc = (const CONTEXT*)context;
 
   st->print_cr("Register to memory mapping:");
   st->cr();
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -66,7 +66,7 @@
 
 #ifdef AMD64
 #define PLATFORM_PRINT_NATIVE_STACK 1
-static bool platform_print_native_stack(outputStream* st, void* context,
+static bool platform_print_native_stack(outputStream* st, const void* context,
                                         char *buf, int buf_size);
 #endif
 
--- a/hotspot/src/share/tools/hsdis/Makefile	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/tools/hsdis/Makefile	Tue Jan 05 13:08:02 2016 -0800
@@ -70,12 +70,12 @@
 else   #linux
 CPU             = $(shell uname -m)
 ARCH1=$(CPU:x86_64=amd64)
-ARCH2=$(ARCH1:i686=i386)
-ARCH=$(ARCH2:ppc64le=ppc64)
+ARCH=$(ARCH1:i686=i386)
 ifdef LP64
 CFLAGS/sparcv9	+= -m64
 CFLAGS/amd64	+= -m64
 CFLAGS/ppc64	+= -m64
+CFLAGS/ppc64le  += -m64 -DABI_ELFv2
 else
 ARCH=$(ARCH1:amd64=i386)
 CFLAGS/i386	+= -m32
--- a/hotspot/src/share/tools/hsdis/hsdis-demo.c	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/tools/hsdis/hsdis-demo.c	Tue Jan 05 13:08:02 2016 -0800
@@ -66,7 +66,7 @@
   printf("...And now for something completely different:\n");
   void *start = (void*) &main;
   void *end = (void*) &end_of_file;
-#if defined(__ia64) || defined(__powerpc__)
+#if defined(__ia64) || (defined(__powerpc__) && !defined(ABI_ELFv2))
   /* On IA64 and PPC function pointers are pointers to function descriptors */
   start = *((void**)start);
   end = *((void**)end);
--- a/hotspot/src/share/tools/hsdis/hsdis.c	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/tools/hsdis/hsdis.c	Tue Jan 05 13:08:02 2016 -0800
@@ -461,7 +461,7 @@
 #ifdef LIBARCH_sparcv9
   res = "sparc:v9b";
 #endif
-#ifdef LIBARCH_ppc64
+#if  defined(LIBARCH_ppc64) || defined(LIBARCH_ppc64le)
   res = "powerpc:common64";
 #endif
 #ifdef LIBARCH_aarch64
--- a/hotspot/src/share/vm/Xusage.txt	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/Xusage.txt	Tue Jan 05 13:08:02 2016 -0800
@@ -8,7 +8,6 @@
                       prepend in front of bootstrap class path
     -Xnoclassgc       disable class garbage collection
     -Xlog:<opts>      control JVM logging, use -Xlog:help for details
-    -Xloggc:<file>    log GC status to a file with time stamps
     -Xbatch           disable background compilation
     -Xms<size>        set initial Java heap size
     -Xmx<size>        set maximum Java heap size
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -551,6 +551,7 @@
 , _would_profile(false)
 , _has_unsafe_access(false)
 , _has_method_handle_invokes(false)
+, _has_reserved_stack_access(method->has_reserved_stack_access())
 , _bailout_msg(NULL)
 , _exception_info_list(NULL)
 , _allocator(NULL)
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,6 +81,7 @@
   bool               _has_unsafe_access;
   bool               _would_profile;
   bool               _has_method_handle_invokes;  // True if this method has MethodHandle invokes.
+  bool               _has_reserved_stack_access;
   const char*        _bailout_msg;
   ExceptionInfoList* _exception_info_list;
   ExceptionHandlerTable _exception_handler_table;
@@ -171,6 +172,9 @@
   bool     has_method_handle_invokes() const { return _has_method_handle_invokes;     }
   void set_has_method_handle_invokes(bool z) {        _has_method_handle_invokes = z; }
 
+  bool     has_reserved_stack_access() const { return _has_reserved_stack_access; }
+  void set_has_reserved_stack_access(bool z) { _has_reserved_stack_access = z; }
+
   DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info();
   Dependencies* dependency_recorder() const; // = _env->dependencies()
   ImplicitExceptionTable* implicit_exception_table()     { return &_implicit_exception_table; }
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -3322,7 +3322,13 @@
 
   // method handle invokes
   if (callee->is_method_handle_intrinsic()) {
-    return try_method_handle_inline(callee);
+    if (try_method_handle_inline(callee)) {
+      if (callee->has_reserved_stack_access()) {
+        compilation()->set_has_reserved_stack_access(true);
+      }
+      return true;
+    }
+    return false;
   }
 
   // handle intrinsics
@@ -3330,6 +3336,9 @@
       (CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
     if (try_inline_intrinsics(callee)) {
       print_inlining(callee, "intrinsic");
+      if (callee->has_reserved_stack_access()) {
+        compilation()->set_has_reserved_stack_access(true);
+      }
       return true;
     }
     // try normal inlining
@@ -3346,8 +3355,12 @@
   if (bc == Bytecodes::_illegal) {
     bc = code();
   }
-  if (try_inline_full(callee, holder_known, bc, receiver))
+  if (try_inline_full(callee, holder_known, bc, receiver)) {
+    if (callee->has_reserved_stack_access()) {
+      compilation()->set_has_reserved_stack_access(true);
+    }
     return true;
+  }
 
   // Entire compilation could fail during try_inline_full call.
   // In that case printing inlining decision info is useless.
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -502,7 +502,7 @@
   // Check the stack guard pages and reenable them if necessary and there is
   // enough space on the stack to do so.  Use fast exceptions only if the guard
   // pages are enabled.
-  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+  bool guard_pages_enabled = thread->stack_guards_enabled();
   if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
 
   if (JvmtiExport::can_post_on_exceptions()) {
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -91,6 +91,7 @@
   _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
   _is_c1_compilable   = !h_m()->is_not_c1_compilable();
   _is_c2_compilable   = !h_m()->is_not_c2_compilable();
+  _has_reserved_stack_access = h_m()->has_reserved_stack_access();
   // Lazy fields, filled in on demand.  Require allocation.
   _code               = NULL;
   _exception_handlers = NULL;
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -81,6 +81,7 @@
   bool _is_c1_compilable;
   bool _is_c2_compilable;
   bool _can_be_statically_bound;
+  bool _has_reserved_stack_access;
 
   // Lazy fields, filled in on demand
   address              _code;
@@ -316,6 +317,7 @@
   bool is_accessor    () const;
   bool is_initializer () const;
   bool can_be_statically_bound() const           { return _can_be_statically_bound; }
+  bool has_reserved_stack_access() const         { return _has_reserved_stack_access; }
   bool is_boxing_method() const;
   bool is_unboxing_method() const;
 
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -946,6 +946,7 @@
     _method_HotSpotIntrinsicCandidate,
     _jdk_internal_vm_annotation_Contended,
     _field_Stable,
+    _jdk_internal_vm_annotation_ReservedStackAccess,
     _annotation_LIMIT
   };
   const Location _location;
@@ -2016,6 +2017,11 @@
       }
       return _jdk_internal_vm_annotation_Contended;
     }
+    case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ReservedStackAccess_signature): {
+      if (_location != _in_method)  break;  // only allow for methods
+      if (RestrictReservedStack && !privileged) break; // honor privileges
+      return _jdk_internal_vm_annotation_ReservedStackAccess;
+    }
     default: {
       break;
     }
@@ -2051,6 +2057,8 @@
     m->set_hidden(true);
   if (has_annotation(_method_HotSpotIntrinsicCandidate) && !m->is_synthetic())
     m->set_intrinsic_candidate(true);
+  if (has_annotation(_jdk_internal_vm_annotation_ReservedStackAccess))
+    m->set_has_reserved_stack_access(true);
 }
 
 void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -212,6 +212,7 @@
   template(java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpdater, "java/util/concurrent/atomic/AtomicLongFieldUpdater$LockedUpdater") \
   template(java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl,     "java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl") \
   template(jdk_internal_vm_annotation_Contended_signature,                   "Ljdk/internal/vm/annotation/Contended;")    \
+  template(jdk_internal_vm_annotation_ReservedStackAccess_signature,         "Ljdk/internal/vm/annotation/ReservedStackAccess;") \
                                                                                                   \
   /* class symbols needed by intrinsics */                                                        \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
--- a/hotspot/src/share/vm/gc/cms/allocationStats.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/allocationStats.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_CMS_ALLOCATIONSTATS_HPP
 
 #include "gc/shared/gcUtil.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
@@ -119,11 +120,9 @@
       ssize_t old_desired = _desired;
       float delta_ise = (CMSExtrapolateSweep ? intra_sweep_estimate : 0.0);
       _desired = (ssize_t)(new_rate * (inter_sweep_estimate + delta_ise));
-      if (PrintFLSStatistics > 1) {
-        gclog_or_tty->print_cr("demand: " SSIZE_FORMAT ", old_rate: %f, current_rate: %f, "
-                               "new_rate: %f, old_desired: " SSIZE_FORMAT ", new_desired: " SSIZE_FORMAT,
-                                demand, old_rate, rate, new_rate, old_desired, _desired);
-      }
+      log_trace(gc, freelist)("demand: " SSIZE_FORMAT ", old_rate: %f, current_rate: %f, "
+                              "new_rate: %f, old_desired: " SSIZE_FORMAT ", new_desired: " SSIZE_FORMAT,
+                              demand, old_rate, rate, new_rate, old_desired, _desired);
     }
   }
 
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -400,17 +400,16 @@
 
 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
 const {
-  reportIndexedFreeListStatistics();
-  gclog_or_tty->print_cr("Layout of Indexed Freelists");
-  gclog_or_tty->print_cr("---------------------------");
+  reportIndexedFreeListStatistics(st);
+  st->print_cr("Layout of Indexed Freelists");
+  st->print_cr("---------------------------");
   AdaptiveFreeList<FreeChunk>::print_labels_on(st, "size");
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    _indexedFreeList[i].print_on(gclog_or_tty);
-    for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
-         fc = fc->next()) {
-      gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ")  %s",
-                          p2i(fc), p2i((HeapWord*)fc + i),
-                          fc->cantCoalesce() ? "\t CC" : "");
+    _indexedFreeList[i].print_on(st);
+    for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; fc = fc->next()) {
+      st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ")  %s",
+                   p2i(fc), p2i((HeapWord*)fc + i),
+                   fc->cantCoalesce() ? "\t CC" : "");
     }
   }
 }
@@ -422,7 +421,7 @@
 
 void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st)
 const {
-  _dictionary->report_statistics();
+  _dictionary->report_statistics(st);
   st->print_cr("Layout of Freelists in Tree");
   st->print_cr("---------------------------");
   _dictionary->print_free_lists(st);
@@ -472,54 +471,58 @@
   return sz;
 }
 
-void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c,
-  outputStream* st) {
-  st->print_cr("\n=========================");
+void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c, outputStream* st) {
+  st->print_cr("=========================");
   st->print_cr("Block layout in CMS Heap:");
   st->print_cr("=========================");
   BlkPrintingClosure  bpcl(c, this, c->markBitMap(), st);
   blk_iterate(&bpcl);
 
-  st->print_cr("\n=======================================");
+  st->print_cr("=======================================");
   st->print_cr("Order & Layout of Promotion Info Blocks");
   st->print_cr("=======================================");
   print_promo_info_blocks(st);
 
-  st->print_cr("\n===========================");
+  st->print_cr("===========================");
   st->print_cr("Order of Indexed Free Lists");
   st->print_cr("=========================");
   print_indexed_free_lists(st);
 
-  st->print_cr("\n=================================");
+  st->print_cr("=================================");
   st->print_cr("Order of Free Lists in Dictionary");
   st->print_cr("=================================");
   print_dictionary_free_lists(st);
 }
 
 
-void CompactibleFreeListSpace::reportFreeListStatistics() const {
+void CompactibleFreeListSpace::reportFreeListStatistics(const char* title) const {
   assert_lock_strong(&_freelistLock);
-  assert(PrintFLSStatistics != 0, "Reporting error");
-  _dictionary->report_statistics();
-  if (PrintFLSStatistics > 1) {
-    reportIndexedFreeListStatistics();
+  LogHandle(gc, freelist, stats) log;
+  if (!log.is_debug()) {
+    return;
+  }
+  log.debug("%s", title);
+  _dictionary->report_statistics(log.debug_stream());
+  if (log.is_trace()) {
+    ResourceMark rm;
+    reportIndexedFreeListStatistics(log.trace_stream());
     size_t total_size = totalSizeInIndexedFreeLists() +
                        _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
-    gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag());
+    log.trace(" free=" SIZE_FORMAT " frag=%1.4f", total_size, flsFrag());
   }
 }
 
-void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
+void CompactibleFreeListSpace::reportIndexedFreeListStatistics(outputStream* st) const {
   assert_lock_strong(&_freelistLock);
-  gclog_or_tty->print("Statistics for IndexedFreeLists:\n"
-                      "--------------------------------\n");
+  st->print_cr("Statistics for IndexedFreeLists:");
+  st->print_cr("--------------------------------");
   size_t total_size = totalSizeInIndexedFreeLists();
-  size_t   free_blocks = numFreeBlocksInIndexedFreeLists();
-  gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size);
-  gclog_or_tty->print("Max   Chunk Size: " SIZE_FORMAT "\n", maxChunkSizeInIndexedFreeLists());
-  gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks);
+  size_t free_blocks = numFreeBlocksInIndexedFreeLists();
+  st->print_cr("Total Free Space: " SIZE_FORMAT, total_size);
+  st->print_cr("Max   Chunk Size: " SIZE_FORMAT, maxChunkSizeInIndexedFreeLists());
+  st->print_cr("Number of Blocks: " SIZE_FORMAT, free_blocks);
   if (free_blocks != 0) {
-    gclog_or_tty->print("Av.  Block  Size: " SIZE_FORMAT "\n", total_size/free_blocks);
+    st->print_cr("Av.  Block  Size: " SIZE_FORMAT, total_size/free_blocks);
   }
 }
 
@@ -1824,10 +1827,7 @@
 void
 CompactibleFreeListSpace::gc_prologue() {
   assert_locked();
-  if (PrintFLSStatistics != 0) {
-    gclog_or_tty->print("Before GC:\n");
-    reportFreeListStatistics();
-  }
+  reportFreeListStatistics("Before GC:");
   refillLinearAllocBlocksIfNeeded();
 }
 
@@ -1837,11 +1837,7 @@
   assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
   _promoInfo.stopTrackingPromotions();
   repairLinearAllocationBlocks();
-  // Print Space's stats
-  if (PrintFLSStatistics != 0) {
-    gclog_or_tty->print("After GC:\n");
-    reportFreeListStatistics();
-  }
+  reportFreeListStatistics("After GC:");
 }
 
 // Iteration support, mostly delegated from a CMS generation
@@ -2014,9 +2010,7 @@
   size_t i;
   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
     AdaptiveFreeList<FreeChunk>* fl    = &_indexedFreeList[i];
-    if (PrintFLSStatistics > 1) {
-      gclog_or_tty->print("size[" SIZE_FORMAT "] : ", i);
-    }
+    log_trace(gc, freelist)("size[" SIZE_FORMAT "] : ", i);
     fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
     fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
     fl->set_before_sweep(fl->count());
@@ -2065,16 +2059,10 @@
 }
 
 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
-  if (PrintFLSStatistics > 0) {
-    HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict();
-    gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT,
-                           p2i(largestAddr));
-  }
+  log_debug(gc, freelist)("CMS: Large block " PTR_FORMAT, p2i(dictionary()->find_largest_dict()));
   setFLSurplus();
   setFLHints();
-  if (PrintGC && PrintFLSCensus > 0) {
-    printFLCensus(sweep_count);
-  }
+  printFLCensus(sweep_count);
   clearFLCensus();
   assert_locked();
   _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent);
@@ -2213,14 +2201,15 @@
       }
     }
     if (res == 0) {
-      gclog_or_tty->print_cr("Livelock: no rank reduction!");
-      gclog_or_tty->print_cr(
-        " Current:  addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n"
-        " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n",
+      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",
         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");
-      _sp->print_on(gclog_or_tty);
-      guarantee(false, "Seppuku!");
+      ResourceMark rm;
+      _sp->print_on(log.info_stream());
+      guarantee(false, "Verification failed.");
     }
     _last_addr = addr;
     _last_size = res;
@@ -2386,17 +2375,23 @@
 
 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
   assert_lock_strong(&_freelistLock);
+  LogHandle(gc, freelist, census) log;
+  if (!log.is_debug()) {
+    return;
+  }
   AdaptiveFreeList<FreeChunk> total;
-  gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
-  AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+  log.debug("end sweep# " SIZE_FORMAT, sweep_count);
+  ResourceMark rm;
+  outputStream* out = log.debug_stream();
+  AdaptiveFreeList<FreeChunk>::print_labels_on(out, "size");
   size_t total_free = 0;
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
     const AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
     total_free += fl->count() * fl->size();
     if (i % (40*IndexSetStride) == 0) {
-      AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+      AdaptiveFreeList<FreeChunk>::print_labels_on(out, "size");
     }
-    fl->print_on(gclog_or_tty);
+    fl->print_on(out);
     total.set_bfr_surp(    total.bfr_surp()     + fl->bfr_surp()    );
     total.set_surplus(    total.surplus()     + fl->surplus()    );
     total.set_desired(    total.desired()     + fl->desired()    );
@@ -2408,14 +2403,13 @@
     total.set_split_births(total.split_births() + fl->split_births());
     total.set_split_deaths(total.split_deaths() + fl->split_deaths());
   }
-  total.print_on(gclog_or_tty, "TOTAL");
-  gclog_or_tty->print_cr("Total free in indexed lists "
-                         SIZE_FORMAT " words", total_free);
-  gclog_or_tty->print("growth: %8.5f  deficit: %8.5f\n",
-    (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/
-            (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0),
-    (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
-  _dictionary->print_dict_census();
+  total.print_on(out, "TOTAL");
+  log.debug("Total free in indexed lists " SIZE_FORMAT " words", total_free);
+  log.debug("growth: %8.5f  deficit: %8.5f",
+            (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/
+                    (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0),
+            (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
+  _dictionary->print_dict_census(out);
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -2544,10 +2538,7 @@
       // Reset counters for next round
       _global_num_workers[i] = 0;
       _global_num_blocks[i] = 0;
-      if (PrintOldPLAB) {
-        gclog_or_tty->print_cr("[" SIZE_FORMAT "]: " SIZE_FORMAT,
-                               i, (size_t)_blocks_to_claim[i].average());
-      }
+      log_trace(gc, plab)("[" SIZE_FORMAT "]: " SIZE_FORMAT, i, (size_t)_blocks_to_claim[i].average());
     }
   }
 }
@@ -2584,10 +2575,8 @@
           _indexedFreeList[i].set_size(i);
         }
       }
-      if (PrintOldPLAB) {
-        gclog_or_tty->print_cr("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT,
-                               tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
-      }
+      log_trace(gc, plab)("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT,
+                          tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
       // Reset stats for next round
       _num_blocks[i]         = 0;
     }
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "gc/cms/promotionInfo.hpp"
 #include "gc/shared/blockOffsetTable.hpp"
 #include "gc/shared/space.hpp"
+#include "logging/log.hpp"
 #include "memory/binaryTreeDictionary.hpp"
 #include "memory/freeList.hpp"
 
@@ -275,8 +276,8 @@
   void       verify_objects_initialized() const;
 
   // Statistics reporting helper functions
-  void       reportFreeListStatistics() const;
-  void       reportIndexedFreeListStatistics() const;
+  void       reportFreeListStatistics(const char* title) const;
+  void       reportIndexedFreeListStatistics(outputStream* st) const;
   size_t     maxChunkSizeInIndexedFreeLists() const;
   size_t     numFreeBlocksInIndexedFreeLists() const;
   // Accessor
@@ -450,11 +451,9 @@
   void save_sweep_limit() {
     _sweep_limit = BlockOffsetArrayUseUnallocatedBlock ?
                    unallocated_block() : end();
-    if (CMSTraceSweeper) {
-      gclog_or_tty->print_cr(">>>>> Saving sweep limit " PTR_FORMAT
-                             "  for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<",
-                             p2i(_sweep_limit), p2i(bottom()), p2i(end()));
-    }
+    log_develop_trace(gc, sweep)(">>>>> Saving sweep limit " PTR_FORMAT
+                                 "  for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<",
+                                 p2i(_sweep_limit), p2i(bottom()), p2i(end()));
   }
   NOT_PRODUCT(
     void clear_sweep_limit() { _sweep_limit = NULL; }
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -47,13 +47,14 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/padded.hpp"
@@ -65,6 +66,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/orderAccess.inline.hpp"
+#include "runtime/timer.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/memoryService.hpp"
 #include "services/runtimeService.hpp"
@@ -367,13 +369,9 @@
     cms_adjustment = cms_adjustment * cms_free_adjustment_factor(cms_free);
     cms_free_dbl = cms_free_dbl * cms_adjustment;
 
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("CMSStats::time_until_cms_gen_full: cms_free "
-        SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
-        cms_free, expected_promotion);
-      gclog_or_tty->print_cr("  cms_free_dbl %f cms_consumption_rate %f",
-        cms_free_dbl, cms_consumption_rate() + 1.0);
-    }
+    log_trace(gc)("CMSStats::time_until_cms_gen_full: cms_free " SIZE_FORMAT " expected_promotion " SIZE_FORMAT,
+                  cms_free, expected_promotion);
+    log_trace(gc)("  cms_free_dbl %f cms_consumption_rate %f", cms_free_dbl, cms_consumption_rate() + 1.0);
     // Add 1 in case the consumption rate goes to zero.
     return cms_free_dbl / (cms_consumption_rate() + 1.0);
   }
@@ -402,12 +400,8 @@
   // If a concurrent mode failure occurred recently, we want to be
   // more conservative and halve our expected time_until_cms_gen_full()
   if (work > deadline) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print(
-        " CMSCollector: collect because of anticipated promotion "
-        "before full %3.7f + %3.7f > %3.7f ", cms_duration(),
-        gc0_period(), time_until_cms_gen_full());
-    }
+    log_develop_trace(gc)("CMSCollector: collect because of anticipated promotion before full %3.7f + %3.7f > %3.7f ",
+                          cms_duration(), gc0_period(), time_until_cms_gen_full());
     return 0.0;
   }
   return work - deadline;
@@ -669,31 +663,6 @@
 }
 #endif
 
-void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) {
-  GenCollectedHeap* gch = GenCollectedHeap::heap();
-  if (PrintGCDetails) {
-    // I didn't want to change the logging when removing the level concept,
-    // but I guess this logging could say "old" or something instead of "1".
-    assert(gch->is_old_gen(this),
-           "The CMS generation should be the old generation");
-    uint level = 1;
-    if (Verbose) {
-      gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "(" SIZE_FORMAT ")]",
-        level, short_name(), s, used(), capacity());
-    } else {
-      gclog_or_tty->print("[%u %s-%s: " SIZE_FORMAT "K(" SIZE_FORMAT "K)]",
-        level, short_name(), s, used() / K, capacity() / K);
-    }
-  }
-  if (Verbose) {
-    gclog_or_tty->print(" " SIZE_FORMAT "(" SIZE_FORMAT ")",
-              gch->used(), gch->capacity());
-  } else {
-    gclog_or_tty->print(" " SIZE_FORMAT "K(" SIZE_FORMAT "K)",
-              gch->used() / K, gch->capacity() / K);
-  }
-}
-
 size_t
 ConcurrentMarkSweepGeneration::contiguous_available() const {
   // dld proposes an improvement in precision here. If the committed
@@ -717,21 +686,18 @@
   size_t available = max_available();
   size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();
   bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);
-  if (Verbose && PrintGCDetails) {
-    gclog_or_tty->print_cr(
-      "CMS: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "),"
-      "max_promo(" SIZE_FORMAT ")",
-      res? "":" not", available, res? ">=":"<",
-      av_promo, max_promotion_in_bytes);
-  }
+  log_trace(gc, promotion)("CMS: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "), max_promo(" SIZE_FORMAT ")",
+                           res? "":" not", available, res? ">=":"<", av_promo, max_promotion_in_bytes);
   return res;
 }
 
 // At a promotion failure dump information on block layout in heap
 // (cms old generation).
 void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
-  if (CMSDumpAtPromotionFailure) {
-    cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
+  LogHandle(gc, promotion) log;
+  if (log.is_trace()) {
+    ResourceMark rm;
+    cmsSpace()->dump_at_safepoint_with_locks(collector(), log.trace_stream());
   }
 }
 
@@ -787,27 +753,26 @@
     size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
     assert(desired_capacity >= capacity(), "invalid expansion size");
     size_t expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
-    if (PrintGCDetails && Verbose) {
+    LogHandle(gc) log;
+    if (log.is_trace()) {
       size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
-      gclog_or_tty->print_cr("\nFrom compute_new_size: ");
-      gclog_or_tty->print_cr("  Free fraction %f", free_percentage);
-      gclog_or_tty->print_cr("  Desired free fraction %f", desired_free_percentage);
-      gclog_or_tty->print_cr("  Maximum free fraction %f", maximum_free_percentage);
-      gclog_or_tty->print_cr("  Capacity " SIZE_FORMAT, capacity() / 1000);
-      gclog_or_tty->print_cr("  Desired capacity " SIZE_FORMAT, desired_capacity / 1000);
+      log.trace("From compute_new_size: ");
+      log.trace("  Free fraction %f", free_percentage);
+      log.trace("  Desired free fraction %f", desired_free_percentage);
+      log.trace("  Maximum free fraction %f", maximum_free_percentage);
+      log.trace("  Capacity " SIZE_FORMAT, capacity() / 1000);
+      log.trace("  Desired capacity " SIZE_FORMAT, desired_capacity / 1000);
       GenCollectedHeap* gch = GenCollectedHeap::heap();
       assert(gch->is_old_gen(this), "The CMS generation should always be the old generation");
       size_t young_size = gch->young_gen()->capacity();
-      gclog_or_tty->print_cr("  Young gen size " SIZE_FORMAT, young_size / 1000);
-      gclog_or_tty->print_cr("  unsafe_max_alloc_nogc " SIZE_FORMAT, unsafe_max_alloc_nogc() / 1000);
-      gclog_or_tty->print_cr("  contiguous available " SIZE_FORMAT, contiguous_available() / 1000);
-      gclog_or_tty->print_cr("  Expand by " SIZE_FORMAT " (bytes)", expand_bytes);
+      log.trace("  Young gen size " SIZE_FORMAT, young_size / 1000);
+      log.trace("  unsafe_max_alloc_nogc " SIZE_FORMAT, unsafe_max_alloc_nogc() / 1000);
+      log.trace("  contiguous available " SIZE_FORMAT, contiguous_available() / 1000);
+      log.trace("  Expand by " SIZE_FORMAT " (bytes)", expand_bytes);
     }
     // safe if expansion fails
     expand_for_gc_cause(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio);
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("  Expanded free fraction %f", ((double) free()) / capacity());
-    }
+    log.trace("  Expanded free fraction %f", ((double) free()) / capacity());
   } else {
     size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
     assert(desired_capacity <= capacity(), "invalid expansion size");
@@ -1145,10 +1110,7 @@
 
 bool CMSCollector::shouldConcurrentCollect() {
   if (_full_gc_requested) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
-                             " gc request (or gc_locker)");
-    }
+    log_trace(gc)("CMSCollector: collect because of explicit  gc request (or gc_locker)");
     return true;
   }
 
@@ -1156,24 +1118,21 @@
   // ------------------------------------------------------------------
   // Print out lots of information which affects the initiation of
   // a collection.
-  if (PrintCMSInitiationStatistics && stats().valid()) {
-    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
-    gclog_or_tty->stamp();
-    gclog_or_tty->cr();
-    stats().print_on(gclog_or_tty);
-    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
-      stats().time_until_cms_gen_full());
-    gclog_or_tty->print_cr("free=" SIZE_FORMAT, _cmsGen->free());
-    gclog_or_tty->print_cr("contiguous_available=" SIZE_FORMAT,
-                           _cmsGen->contiguous_available());
-    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
-    gclog_or_tty->print_cr("cms_allocation_rate=%g", stats().cms_allocation_rate());
-    gclog_or_tty->print_cr("occupancy=%3.7f", _cmsGen->occupancy());
-    gclog_or_tty->print_cr("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
-    gclog_or_tty->print_cr("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
-    gclog_or_tty->print_cr("cms_time_since_end=%3.7f", stats().cms_time_since_end());
-    gclog_or_tty->print_cr("metadata initialized %d",
-      MetaspaceGC::should_concurrent_collect());
+  LogHandle(gc) log;
+  if (log.is_trace() && stats().valid()) {
+    log.trace("CMSCollector shouldConcurrentCollect: ");
+    ResourceMark rm;
+    stats().print_on(log.debug_stream());
+    log.trace("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full());
+    log.trace("free=" SIZE_FORMAT, _cmsGen->free());
+    log.trace("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available());
+    log.trace("promotion_rate=%g", stats().promotion_rate());
+    log.trace("cms_allocation_rate=%g", stats().cms_allocation_rate());
+    log.trace("occupancy=%3.7f", _cmsGen->occupancy());
+    log.trace("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy());
+    log.trace("cms_time_since_begin=%3.7f", stats().cms_time_since_begin());
+    log.trace("cms_time_since_end=%3.7f", stats().cms_time_since_end());
+    log.trace("metadata initialized %d", MetaspaceGC::should_concurrent_collect());
   }
   // ------------------------------------------------------------------
 
@@ -1191,12 +1150,8 @@
       // this branch will not fire after the first successful CMS
       // collection because the stats should then be valid.
       if (_cmsGen->occupancy() >= _bootstrap_occupancy) {
-        if (Verbose && PrintGCDetails) {
-          gclog_or_tty->print_cr(
-            " CMSCollector: collect for bootstrapping statistics:"
-            " occupancy = %f, boot occupancy = %f", _cmsGen->occupancy(),
-            _bootstrap_occupancy);
-        }
+        log_trace(gc)(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f",
+                      _cmsGen->occupancy(), _bootstrap_occupancy);
         return true;
       }
     }
@@ -1208,9 +1163,7 @@
   // XXX We need to make sure that the gen expansion
   // criterion dovetails well with this. XXX NEED TO FIX THIS
   if (_cmsGen->should_concurrent_collect()) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print_cr("CMS old gen initiated");
-    }
+    log_trace(gc)("CMS old gen initiated");
     return true;
   }
 
@@ -1221,16 +1174,12 @@
   assert(gch->collector_policy()->is_generation_policy(),
          "You may want to check the correctness of the following");
   if (gch->incremental_collection_will_fail(true /* consult_young */)) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print("CMSCollector: collect because incremental collection will fail ");
-    }
+    log_trace(gc)("CMSCollector: collect because incremental collection will fail ");
     return true;
   }
 
   if (MetaspaceGC::should_concurrent_collect()) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print("CMSCollector: collect for metadata allocation ");
-    }
+    log_trace(gc)("CMSCollector: collect for metadata allocation ");
     return true;
   }
 
@@ -1244,13 +1193,11 @@
     // Check the CMS time since begin (we do not check the stats validity
     // as we want to be able to trigger the first CMS cycle as well)
     if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) {
-      if (Verbose && PrintGCDetails) {
-        if (stats().valid()) {
-          gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
-                                 stats().cms_time_since_begin());
-        } else {
-          gclog_or_tty->print_cr("CMSCollector: collect because of trigger interval (first collection)");
-        }
+      if (stats().valid()) {
+        log_trace(gc)("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)",
+                      stats().cms_time_since_begin());
+      } else {
+        log_trace(gc)("CMSCollector: collect because of trigger interval (first collection)");
       }
       return true;
     }
@@ -1293,20 +1240,15 @@
 
   assert_lock_strong(freelistLock());
   if (occupancy() > initiating_occupancy()) {
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print(" %s: collect because of occupancy %f / %f  ",
-        short_name(), occupancy(), initiating_occupancy());
-    }
+    log_trace(gc)(" %s: collect because of occupancy %f / %f  ",
+                  short_name(), occupancy(), initiating_occupancy());
     return true;
   }
   if (UseCMSInitiatingOccupancyOnly) {
     return false;
   }
   if (expansion_cause() == CMSExpansionCause::_satisfy_allocation) {
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print(" %s: collect because expanded for allocation ",
-        short_name());
-    }
+    log_trace(gc)(" %s: collect because expanded for allocation ", short_name());
     return true;
   }
   return false;
@@ -1363,13 +1305,9 @@
 
 void CMSCollector::report_concurrent_mode_interruption() {
   if (is_external_interruption()) {
-    if (PrintGCDetails) {
-      gclog_or_tty->print(" (concurrent mode interrupted)");
-    }
+    log_debug(gc)("Concurrent mode interrupted");
   } else {
-    if (PrintGCDetails) {
-      gclog_or_tty->print(" (concurrent mode failure)");
-    }
+    log_debug(gc)("Concurrent mode failure");
     _gc_tracer_cm->report_concurrent_mode_failure();
   }
 }
@@ -1503,11 +1441,9 @@
          "VM thread should have CMS token");
   getFreelistLocks();
   bitMapLock()->lock_without_safepoint_check();
-  if (TraceCMSState) {
-    gclog_or_tty->print_cr("CMS foreground collector has asked for control "
-      INTPTR_FORMAT " with first state %d", p2i(Thread::current()), first_state);
-    gclog_or_tty->print_cr("    gets control with state %d", _collectorState);
-  }
+  log_debug(gc, state)("CMS foreground collector has asked for control " INTPTR_FORMAT " with first state %d",
+                       p2i(Thread::current()), first_state);
+  log_debug(gc, state)("    gets control with state %d", _collectorState);
 
   // Inform cms gen if this was due to partial collection failing.
   // The CMS gen may use this fact to determine its expansion policy.
@@ -1581,7 +1517,7 @@
   SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
   gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
 
-  GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL);
+  GCTraceTime(Trace, gc) t("CMS:MSC");
 
   // Temporarily widen the span of the weak reference processing to
   // the entire heap.
@@ -1666,33 +1602,34 @@
 }
 
 void CMSCollector::print_eden_and_survivor_chunk_arrays() {
+  LogHandle(gc, heap) log;
+  if (!log.is_trace()) {
+    return;
+  }
+
   ContiguousSpace* eden_space = _young_gen->eden();
   ContiguousSpace* from_space = _young_gen->from();
   ContiguousSpace* to_space   = _young_gen->to();
   // Eden
   if (_eden_chunk_array != NULL) {
-    gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
-                           p2i(eden_space->bottom()), p2i(eden_space->top()),
-                           p2i(eden_space->end()), eden_space->capacity());
-    gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", "
-                           "_eden_chunk_capacity=" SIZE_FORMAT,
-                           _eden_chunk_index, _eden_chunk_capacity);
+    log.trace("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+              p2i(eden_space->bottom()), p2i(eden_space->top()),
+              p2i(eden_space->end()), eden_space->capacity());
+    log.trace("_eden_chunk_index=" SIZE_FORMAT ", _eden_chunk_capacity=" SIZE_FORMAT,
+              _eden_chunk_index, _eden_chunk_capacity);
     for (size_t i = 0; i < _eden_chunk_index; i++) {
-      gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
-                             i, p2i(_eden_chunk_array[i]));
+      log.trace("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, i, p2i(_eden_chunk_array[i]));
     }
   }
   // Survivor
   if (_survivor_chunk_array != NULL) {
-    gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
-                           p2i(from_space->bottom()), p2i(from_space->top()),
-                           p2i(from_space->end()), from_space->capacity());
-    gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", "
-                           "_survivor_chunk_capacity=" SIZE_FORMAT,
-                           _survivor_chunk_index, _survivor_chunk_capacity);
+    log.trace("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+              p2i(from_space->bottom()), p2i(from_space->top()),
+              p2i(from_space->end()), from_space->capacity());
+    log.trace("_survivor_chunk_index=" SIZE_FORMAT ", _survivor_chunk_capacity=" SIZE_FORMAT,
+              _survivor_chunk_index, _survivor_chunk_capacity);
     for (size_t i = 0; i < _survivor_chunk_index; i++) {
-      gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
-                             i, p2i(_survivor_chunk_array[i]));
+      log.trace("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, i, p2i(_survivor_chunk_array[i]));
     }
   }
 }
@@ -1781,11 +1718,7 @@
     _collection_count_start = gch->total_full_collections();
   }
 
-  // Used for PrintGC
-  size_t prev_used = 0;
-  if (PrintGC && Verbose) {
-    prev_used = _cmsGen->used();
-  }
+  size_t prev_used = _cmsGen->used();
 
   // The change of the collection state is normally done at this level;
   // the exceptions are phases that are executed while the world is
@@ -1796,10 +1729,8 @@
   // while the world is stopped because the foreground collector already
   // has the world stopped and would deadlock.
   while (_collectorState != Idling) {
-    if (TraceCMSState) {
-      gclog_or_tty->print_cr("Thread " INTPTR_FORMAT " in CMS state %d",
-        p2i(Thread::current()), _collectorState);
-    }
+    log_debug(gc, state)("Thread " INTPTR_FORMAT " in CMS state %d",
+                         p2i(Thread::current()), _collectorState);
     // The foreground collector
     //   holds the Heap_lock throughout its collection.
     //   holds the CMS token (but not the lock)
@@ -1829,11 +1760,8 @@
         // done this round.
         assert(_foregroundGCShouldWait == false, "We set it to false in "
                "waitForForegroundGC()");
-        if (TraceCMSState) {
-          gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
-            " exiting collection CMS state %d",
-            p2i(Thread::current()), _collectorState);
-        }
+        log_debug(gc, state)("CMS Thread " INTPTR_FORMAT " exiting collection CMS state %d",
+                             p2i(Thread::current()), _collectorState);
         return;
       } else {
         // The background collector can run but check to see if the
@@ -1937,10 +1865,8 @@
         ShouldNotReachHere();
         break;
     }
-    if (TraceCMSState) {
-      gclog_or_tty->print_cr("  Thread " INTPTR_FORMAT " done - next CMS state %d",
-        p2i(Thread::current()), _collectorState);
-    }
+    log_debug(gc, state)("  Thread " INTPTR_FORMAT " done - next CMS state %d",
+                         p2i(Thread::current()), _collectorState);
     assert(_foregroundGCShouldWait, "block post-condition");
   }
 
@@ -1959,14 +1885,10 @@
     assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
            "Possible deadlock");
   }
-  if (TraceCMSState) {
-    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
-      " exiting collection CMS state %d",
-      p2i(Thread::current()), _collectorState);
-  }
-  if (PrintGC && Verbose) {
-    _cmsGen->print_heap_change(prev_used);
-  }
+  log_debug(gc, state)("CMS Thread " INTPTR_FORMAT " exiting collection CMS state %d",
+                       p2i(Thread::current()), _collectorState);
+  log_info(gc, heap)("Old: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                     prev_used / K, _cmsGen->used()/K, _cmsGen->capacity() /K);
 }
 
 void CMSCollector::register_gc_start(GCCause::Cause cause) {
@@ -2018,10 +1940,8 @@
       ConcurrentMarkSweepThread::CMS_cms_wants_token);
     // Get a possibly blocked foreground thread going
     CGC_lock->notify();
-    if (TraceCMSState) {
-      gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
-        p2i(Thread::current()), _collectorState);
-    }
+    log_debug(gc, state)("CMS Thread " INTPTR_FORMAT " waiting at CMS state %d",
+                         p2i(Thread::current()), _collectorState);
     while (_foregroundGCIsActive) {
       CGC_lock->wait(Mutex::_no_safepoint_check_flag);
     }
@@ -2030,10 +1950,8 @@
     ConcurrentMarkSweepThread::clear_CMS_flag(
       ConcurrentMarkSweepThread::CMS_cms_wants_token);
   }
-  if (TraceCMSState) {
-    gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
-      p2i(Thread::current()), _collectorState);
-  }
+  log_debug(gc, state)("CMS Thread " INTPTR_FORMAT " continuing at CMS state %d",
+                       p2i(Thread::current()), _collectorState);
   return res;
 }
 
@@ -2130,11 +2048,8 @@
   NOT_PRODUCT(
     assert(_numObjectsPromoted == 0, "check");
     assert(_numWordsPromoted   == 0, "check");
-    if (Verbose && PrintGC) {
-      gclog_or_tty->print("Allocated " SIZE_FORMAT " objects, "
-                          SIZE_FORMAT " bytes concurrently",
-      _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
-    }
+    log_develop_trace(gc, alloc)("Allocated " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes concurrently",
+                                 _numObjectsAllocated, _numWordsAllocated*sizeof(HeapWord));
     _numObjectsAllocated = 0;
     _numWordsAllocated   = 0;
   )
@@ -2211,21 +2126,15 @@
   NOT_PRODUCT(
     assert(_numObjectsAllocated == 0, "check");
     assert(_numWordsAllocated == 0, "check");
-    if (Verbose && PrintGC) {
-      gclog_or_tty->print("Promoted " SIZE_FORMAT " objects, "
-                          SIZE_FORMAT " bytes",
-                 _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
-    }
+    log_develop_trace(gc, promotion)("Promoted " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
+                                     _numObjectsPromoted, _numWordsPromoted*sizeof(HeapWord));
     _numObjectsPromoted = 0;
     _numWordsPromoted   = 0;
   )
 
-  if (PrintGC && Verbose) {
-    // Call down the chain in contiguous_available needs the freelistLock
-    // so print this out before releasing the freeListLock.
-    gclog_or_tty->print(" Contiguous available " SIZE_FORMAT " bytes ",
-                        contiguous_available());
-  }
+  // Call down the chain in contiguous_available needs the freelistLock
+  // so print this out before releasing the freeListLock.
+  log_develop_trace(gc)(" Contiguous available " SIZE_FORMAT " bytes ", contiguous_available());
 }
 
 #ifndef PRODUCT
@@ -2309,8 +2218,10 @@
   bool do_bit(size_t offset) {
     HeapWord* addr = _marks->offsetToHeapWord(offset);
     if (!_marks->isMarked(addr)) {
-      oop(addr)->print_on(gclog_or_tty);
-      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
+      LogHandle(gc, verify) log;
+      ResourceMark rm;
+      oop(addr)->print_on(log.info_stream());
+      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       _failed = true;
     }
     return true;
@@ -2319,8 +2230,8 @@
   bool failed() { return _failed; }
 };
 
-bool CMSCollector::verify_after_remark(bool silent) {
-  if (!silent) gclog_or_tty->print(" [Verifying CMS Marking... ");
+bool CMSCollector::verify_after_remark() {
+  GCTraceTime(Info, gc, verify) tm("Verifying CMS Marking.");
   MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
   static bool init = false;
 
@@ -2383,7 +2294,6 @@
     warning("Unrecognized value " UINTX_FORMAT " for CMSRemarkVerifyVariant",
             CMSRemarkVerifyVariant);
   }
-  if (!silent) gclog_or_tty->print(" done] ");
   return true;
 }
 
@@ -2435,8 +2345,10 @@
   VerifyMarkedClosure vcl(markBitMap());
   verification_mark_bm()->iterate(&vcl);
   if (vcl.failed()) {
-    gclog_or_tty->print("Verification failed");
-    gch->print_on(gclog_or_tty);
+    LogHandle(gc, verify) log;
+    log.info("Verification failed");
+    ResourceMark rm;
+    gch->print_on(log.info_stream());
     fatal("CMS: failed marking verification after remark");
   }
 }
@@ -2729,10 +2641,7 @@
   // a new CMS cycle.
   if (success) {
     set_expansion_cause(cause);
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("Expanded CMS gen for %s",
-        CMSExpansionCause::to_string(cause));
-    }
+    log_trace(gc)("Expanded CMS gen for %s",  CMSExpansionCause::to_string(cause));
   }
 }
 
@@ -2800,9 +2709,7 @@
 void ConcurrentMarkSweepGeneration::shrink_free_list_by(size_t bytes) {
   assert_locked_or_safepoint(Heap_lock);
   assert_lock_strong(freelistLock());
-  if (PrintGCDetails && Verbose) {
-    warning("Shrinking of CMS not yet implemented");
-  }
+  log_trace(gc)("Shrinking of CMS not yet implemented");
   return;
 }
 
@@ -2812,63 +2719,35 @@
 class CMSPhaseAccounting: public StackObj {
  public:
   CMSPhaseAccounting(CMSCollector *collector,
-                     const char *phase,
-                     bool print_cr = true);
+                     const char *title);
   ~CMSPhaseAccounting();
 
  private:
   CMSCollector *_collector;
-  const char *_phase;
-  elapsedTimer _wallclock;
-  bool _print_cr;
+  const char *_title;
+  GCTraceConcTime(Info, gc) _trace_time;
 
  public:
   // Not MT-safe; so do not pass around these StackObj's
   // where they may be accessed by other threads.
   jlong wallclock_millis() {
-    assert(_wallclock.is_active(), "Wall clock should not stop");
-    _wallclock.stop();  // to record time
-    jlong ret = _wallclock.milliseconds();
-    _wallclock.start(); // restart
-    return ret;
+    return TimeHelper::counter_to_millis(os::elapsed_counter() - _trace_time.start_time());
   }
 };
 
 CMSPhaseAccounting::CMSPhaseAccounting(CMSCollector *collector,
-                                       const char *phase,
-                                       bool print_cr) :
-  _collector(collector), _phase(phase), _print_cr(print_cr) {
-
-  if (PrintCMSStatistics != 0) {
-    _collector->resetYields();
-  }
-  if (PrintGCDetails) {
-    gclog_or_tty->gclog_stamp();
-    gclog_or_tty->print_cr("[%s-concurrent-%s-start]",
-      _collector->cmsGen()->short_name(), _phase);
-  }
+                                       const char *title) :
+  _collector(collector), _title(title), _trace_time(title) {
+
+  _collector->resetYields();
   _collector->resetTimer();
-  _wallclock.start();
   _collector->startTimer();
 }
 
 CMSPhaseAccounting::~CMSPhaseAccounting() {
-  assert(_wallclock.is_active(), "Wall clock should not have stopped");
   _collector->stopTimer();
-  _wallclock.stop();
-  if (PrintGCDetails) {
-    gclog_or_tty->gclog_stamp();
-    gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
-                 _collector->cmsGen()->short_name(),
-                 _phase, _collector->timerValue(), _wallclock.seconds());
-    if (_print_cr) {
-      gclog_or_tty->cr();
-    }
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr(" (CMS-concurrent-%s yielded %d times)", _phase,
-                    _collector->yields());
-    }
-  }
+  log_debug(gc)("Concurrent active time: %.3fms", TimeHelper::counter_to_seconds(_collector->timerTicks()));
+  log_trace(gc)(" (CMS %s yielded %d times)", _title, _collector->yields());
 }
 
 // CMS work
@@ -2935,8 +2814,7 @@
   // CMS collection cycle.
   setup_cms_unloading_and_verification_state();
 
-  NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork",
-    PrintGCDetails && Verbose, true, _gc_timer_cm);)
+  GCTraceTime(Trace, gc) ts("checkpointRootsInitialWork", _gc_timer_cm);
 
   // Reset all the PLAB chunk arrays if necessary.
   if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
@@ -2967,9 +2845,7 @@
   // the klasses. The claimed marks need to be cleared before marking starts.
   ClassLoaderDataGraph::clear_claimed_marks();
 
-  if (CMSPrintEdenSurvivorChunks) {
-    print_eden_and_survivor_chunk_arrays();
-  }
+  print_eden_and_survivor_chunk_arrays();
 
   {
 #if defined(COMPILER2) || INCLUDE_JVMCI
@@ -3040,17 +2916,15 @@
   // weak ref discovery by the young generation collector.
 
   CMSTokenSyncWithLocks ts(true, bitMapLock());
-  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  CMSPhaseAccounting pa(this, "mark", !PrintGCDetails);
+  GCTraceCPUTime tcpu;
+  CMSPhaseAccounting pa(this, "Concrurrent Mark");
   bool res = markFromRootsWork();
   if (res) {
     _collectorState = Precleaning;
   } else { // We failed and a foreground collection wants to take over
     assert(_foregroundGCIsActive, "internal state inconsistency");
     assert(_restart_addr == NULL,  "foreground will restart from scratch");
-    if (PrintGCDetails) {
-      gclog_or_tty->print_cr("bailing out to foreground collection");
-    }
+    log_debug(gc)("bailing out to foreground collection");
   }
   verify_overflow_empty();
   return res;
@@ -3255,22 +3129,14 @@
   _timer.start();
   do_scan_and_mark(worker_id, _cms_space);
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-      // XXX: need xxx/xxx type of notation, two timers
-  }
+  log_trace(gc, task)("Finished cms space scanning in %dth thread: %3.3f sec", worker_id, _timer.seconds());
 
   // ... do work stealing
   _timer.reset();
   _timer.start();
   do_work_steal(worker_id);
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-      // XXX: need xxx/xxx type of notation, two timers
-  }
+  log_trace(gc, task)("Finished work stealing in %dth thread: %3.3f sec", worker_id, _timer.seconds());
   assert(_collector->_markStack.isEmpty(), "Should have been emptied");
   assert(work_queue(worker_id)->size() == 0, "Should have been emptied");
   // Note that under the current task protocol, the
@@ -3485,10 +3351,7 @@
       if (simulate_overflow ||
           !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
         // stack overflow
-        if (PrintCMSStatistics != 0) {
-          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
-                                 SIZE_FORMAT, _overflow_stack->capacity());
-        }
+        log_trace(gc)("CMS marking stack overflow (benign) at " SIZE_FORMAT, _overflow_stack->capacity());
         // We cannot assert that the overflow stack is full because
         // it may have been emptied since.
         assert(simulate_overflow ||
@@ -3573,9 +3436,7 @@
   _bit_map_lock->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // It is possible for whichever thread initiated the yield request
   // not to get a chance to wake up and take the bitmap lock between
@@ -3737,8 +3598,8 @@
     } else {
       _start_sampling = false;
     }
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "preclean", !PrintGCDetails);
+    GCTraceCPUTime tcpu;
+    CMSPhaseAccounting pa(this, "Concurrent Preclean");
     preclean_work(CMSPrecleanRefLists1, CMSPrecleanSurvivors1);
   }
   CMSTokenSync x(true); // is cms thread
@@ -3766,8 +3627,8 @@
   // CMSScheduleRemarkEdenSizeThreshold >= max eden size
   // we will never do an actual abortable preclean cycle.
   if (get_eden_used() > CMSScheduleRemarkEdenSizeThreshold) {
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "abortable-preclean", !PrintGCDetails);
+    GCTraceCPUTime tcpu;
+    CMSPhaseAccounting pa(this, "Concurrent Abortable Preclean");
     // We need more smarts in the abortable preclean
     // loop below to deal with cases where allocation
     // in young gen is very very slow, and our precleaning
@@ -3789,15 +3650,11 @@
       // been at it for too long.
       if ((CMSMaxAbortablePrecleanLoops != 0) &&
           loops >= CMSMaxAbortablePrecleanLoops) {
-        if (PrintGCDetails) {
-          gclog_or_tty->print(" CMS: abort preclean due to loops ");
-        }
+        log_debug(gc)(" CMS: abort preclean due to loops ");
         break;
       }
       if (pa.wallclock_millis() > CMSMaxAbortablePrecleanTime) {
-        if (PrintGCDetails) {
-          gclog_or_tty->print(" CMS: abort preclean due to time ");
-        }
+        log_debug(gc)(" CMS: abort preclean due to time ");
         break;
       }
       // If we are doing little work each iteration, we should
@@ -3810,10 +3667,8 @@
         waited++;
       }
     }
-    if (PrintCMSStatistics > 0) {
-      gclog_or_tty->print(" [" SIZE_FORMAT " iterations, " SIZE_FORMAT " waits, " SIZE_FORMAT " cards)] ",
-                          loops, waited, cumworkdone);
-    }
+    log_trace(gc)(" [" SIZE_FORMAT " iterations, " SIZE_FORMAT " waits, " SIZE_FORMAT " cards)] ",
+                               loops, waited, cumworkdone);
   }
   CMSTokenSync x(true); // is cms thread
   if (_collectorState != Idling) {
@@ -3957,9 +3812,7 @@
        numIter < CMSPrecleanIter;
        numIter++, lastNumCards = curNumCards, cumNumCards += curNumCards) {
     curNumCards  = preclean_mod_union_table(_cmsGen, &smoac_cl);
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print(" (modUnionTable: " SIZE_FORMAT " cards)", curNumCards);
-    }
+    log_trace(gc)(" (modUnionTable: " SIZE_FORMAT " cards)", curNumCards);
     // Either there are very few dirty cards, so re-mark
     // pause will be small anyway, or our pre-cleaning isn't
     // that much faster than the rate at which cards are being
@@ -3979,10 +3832,8 @@
 
   curNumCards = preclean_card_table(_cmsGen, &smoac_cl);
   cumNumCards += curNumCards;
-  if (PrintGCDetails && PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr(" (cardTable: " SIZE_FORMAT " cards, re-scanned " SIZE_FORMAT " cards, " SIZE_FORMAT " iterations)",
-                  curNumCards, cumNumCards, numIter);
-  }
+  log_trace(gc)(" (cardTable: " SIZE_FORMAT " cards, re-scanned " SIZE_FORMAT " cards, " SIZE_FORMAT " iterations)",
+                             curNumCards, cumNumCards, numIter);
   return cumNumCards;   // as a measure of useful work done
 }
 
@@ -4236,19 +4087,17 @@
   verify_work_stacks_empty();
   verify_overflow_empty();
 
-  if (PrintGCDetails) {
-    gclog_or_tty->print("[YG occupancy: " SIZE_FORMAT " K (" SIZE_FORMAT " K)]",
-                        _young_gen->used() / K,
-                        _young_gen->capacity() / K);
-  }
+  log_debug(gc)("YG occupancy: " SIZE_FORMAT " K (" SIZE_FORMAT " K)",
+                _young_gen->used() / K, _young_gen->capacity() / K);
   {
     if (CMSScavengeBeforeRemark) {
       GenCollectedHeap* gch = GenCollectedHeap::heap();
       // Temporarily set flag to false, GCH->do_collection will
       // expect it to be false and set to true
       FlagSetting fl(gch->_is_gc_active, false);
-      NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark",
-        PrintGCDetails && Verbose, true, _gc_timer_cm);)
+
+      GCTraceTime(Trace, gc) tm("Pause Scavenge Before Remark", _gc_timer_cm);
+
       gch->do_collection(true,                      // full (i.e. force, see below)
                          false,                     // !clear_all_soft_refs
                          0,                         // size
@@ -4266,7 +4115,7 @@
 }
 
 void CMSCollector::checkpointRootsFinalWork() {
-  NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);)
+  GCTraceTime(Trace, gc) tm("checkpointRootsFinalWork", _gc_timer_cm);
 
   assert(haveFreelistLocks(), "must have free list locks");
   assert_lock_strong(bitMapLock());
@@ -4298,9 +4147,7 @@
   // Update the saved marks which may affect the root scans.
   gch->save_marks();
 
-  if (CMSPrintEdenSurvivorChunks) {
-    print_eden_and_survivor_chunk_arrays();
-  }
+  print_eden_and_survivor_chunk_arrays();
 
   {
 #if defined(COMPILER2) || INCLUDE_JVMCI
@@ -4318,10 +4165,10 @@
     // the most recent young generation GC, minus those cleaned up by the
     // concurrent precleaning.
     if (CMSParallelRemarkEnabled) {
-      GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm);
+      GCTraceTime(Debug, gc) t("Rescan (parallel)", _gc_timer_cm);
       do_remark_parallel();
     } else {
-      GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false, _gc_timer_cm);
+      GCTraceTime(Debug, gc) t("Rescan (non-parallel)", _gc_timer_cm);
       do_remark_non_parallel();
     }
   }
@@ -4329,7 +4176,7 @@
   verify_overflow_empty();
 
   {
-    NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);)
+    GCTraceTime(Trace, gc) ts("refProcessingWork", _gc_timer_cm);
     refProcessingWork();
   }
   verify_work_stacks_empty();
@@ -4348,13 +4195,8 @@
   size_t ser_ovflw = _ser_pmc_remark_ovflw + _ser_pmc_preclean_ovflw +
                      _ser_kac_ovflw        + _ser_kac_preclean_ovflw;
   if (ser_ovflw > 0) {
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr("Marking stack overflow (benign) "
-        "(pmc_pc=" SIZE_FORMAT ", pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT
-        ", kac_preclean=" SIZE_FORMAT ")",
-        _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw,
-        _ser_kac_ovflw, _ser_kac_preclean_ovflw);
-    }
+    log_trace(gc)("Marking stack overflow (benign) (pmc_pc=" SIZE_FORMAT ", pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT ", kac_preclean=" SIZE_FORMAT ")",
+                         _ser_pmc_preclean_ovflw, _ser_pmc_remark_ovflw, _ser_kac_ovflw, _ser_kac_preclean_ovflw);
     _markStack.expand();
     _ser_pmc_remark_ovflw = 0;
     _ser_pmc_preclean_ovflw = 0;
@@ -4362,26 +4204,19 @@
     _ser_kac_ovflw = 0;
   }
   if (_par_pmc_remark_ovflw > 0 || _par_kac_ovflw > 0) {
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr("Work queue overflow (benign) "
-        "(pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT ")",
-        _par_pmc_remark_ovflw, _par_kac_ovflw);
-    }
-    _par_pmc_remark_ovflw = 0;
+     log_trace(gc)("Work queue overflow (benign) (pmc_rm=" SIZE_FORMAT ", kac=" SIZE_FORMAT ")",
+                          _par_pmc_remark_ovflw, _par_kac_ovflw);
+     _par_pmc_remark_ovflw = 0;
     _par_kac_ovflw = 0;
   }
-  if (PrintCMSStatistics != 0) {
-     if (_markStack._hit_limit > 0) {
-       gclog_or_tty->print_cr(" (benign) Hit max stack size limit (" SIZE_FORMAT ")",
-                              _markStack._hit_limit);
-     }
-     if (_markStack._failed_double > 0) {
-       gclog_or_tty->print_cr(" (benign) Failed stack doubling (" SIZE_FORMAT "),"
-                              " current capacity " SIZE_FORMAT,
-                              _markStack._failed_double,
-                              _markStack.capacity());
-     }
-  }
+   if (_markStack._hit_limit > 0) {
+     log_trace(gc)(" (benign) Hit max stack size limit (" SIZE_FORMAT ")",
+                          _markStack._hit_limit);
+   }
+   if (_markStack._failed_double > 0) {
+     log_trace(gc)(" (benign) Failed stack doubling (" SIZE_FORMAT "), current capacity " SIZE_FORMAT,
+                          _markStack._failed_double, _markStack.capacity());
+   }
   _markStack._hit_limit = 0;
   _markStack._failed_double = 0;
 
@@ -4415,11 +4250,7 @@
   {
     work_on_young_gen_roots(worker_id, &par_mri_cl);
     _timer.stop();
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr(
-        "Finished young gen initial mark scan work in %dth thread: %3.3f sec",
-        worker_id, _timer.seconds());
-    }
+    log_trace(gc, task)("Finished young gen initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
   }
 
   // ---------- remaining roots --------------
@@ -4440,11 +4271,7 @@
          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr(
-      "Finished remaining root initial mark scan work in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-  }
+  log_trace(gc, task)("Finished remaining root initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
 }
 
 // Parallel remark task
@@ -4557,11 +4384,7 @@
   {
     work_on_young_gen_roots(worker_id, &par_mrias_cl);
     _timer.stop();
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr(
-        "Finished young gen rescan work in %dth thread: %3.3f sec",
-        worker_id, _timer.seconds());
-    }
+    log_trace(gc, task)("Finished young gen rescan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
   }
 
   // ---------- remaining roots --------------
@@ -4580,11 +4403,7 @@
          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr(
-      "Finished remaining root rescan work in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-  }
+  log_trace(gc, task)("Finished remaining root rescan work in %dth thread: %3.3f sec",  worker_id, _timer.seconds());
 
   // ---------- unhandled CLD scanning ----------
   if (worker_id == 0) { // Single threaded at the moment.
@@ -4603,11 +4422,7 @@
     ClassLoaderDataGraph::remember_new_clds(false);
 
     _timer.stop();
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr(
-          "Finished unhandled CLD scanning work in %dth thread: %3.3f sec",
-          worker_id, _timer.seconds());
-    }
+    log_trace(gc, task)("Finished unhandled CLD scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
   }
 
   // ---------- dirty klass scanning ----------
@@ -4620,11 +4435,7 @@
     ClassLoaderDataGraph::classes_do(&remark_klass_closure);
 
     _timer.stop();
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print_cr(
-          "Finished dirty klass scanning work in %dth thread: %3.3f sec",
-          worker_id, _timer.seconds());
-    }
+    log_trace(gc, task)("Finished dirty klass scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
   }
 
   // We might have added oops to ClassLoaderData::_handles during the
@@ -4642,11 +4453,7 @@
   // "worker_id" is passed to select the task_queue for "worker_id"
   do_dirty_card_rescan_tasks(_cms_space, worker_id, &par_mrias_cl);
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr(
-      "Finished dirty card rescan work in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-  }
+  log_trace(gc, task)("Finished dirty card rescan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
 
   // ---------- steal work from other threads ...
   // ---------- ... and drain overflow list.
@@ -4654,11 +4461,7 @@
   _timer.start();
   do_work_steal(worker_id, &par_mrias_cl, _collector->hash_seed(worker_id));
   _timer.stop();
-  if (PrintCMSStatistics != 0) {
-    gclog_or_tty->print_cr(
-      "Finished work stealing in %dth thread: %3.3f sec",
-      worker_id, _timer.seconds());
-  }
+  log_trace(gc, task)("Finished work stealing in %dth thread: %3.3f sec", worker_id, _timer.seconds());
 }
 
 // Note that parameter "i" is not used.
@@ -4852,11 +4655,7 @@
         break;  // nirvana from the infinite cycle
     }
   }
-  NOT_PRODUCT(
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
-    }
-  )
+  log_develop_trace(gc, task)("\t(%d: stole %d oops)", i, num_steals);
   assert(work_q->size() == 0 && _collector->overflow_list_is_empty(),
          "Else our work is not yet done");
 }
@@ -4953,9 +4752,7 @@
   }
   // We are all done; record the size of the _survivor_chunk_array
   _survivor_chunk_index = i; // exclusive: [0, i)
-  if (PrintCMSStatistics > 0) {
-    gclog_or_tty->print(" (Survivor:" SIZE_FORMAT "chunks) ", i);
-  }
+  log_trace(gc, survivor)(" (Survivor:" SIZE_FORMAT "chunks) ", i);
   // Verify that we used up all the recorded entries
   #ifdef ASSERT
     size_t total = 0;
@@ -4967,10 +4764,8 @@
     // Check that the merged array is in sorted order
     if (total > 0) {
       for (size_t i = 0; i < total - 1; i++) {
-        if (PrintCMSStatistics > 0) {
-          gclog_or_tty->print(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
-                              i, p2i(_survivor_chunk_array[i]));
-        }
+        log_develop_trace(gc, survivor)(" (chunk" SIZE_FORMAT ":" INTPTR_FORMAT ") ",
+                                     i, p2i(_survivor_chunk_array[i]));
         assert(_survivor_chunk_array[i] < _survivor_chunk_array[i+1],
                "Not sorted");
       }
@@ -5104,7 +4899,7 @@
                               NULL,  // space is set further below
                               &_markBitMap, &_markStack, &mrias_cl);
   {
-    GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm);
+    GCTraceTime(Trace, gc) t("Grey Object Rescan", _gc_timer_cm);
     // Iterate over the dirty cards, setting the corresponding bits in the
     // mod union table.
     {
@@ -5129,10 +4924,7 @@
       _modUnionTable.dirty_range_iterate_clear(cms_span,
                                                &markFromDirtyCardsClosure);
       verify_work_stacks_empty();
-      if (PrintCMSStatistics != 0) {
-        gclog_or_tty->print(" (re-scanned " SIZE_FORMAT " dirty cards in cms gen) ",
-          markFromDirtyCardsClosure.num_dirty_cards());
-      }
+      log_trace(gc)(" (re-scanned " SIZE_FORMAT " dirty cards in cms gen) ", markFromDirtyCardsClosure.num_dirty_cards());
     }
   }
   if (VerifyDuringGC &&
@@ -5141,7 +4933,7 @@
     Universe::verify();
   }
   {
-    GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm);
+    GCTraceTime(Trace, gc) t("Root Rescan", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5163,7 +4955,7 @@
   }
 
   {
-    GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm);
+    GCTraceTime(Trace, gc) t("Visit Unhandled CLDs", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5182,7 +4974,7 @@
   }
 
   {
-    GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm);
+    GCTraceTime(Trace, gc) t("Dirty Klass Scan", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5344,11 +5136,7 @@
       break;  // nirvana from the infinite cycle
     }
   }
-  NOT_PRODUCT(
-    if (PrintCMSStatistics != 0) {
-      gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals);
-    }
-  )
+  log_develop_trace(gc, task)("\t(%d: stole %d oops)", i, num_steals);
 }
 
 void CMSRefProcTaskExecutor::execute(ProcessTask& task)
@@ -5390,7 +5178,7 @@
                                 _span, &_markBitMap, &_markStack,
                                 &cmsKeepAliveClosure, false /* !preclean */);
   {
-    GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm);
+    GCTraceTime(Debug, gc) t("Weak Refs Processing", _gc_timer_cm);
 
     ReferenceProcessorStats stats;
     if (rp->processing_is_mt()) {
@@ -5432,7 +5220,7 @@
 
   if (should_unload_classes()) {
     {
-      GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm);
+      GCTraceTime(Debug, gc) t("Class Unloading", _gc_timer_cm);
 
       // Unload classes and purge the SystemDictionary.
       bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
@@ -5445,13 +5233,13 @@
     }
 
     {
-      GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm);
+      GCTraceTime(Debug, gc) t("Scrub Symbol Table", _gc_timer_cm);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
 
     {
-      GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm);
+      GCTraceTime(Debug, gc) t("Scrub String Table", _gc_timer_cm);
       // Delete entries for dead interned strings.
       StringTable::unlink(&_is_alive_closure);
     }
@@ -5518,8 +5306,8 @@
   _intra_sweep_timer.reset();
   _intra_sweep_timer.start();
   {
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    CMSPhaseAccounting pa(this, "sweep", !PrintGCDetails);
+    GCTraceCPUTime tcpu;
+    CMSPhaseAccounting pa(this, "Concurrent Sweep");
     // First sweep the old gen
     {
       CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock(),
@@ -5602,13 +5390,8 @@
   size_t largestOffset     = pointer_delta(largestAddr, minAddr);
   size_t nearLargestOffset =
     (size_t)((double)largestOffset * nearLargestPercent) - MinChunkSize;
-  if (PrintFLSStatistics != 0) {
-    gclog_or_tty->print_cr(
-      "CMS: Large Block: " PTR_FORMAT ";"
-      " Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
-      p2i(largestAddr),
-      p2i(_cmsSpace->nearLargestChunk()), p2i(minAddr + nearLargestOffset));
-  }
+  log_debug(gc, freelist)("CMS: Large Block: " PTR_FORMAT "; Proximity: " PTR_FORMAT " -> " PTR_FORMAT,
+                          p2i(largestAddr), p2i(_cmsSpace->nearLargestChunk()), p2i(minAddr + nearLargestOffset));
   _cmsSpace->set_nearLargestChunk(minAddr + nearLargestOffset);
 }
 
@@ -5702,8 +5485,8 @@
 
   // Clear the mark bitmap (no grey objects to start with)
   // for the next cycle.
-  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  CMSPhaseAccounting cmspa(this, "reset", !PrintGCDetails);
+  GCTraceCPUTime tcpu;
+  CMSPhaseAccounting cmspa(this, "Concurrent Reset");
 
   HeapWord* curAddr = _markBitMap.startWord();
   while (curAddr < _markBitMap.endWord()) {
@@ -5719,9 +5502,7 @@
       bitMapLock()->unlock();
       ConcurrentMarkSweepThread::desynchronize(true);
       stopTimer();
-      if (PrintCMSStatistics != 0) {
-        incrementYields();
-      }
+      incrementYields();
 
       // See the comment in coordinator_yield()
       for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -5758,25 +5539,20 @@
 }
 
 void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
-  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
+  GCTraceCPUTime tcpu;
   TraceCollectorStats tcs(counters());
 
   switch (op) {
     case CMS_op_checkpointRootsInitial: {
+      GCTraceTime(Info, gc) t("Pause Initial Mark", NULL, GCCause::_no_gc, true);
       SvcGCMarker sgcm(SvcGCMarker::OTHER);
       checkpointRootsInitial();
-      if (PrintGC) {
-        _cmsGen->printOccupancy("initial-mark");
-      }
       break;
     }
     case CMS_op_checkpointRootsFinal: {
+      GCTraceTime(Info, gc) t("Pause Remark", NULL, GCCause::_no_gc, true);
       SvcGCMarker sgcm(SvcGCMarker::OTHER);
       checkpointRootsFinal();
-      if (PrintGC) {
-        _cmsGen->printOccupancy("remark");
-      }
       break;
     }
     default:
@@ -5989,9 +5765,9 @@
 void CMSMarkStack::expand() {
   assert(_capacity <= MarkStackSizeMax, "stack bigger than permitted");
   if (_capacity == MarkStackSizeMax) {
-    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
+    if (_hit_limit++ == 0 && !CMSConcurrentMTEnabled) {
       // We print a warning message only once per CMS cycle.
-      gclog_or_tty->print_cr(" (benign) Hit CMSMarkStack max size limit");
+      log_debug(gc)(" (benign) Hit CMSMarkStack max size limit");
     }
     return;
   }
@@ -6011,12 +5787,11 @@
     _base = (oop*)(_virtual_space.low());
     _index = 0;
     _capacity = new_capacity;
-  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled && PrintGCDetails) {
+  } else if (_failed_double++ == 0 && !CMSConcurrentMTEnabled) {
     // Failed to double capacity, continue;
     // we print a detail message only once per CMS cycle.
-    gclog_or_tty->print(" (benign) Failed to expand marking stack from " SIZE_FORMAT "K to "
-            SIZE_FORMAT "K",
-            _capacity / K, new_capacity / K);
+    log_debug(gc)(" (benign) Failed to expand marking stack from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                        _capacity / K, new_capacity / K);
   }
 }
 
@@ -6093,8 +5868,10 @@
   if (_span.contains(addr)) {
     _verification_bm->mark(addr);
     if (!_cms_bm->isMarked(addr)) {
-      oop(addr)->print();
-      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
+      LogHandle(gc, verify) log;
+      ResourceMark rm;
+      oop(addr)->print_on(log.info_stream());
+      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       fatal("... aborting");
     }
   }
@@ -6190,9 +5967,7 @@
   _freelistLock->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0;
@@ -6348,9 +6123,7 @@
   _freelistLock->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -6417,9 +6190,7 @@
   _bit_map->lock()->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -6572,9 +6343,7 @@
   _bitMap->lock()->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -6880,17 +6649,15 @@
     // Oop lies in _span and isn't yet grey or black
     _verification_bm->mark(addr);            // now grey
     if (!_cms_bm->isMarked(addr)) {
-      oop(addr)->print();
-      gclog_or_tty->print_cr(" (" INTPTR_FORMAT " should have been marked)",
-                             p2i(addr));
+      LogHandle(gc, verify) log;
+      ResourceMark rm;
+      oop(addr)->print_on(log.info_stream());
+      log.info(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
       fatal("... aborting");
     }
 
     if (!_mark_stack->push(obj)) { // stack overflow
-      if (PrintCMSStatistics != 0) {
-        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
-                               SIZE_FORMAT, _mark_stack->capacity());
-      }
+      log_trace(gc)("CMS marking stack overflow (benign) at " SIZE_FORMAT, _mark_stack->capacity());
       assert(_mark_stack->isFull(), "Else push should have succeeded");
       handle_stack_overflow(addr);
     }
@@ -6990,10 +6757,7 @@
         }
       )
       if (simulate_overflow || !_markStack->push(obj)) { // stack overflow
-        if (PrintCMSStatistics != 0) {
-          gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
-                                 SIZE_FORMAT, _markStack->capacity());
-        }
+        log_trace(gc)("CMS marking stack overflow (benign) at " SIZE_FORMAT, _markStack->capacity());
         assert(simulate_overflow || _markStack->isFull(), "Else push should have succeeded");
         handle_stack_overflow(addr);
       }
@@ -7042,10 +6806,7 @@
     if (simulate_overflow ||
         !(_work_queue->push(obj) || _overflow_stack->par_push(obj))) {
       // stack overflow
-      if (PrintCMSStatistics != 0) {
-        gclog_or_tty->print_cr("CMS marking stack overflow (benign) at "
-                               SIZE_FORMAT, _overflow_stack->capacity());
-      }
+      log_trace(gc)("CMS marking stack overflow (benign) at " SIZE_FORMAT, _overflow_stack->capacity());
       // We cannot assert that the overflow stack is full because
       // it may have been emptied since.
       assert(simulate_overflow ||
@@ -7207,9 +6968,7 @@
   ConcurrentMarkSweepThread::desynchronize(true);
 
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -7240,10 +6999,7 @@
   // However, that would be too strong in one case -- the last
   // partition ends at _unallocated_block which, in general, can be
   // an arbitrary boundary, not necessarily card aligned.
-  if (PrintCMSStatistics != 0) {
-    _num_dirty_cards +=
-         mr.word_size()/CardTableModRefBS::card_size_in_words;
-  }
+  _num_dirty_cards += mr.word_size()/CardTableModRefBS::card_size_in_words;
   _space->object_iterate_mem(mr, &_scan_cl);
 }
 
@@ -7276,10 +7032,8 @@
   )
   assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
          "sweep _limit out of bounds");
-  if (CMSTraceSweeper) {
-    gclog_or_tty->print_cr("\n====================\nStarting new sweep with limit " PTR_FORMAT,
-                        p2i(_limit));
-  }
+  log_develop_trace(gc, sweep)("====================");
+  log_develop_trace(gc, sweep)("Starting new sweep with limit " PTR_FORMAT, p2i(_limit));
 }
 
 void SweepClosure::print_on(outputStream* st) const {
@@ -7306,42 +7060,32 @@
     print();
     ShouldNotReachHere();
   }
-  if (Verbose && PrintGC) {
-    gclog_or_tty->print("Collected " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
-                        _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
-    gclog_or_tty->print_cr("\nLive " SIZE_FORMAT " objects,  "
-                           SIZE_FORMAT " bytes  "
-      "Already free " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
-      _numObjectsLive, _numWordsLive*sizeof(HeapWord),
-      _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
-    size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree)
-                        * sizeof(HeapWord);
-    gclog_or_tty->print_cr("Total sweep: " SIZE_FORMAT " bytes", totalBytes);
-
-    if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
-      size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
-      size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes();
-      size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes;
-      gclog_or_tty->print("Returned " SIZE_FORMAT " bytes", returned_bytes);
-      gclog_or_tty->print("   Indexed List Returned " SIZE_FORMAT " bytes",
-        indexListReturnedBytes);
-      gclog_or_tty->print_cr("        Dictionary Returned " SIZE_FORMAT " bytes",
-        dict_returned_bytes);
-    }
-  }
-  if (CMSTraceSweeper) {
-    gclog_or_tty->print_cr("end of sweep with _limit = " PTR_FORMAT "\n================",
-                           p2i(_limit));
-  }
+
+  if (log_is_enabled(Debug, gc, sweep)) {
+    log_debug(gc, sweep)("Collected " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
+                         _numObjectsFreed, _numWordsFreed*sizeof(HeapWord));
+    log_debug(gc, sweep)("Live " SIZE_FORMAT " objects,  " SIZE_FORMAT " bytes  Already free " SIZE_FORMAT " objects, " SIZE_FORMAT " bytes",
+                         _numObjectsLive, _numWordsLive*sizeof(HeapWord), _numObjectsAlreadyFree, _numWordsAlreadyFree*sizeof(HeapWord));
+    size_t totalBytes = (_numWordsFreed + _numWordsLive + _numWordsAlreadyFree) * sizeof(HeapWord);
+    log_debug(gc, sweep)("Total sweep: " SIZE_FORMAT " bytes", totalBytes);
+  }
+
+  if (log_is_enabled(Trace, gc, sweep) && CMSVerifyReturnedBytes) {
+    size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
+    size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes();
+    size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes;
+    log_trace(gc, sweep)("Returned " SIZE_FORMAT " bytes   Indexed List Returned " SIZE_FORMAT " bytes        Dictionary Returned " SIZE_FORMAT " bytes",
+                         returned_bytes, indexListReturnedBytes, dict_returned_bytes);
+  }
+  log_develop_trace(gc, sweep)("end of sweep with _limit = " PTR_FORMAT, p2i(_limit));
+  log_develop_trace(gc, sweep)("================");
 }
 #endif  // PRODUCT
 
 void SweepClosure::initialize_free_range(HeapWord* freeFinger,
     bool freeRangeInFreeLists) {
-  if (CMSTraceSweeper) {
-    gclog_or_tty->print("---- Start free range at " PTR_FORMAT " with free block (%d)\n",
-               p2i(freeFinger), freeRangeInFreeLists);
-  }
+  log_develop_trace(gc, sweep)("---- Start free range at " PTR_FORMAT " with free block (%d)",
+                               p2i(freeFinger), freeRangeInFreeLists);
   assert(!inFreeRange(), "Trampling existing free range");
   set_inFreeRange(true);
   set_lastFreeRangeCoalesced(false);
@@ -7407,13 +7151,9 @@
              "freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger()));
       flush_cur_free_chunk(freeFinger(),
                            pointer_delta(addr, freeFinger()));
-      if (CMSTraceSweeper) {
-        gclog_or_tty->print("Sweep: last chunk: ");
-        gclog_or_tty->print("put_free_blk " PTR_FORMAT " (" SIZE_FORMAT ") "
-                   "[coalesced:%d]\n",
-                   p2i(freeFinger()), pointer_delta(addr, freeFinger()),
-                   lastFreeRangeCoalesced() ? 1 : 0);
-      }
+      log_develop_trace(gc, sweep)("Sweep: last chunk: put_free_blk " PTR_FORMAT " (" SIZE_FORMAT ") [coalesced:%d]",
+                                   p2i(freeFinger()), pointer_delta(addr, freeFinger()),
+                                   lastFreeRangeCoalesced() ? 1 : 0);
     }
 
     // help the iterator loop finish
@@ -7624,9 +7364,7 @@
     assert(_sp->verify_chunk_in_free_list(fc), "free chunk is not in free lists");
   }
 
-  if (CMSTraceSweeper) {
-    gclog_or_tty->print_cr("  -- pick up another chunk at " PTR_FORMAT " (" SIZE_FORMAT ")", p2i(fc), chunkSize);
-  }
+  log_develop_trace(gc, sweep)("  -- pick up another chunk at " PTR_FORMAT " (" SIZE_FORMAT ")", p2i(fc), chunkSize);
 
   HeapWord* const fc_addr = (HeapWord*) fc;
 
@@ -7727,16 +7465,12 @@
          p2i(eob), p2i(eob-1), p2i(_limit), p2i(_sp->bottom()), p2i(_sp->end()), p2i(fc), chunk_size);
   if (eob >= _limit) {
     assert(eob == _limit || fc->is_free(), "Only a free chunk should allow us to cross over the limit");
-    if (CMSTraceSweeper) {
-      gclog_or_tty->print_cr("_limit " PTR_FORMAT " reached or crossed by block "
-                             "[" PTR_FORMAT "," PTR_FORMAT ") in space "
-                             "[" PTR_FORMAT "," PTR_FORMAT ")",
-                             p2i(_limit), p2i(fc), p2i(eob), p2i(_sp->bottom()), p2i(_sp->end()));
-    }
+    log_develop_trace(gc, sweep)("_limit " PTR_FORMAT " reached or crossed by block "
+                                 "[" PTR_FORMAT "," PTR_FORMAT ") in space "
+                                 "[" PTR_FORMAT "," PTR_FORMAT ")",
+                                 p2i(_limit), p2i(fc), p2i(eob), p2i(_sp->bottom()), p2i(_sp->end()));
     // Return the storage we are tracking back into the free lists.
-    if (CMSTraceSweeper) {
-      gclog_or_tty->print_cr("Flushing ... ");
-    }
+    log_develop_trace(gc, sweep)("Flushing ... ");
     assert(freeFinger() < eob, "Error");
     flush_cur_free_chunk( freeFinger(), pointer_delta(eob, freeFinger()));
   }
@@ -7753,10 +7487,7 @@
       assert(!_sp->verify_chunk_in_free_list(fc),
              "chunk should not be in free lists yet");
     }
-    if (CMSTraceSweeper) {
-      gclog_or_tty->print_cr(" -- add free block " PTR_FORMAT " (" SIZE_FORMAT ") to free lists",
-                    p2i(chunk), size);
-    }
+    log_develop_trace(gc, sweep)(" -- add free block " PTR_FORMAT " (" SIZE_FORMAT ") to free lists", p2i(chunk), size);
     // A new free range is going to be starting.  The current
     // free range has not been added to the free lists yet or
     // was removed so add it back.
@@ -7767,8 +7498,8 @@
     }
     _sp->addChunkAndRepairOffsetTable(chunk, size,
             lastFreeRangeCoalesced());
-  } else if (CMSTraceSweeper) {
-    gclog_or_tty->print_cr("Already in free list: nothing to flush");
+  } else {
+    log_develop_trace(gc, sweep)("Already in free list: nothing to flush");
   }
   set_inFreeRange(false);
   set_freeRangeInFreeLists(false);
@@ -7799,9 +7530,7 @@
   _freelistLock->unlock();
   ConcurrentMarkSweepThread::desynchronize(true);
   _collector->stopTimer();
-  if (PrintCMSStatistics != 0) {
-    _collector->incrementYields();
-  }
+  _collector->incrementYields();
 
   // See the comment in coordinator_yield()
   for (unsigned i = 0; i < CMSYieldSleepCount &&
@@ -7826,10 +7555,8 @@
 #endif
 
 void SweepClosure::print_free_block_coalesced(FreeChunk* fc) const {
-  if (CMSTraceSweeper) {
-    gclog_or_tty->print_cr("Sweep:coal_free_blk " PTR_FORMAT " (" SIZE_FORMAT ")",
-                           p2i(fc), fc->size());
-  }
+  log_develop_trace(gc, sweep)("Sweep:coal_free_blk " PTR_FORMAT " (" SIZE_FORMAT ")",
+                               p2i(fc), fc->size());
 }
 
 // CMSIsAliveClosure
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,6 +35,7 @@
 #include "gc/shared/generationCounters.hpp"
 #include "gc/shared/space.hpp"
 #include "gc/shared/taskqueue.hpp"
+#include "logging/log.hpp"
 #include "memory/freeBlockDictionary.hpp"
 #include "memory/iterator.hpp"
 #include "memory/virtualspace.hpp"
@@ -308,9 +309,8 @@
 
   void reset() {
     _index = 0;
-    if (_overflows > 0 && PrintCMSStatistics > 1) {
-      warning("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times",
-              _capacity, _overflows);
+    if (_overflows > 0) {
+      log_trace(gc)("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times", _capacity, _overflows);
     }
     _overflows = 0;
   }
@@ -451,7 +451,7 @@
 
   // Debugging.
   void print_on(outputStream* st) const PRODUCT_RETURN;
-  void print() const { print_on(gclog_or_tty); }
+  void print() const { print_on(tty); }
 };
 
 // A closure related to weak references processing which
@@ -935,7 +935,7 @@
   void    startTimer() { assert(!_timer.is_active(), "Error"); _timer.start();   }
   void    stopTimer()  { assert( _timer.is_active(), "Error"); _timer.stop();    }
   void    resetTimer() { assert(!_timer.is_active(), "Error"); _timer.reset();   }
-  double  timerValue() { assert(!_timer.is_active(), "Error"); return _timer.seconds(); }
+  jlong   timerTicks() { assert(!_timer.is_active(), "Error"); return _timer.ticks(); }
 
   int  yields()          { return _numYields; }
   void resetYields()     { _numYields = 0;    }
@@ -961,7 +961,7 @@
 
   // Debugging
   void verify();
-  bool verify_after_remark(bool silent = VerifySilently);
+  bool verify_after_remark();
   void verify_ok_to_terminate() const PRODUCT_RETURN;
   void verify_work_stacks_empty() const PRODUCT_RETURN;
   void verify_overflow_empty() const PRODUCT_RETURN;
@@ -1234,7 +1234,6 @@
   const char* name() const;
   virtual const char* short_name() const { return "CMS"; }
   void        print() const;
-  void printOccupancy(const char* s);
 
   // Resize the generation after a compacting GC.  The
   // generation can be treated as a contiguous space
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -34,7 +34,7 @@
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/generation.hpp"
@@ -45,6 +45,7 @@
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -270,9 +271,9 @@
 }
 
 void ParScanThreadState::print_promotion_failure_size() {
-  if (_promotion_failed_info.has_failed() && PrintPromotionFailure) {
-    gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
-                        _thread_num, _promotion_failed_info.first_size());
+  if (_promotion_failed_info.has_failed()) {
+    log_trace(gc, promotion)(" (%d: promotion failure size = " SIZE_FORMAT ") ",
+                             _thread_num, _promotion_failed_info.first_size());
   }
 }
 
@@ -298,11 +299,11 @@
 
   #if TASKQUEUE_STATS
   static void
-    print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
-  void print_termination_stats(outputStream* const st = gclog_or_tty);
+    print_termination_stats_hdr(outputStream* const st);
+  void print_termination_stats();
   static void
-    print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
-  void print_taskqueue_stats(outputStream* const st = gclog_or_tty);
+    print_taskqueue_stats_hdr(outputStream* const st);
+  void print_taskqueue_stats();
   void reset_stats();
   #endif // TASKQUEUE_STATS
 
@@ -383,7 +384,15 @@
   st->print_raw_cr("--- --------- --------- ------ --------- ------ --------");
 }
 
-void ParScanThreadStateSet::print_termination_stats(outputStream* const st) {
+void ParScanThreadStateSet::print_termination_stats() {
+  LogHandle(gc, task, stats) log;
+  if (!log.is_debug()) {
+    return;
+  }
+
+  ResourceMark rm;
+  outputStream* st = log.debug_stream();
+
   print_termination_stats_hdr(st);
 
   for (int i = 0; i < length(); ++i) {
@@ -404,7 +413,13 @@
   st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
 }
 
-void ParScanThreadStateSet::print_taskqueue_stats(outputStream* const st) {
+void ParScanThreadStateSet::print_taskqueue_stats() {
+  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+    return;
+  }
+  LogHandle(gc, task, stats) log;
+  ResourceMark rm;
+  outputStream* st = log.trace_stream();
   print_taskqueue_stats_hdr(st);
 
   TaskQueueStats totals;
@@ -823,9 +838,7 @@
   _promo_failure_scan_stack.clear(true); // Clear cached segments.
 
   remove_forwarding_pointers();
-  if (PrintGCDetails) {
-    gclog_or_tty->print(" (promotion failed)");
-  }
+  log_info(gc, promotion)("Promotion failed");
   // All the spaces are in play for mark-sweep.
   swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
   from()->set_next_compaction_space(to());
@@ -882,9 +895,7 @@
     size_policy->minor_collection_begin();
   }
 
-  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
-  // Capture heap used before collection (for printing).
-  size_t gch_prev_used = gch->used();
+  GCTraceTime(Trace, gc) t1("ParNew", NULL, gch->gc_cause());
 
   age_table()->clear();
   to()->clear(SpaceDecorator::Mangle);
@@ -990,12 +1001,8 @@
     plab_stats()->adjust_desired_plab_sz();
   }
 
-  if (PrintGC && !PrintGCDetails) {
-    gch->print_heap_change(gch_prev_used);
-  }
-
-  TASKQUEUE_STATS_ONLY(if (PrintTerminationStats) thread_state_set.print_termination_stats());
-  TASKQUEUE_STATS_ONLY(if (PrintTaskqueue) thread_state_set.print_taskqueue_stats());
+  TASKQUEUE_STATS_ONLY(thread_state_set.print_termination_stats());
+  TASKQUEUE_STATS_ONLY(thread_state_set.print_taskqueue_stats());
 
   if (UseAdaptiveSizePolicy) {
     size_policy->minor_collection_end(gch->gc_cause());
@@ -1150,11 +1157,9 @@
 
   // This code must come after the CAS test, or it will print incorrect
   // information.
-  if (TraceScavenge) {
-    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-       is_in_reserved(new_obj) ? "copying" : "tenuring",
-       new_obj->klass()->internal_name(), p2i(old), p2i(new_obj), new_obj->size());
-  }
+  log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
+                                  is_in_reserved(new_obj) ? "copying" : "tenuring",
+                                  new_obj->klass()->internal_name(), p2i(old), p2i(new_obj), new_obj->size());
 
   if (forward_ptr == NULL) {
     oop obj_to_push = new_obj;
@@ -1176,9 +1181,7 @@
     )
     if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
       // Add stats for overflow pushes.
-      if (Verbose && PrintGCDetails) {
-        gclog_or_tty->print("queue overflow!\n");
-      }
+      log_develop_trace(gc)("Queue Overflow");
       push_on_overflow_list(old, par_scan_state);
       TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
     }
--- a/hotspot/src/share/vm/gc/cms/parOopClosures.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/parOopClosures.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/shared/cardTableRS.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
+#include "logging/log.hpp"
 
 template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
   assert (!oopDesc::is_null(*p), "null weak reference?");
@@ -108,11 +109,9 @@
       if (m->is_marked()) { // Contains forwarding pointer.
         new_obj = ParNewGeneration::real_forwardee(obj);
         oopDesc::encode_store_heap_oop_not_null(p, new_obj);
-        if (TraceScavenge) {
-          gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-             "forwarded ",
-             new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size());
-        }
+        log_develop_trace(gc, scavenge)("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
+                                        "forwarded ",
+                                        new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size());
       } else {
         size_t obj_sz = obj->size_given_klass(objK);
         new_obj = _g->copy_to_survivor_space(_par_scan_state, obj, obj_sz, m);
--- a/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -132,7 +132,7 @@
   }
 
   void print_on(outputStream* st) const;
-  void print() const { print_on(gclog_or_tty); }
+  void print() const { print_on(tty); }
 };
 
 class PromotionInfo VALUE_OBJ_CLASS_SPEC {
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,7 +28,7 @@
 #include "gc/cms/vmCMSOperations.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/os.hpp"
@@ -58,7 +58,7 @@
 void VM_CMS_Operation::verify_before_gc() {
   if (VerifyBeforeGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm);
+    GCTraceTime(Info, gc, verify) tm("Verify Before", _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -70,7 +70,7 @@
 void VM_CMS_Operation::verify_after_gc() {
   if (VerifyAfterGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm);
+    GCTraceTime(Info, gc, verify) tm("Verify After", _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,7 +26,6 @@
 #include "gc/g1/collectionSetChooser.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
-#include "gc/g1/g1ErgoVerbose.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 
@@ -136,8 +135,8 @@
     assert(regions_at(i) != NULL, "Should be true by sorting!");
   }
 #endif // ASSERT
-  if (G1PrintRegionLivenessInfo) {
-    G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
+  if (log_is_enabled(Trace, gc, liveness)) {
+    G1PrintRegionLivenessInfoClosure cl("Post-Sorting");
     for (uint i = 0; i < _end; ++i) {
       HeapRegion* r = regions_at(i);
       cl.doHeapRegion(r);
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -88,11 +89,8 @@
 void ConcurrentG1RefineThread::activate() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   if (!is_primary()) {
-    if (G1TraceConcRefinement) {
-      DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-      gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
-                             _worker_id, _threshold, (int)dcqs.completed_buffers_num());
-    }
+    log_debug(gc, refine)("G1-Refine-activated worker %d, on threshold %d, current %d",
+                          _worker_id, _threshold, JavaThread::dirty_card_queue_set().completed_buffers_num());
     set_active(true);
   } else {
     DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@@ -104,11 +102,8 @@
 void ConcurrentG1RefineThread::deactivate() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   if (!is_primary()) {
-    if (G1TraceConcRefinement) {
-      DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-      gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
-                             _worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
-    }
+    log_debug(gc, refine)("G1-Refine-deactivated worker %d, off threshold %d, current %d",
+                          _worker_id, _deactivation_threshold, JavaThread::dirty_card_queue_set().completed_buffers_num());
     set_active(false);
   } else {
     DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@@ -174,9 +169,7 @@
     }
   }
 
-  if (G1TraceConcRefinement) {
-    gclog_or_tty->print_cr("G1-Refine-stop");
-  }
+  log_debug(gc, refine)("G1-Refine-stop");
 }
 
 void ConcurrentG1RefineThread::stop() {
@@ -199,4 +192,4 @@
 void ConcurrentG1RefineThread::stop_service() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   _monitor->notify();
-}
\ No newline at end of file
+}
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,8 +31,6 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
-#include "gc/g1/g1ErgoVerbose.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1StringDedup.hpp"
@@ -44,12 +42,13 @@
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/vmGCOperations.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
@@ -232,9 +231,7 @@
   // Clear expansion flag
   _should_expand = false;
   if (_capacity == (jint) MarkStackSizeMax) {
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr(" (benign) Can't expand marking stack capacity, at max size limit");
-    }
+    log_trace(gc)("(benign) Can't expand marking stack capacity, at max size limit");
     return;
   }
   // Double capacity if possible
@@ -254,12 +251,9 @@
     _index = 0;
     _capacity = new_capacity;
   } else {
-    if (PrintGCDetails && Verbose) {
-      // Failed to double capacity, continue;
-      gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from "
-                          SIZE_FORMAT "K to " SIZE_FORMAT "K",
-                          _capacity / K, new_capacity / K);
-    }
+    // Failed to double capacity, continue;
+    log_trace(gc)("(benign) Failed to expand marking stack capacity from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                  _capacity / K, new_capacity / K);
   }
 }
 
@@ -848,10 +842,7 @@
       // marking.
       reset_marking_state(true /* clear_overflow */);
 
-      if (G1Log::fine()) {
-        gclog_or_tty->gclog_stamp();
-        gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
-      }
+      log_info(gc)("Concurrent Mark reset for overflow");
     }
   }
 
@@ -987,8 +978,6 @@
 };
 
 void ConcurrentMark::scanRootRegions() {
-  double scan_start = os::elapsedTime();
-
   // Start of concurrent marking.
   ClassLoaderDataGraph::clear_claimed_marks();
 
@@ -996,10 +985,7 @@
   // 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()) {
-    if (G1Log::fine()) {
-      gclog_or_tty->gclog_stamp();
-      gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
-    }
+    GCTraceConcTime(Info, gc) tt("Concurrent Root Region Scan");
 
     _parallel_marking_threads = calc_parallel_marking_threads();
     assert(parallel_marking_threads() <= max_parallel_marking_threads(),
@@ -1010,11 +996,6 @@
     _parallel_workers->set_active_workers(active_workers);
     _parallel_workers->run_task(&task);
 
-    if (G1Log::fine()) {
-      gclog_or_tty->gclog_stamp();
-      gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]", os::elapsedTime() - scan_start);
-    }
-
     // It's possible that has_aborted() is true here without actually
     // aborting the survivor scan earlier. This is OK as it's
     // mainly used for sanity checking.
@@ -1049,22 +1030,6 @@
   print_stats();
 }
 
-// Helper class to get rid of some boilerplate code.
-class G1CMTraceTime : public StackObj {
-  GCTraceTimeImpl _gc_trace_time;
-  static bool doit_and_prepend(bool doit) {
-    if (doit) {
-      gclog_or_tty->put(' ');
-    }
-    return doit;
-  }
-
- public:
-  G1CMTraceTime(const char* title, bool doit)
-    : _gc_trace_time(title, doit_and_prepend(doit), false, G1CollectedHeap::heap()->gc_timer_cm()) {
-  }
-};
-
 void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
   // world is stopped at this checkpoint
   assert(SafepointSynchronize::is_at_safepoint(),
@@ -1083,8 +1048,7 @@
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking,
-                     " VerifyDuringGC:(before)");
+    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
   g1h->check_bitmaps("Remark Start");
 
@@ -1102,16 +1066,13 @@
   if (has_overflown()) {
     // Oops.  We overflowed.  Restart concurrent marking.
     _restart_for_overflow = true;
-    if (G1TraceMarkStackOverflow) {
-      gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
-    }
+    log_develop_trace(gc)("Remark led to restart for overflow.");
 
     // Verify the heap w.r.t. the previous marking bitmap.
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
       g1h->prepare_for_verify();
-      Universe::verify(VerifyOption_G1UsePrevMarking,
-                       " VerifyDuringGC:(overflow)");
+      Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (overflow)");
     }
 
     // Clear the marking state because we will be restarting
@@ -1119,7 +1080,7 @@
     reset_marking_state();
   } else {
     {
-      G1CMTraceTime trace("GC aggregate-data", G1Log::finer());
+      GCTraceTime(Debug, gc) trace("GC Aggregate Data", g1h->gc_timer_cm());
 
       // Aggregate the per-task counting data that we have accumulated
       // while marking.
@@ -1136,8 +1097,7 @@
     if (VerifyDuringGC) {
       HandleMark hm;  // handle scope
       g1h->prepare_for_verify();
-      Universe::verify(VerifyOption_G1UseNextMarking,
-                       " VerifyDuringGC:(after)");
+      Universe::verify(VerifyOption_G1UseNextMarking, "During GC (after)");
     }
     g1h->check_bitmaps("Remark End");
     assert(!restart_for_overflow(), "sanity");
@@ -1523,8 +1483,8 @@
   G1CollectedHeap* _g1;
   size_t _freed_bytes;
   FreeRegionList* _local_cleanup_list;
-  HeapRegionSetCount _old_regions_removed;
-  HeapRegionSetCount _humongous_regions_removed;
+  uint _old_regions_removed;
+  uint _humongous_regions_removed;
   HRRSCleanupTask* _hrrs_cleanup_task;
 
 public:
@@ -1534,13 +1494,13 @@
     _g1(g1),
     _freed_bytes(0),
     _local_cleanup_list(local_cleanup_list),
-    _old_regions_removed(),
-    _humongous_regions_removed(),
+    _old_regions_removed(0),
+    _humongous_regions_removed(0),
     _hrrs_cleanup_task(hrrs_cleanup_task) { }
 
   size_t freed_bytes() { return _freed_bytes; }
-  const HeapRegionSetCount& old_regions_removed() { return _old_regions_removed; }
-  const HeapRegionSetCount& humongous_regions_removed() { return _humongous_regions_removed; }
+  const uint old_regions_removed() { return _old_regions_removed; }
+  const uint humongous_regions_removed() { return _humongous_regions_removed; }
 
   bool doHeapRegion(HeapRegion *hr) {
     if (hr->is_archive()) {
@@ -1555,10 +1515,10 @@
       _freed_bytes += hr->used();
       hr->set_containing_set(NULL);
       if (hr->is_humongous()) {
-        _humongous_regions_removed.increment(1u, hr->capacity());
+        _humongous_regions_removed++;
         _g1->free_humongous_region(hr, _local_cleanup_list, true);
       } else {
-        _old_regions_removed.increment(1u, hr->capacity());
+        _old_regions_removed++;
         _g1->free_region(hr, _local_cleanup_list, true);
       }
     } else {
@@ -1656,8 +1616,7 @@
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking,
-                     " VerifyDuringGC:(before)");
+    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
   }
   g1h->check_bitmaps("Cleanup Start");
 
@@ -1699,8 +1658,8 @@
   double this_final_counting_time = (count_end - start);
   _total_counting_time += this_final_counting_time;
 
-  if (G1PrintRegionLivenessInfo) {
-    G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Marking");
+  if (log_is_enabled(Trace, gc, liveness)) {
+    G1PrintRegionLivenessInfoClosure cl("Post-Marking");
     _g1h->heap_region_iterate(&cl);
   }
 
@@ -1743,10 +1702,6 @@
   double end = os::elapsedTime();
   _cleanup_times.add((end - start) * 1000.0);
 
-  if (G1Log::fine()) {
-    g1h->g1_policy()->print_heap_transition(start_used_bytes);
-  }
-
   // Clean up will have freed any regions completely full of garbage.
   // Update the soft reference policy with the new heap occupancy.
   Universe::update_heap_info_at_gc();
@@ -1754,8 +1709,7 @@
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
     g1h->prepare_for_verify();
-    Universe::verify(VerifyOption_G1UsePrevMarking,
-                     " VerifyDuringGC:(after)");
+    Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (after)");
   }
 
   g1h->check_bitmaps("Cleanup End");
@@ -1788,11 +1742,9 @@
   _cleanup_list.verify_optional();
   FreeRegionList tmp_free_list("Tmp Free List");
 
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
-                           "cleanup list has %u entries",
-                           _cleanup_list.length());
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [complete cleanup] : "
+                                  "cleanup list has %u entries",
+                                  _cleanup_list.length());
 
   // No one else should be accessing the _cleanup_list at this point,
   // so it is not necessary to take any locks
@@ -1810,13 +1762,11 @@
     // region from the _cleanup_list).
     if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
         _cleanup_list.is_empty()) {
-      if (G1ConcRegionFreeingVerbose) {
-        gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
-                               "appending %u entries to the secondary_free_list, "
-                               "cleanup list still has %u entries",
-                               tmp_free_list.length(),
-                               _cleanup_list.length());
-      }
+      log_develop_trace(gc, freelist)("G1ConcRegionFreeing [complete cleanup] : "
+                                      "appending %u entries to the secondary_free_list, "
+                                      "cleanup list still has %u entries",
+                                      tmp_free_list.length(),
+                                      _cleanup_list.length());
 
       {
         MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
@@ -2073,7 +2023,7 @@
   // Inner scope to exclude the cleaning of the string and symbol
   // tables from the displayed time.
   {
-    G1CMTraceTime t("GC ref-proc", G1Log::finer());
+    GCTraceTime(Debug, gc) trace("GC Ref Proc", g1h->gc_timer_cm());
 
     ReferenceProcessor* rp = g1h->ref_processor_cm();
 
@@ -2163,24 +2113,24 @@
 
   // Unload Klasses, String, Symbols, Code Cache, etc.
   {
-    G1CMTraceTime trace("Unloading", G1Log::finer());
+    GCTraceTime(Debug, gc) trace("Unloading", g1h->gc_timer_cm());
 
     if (ClassUnloadingWithConcurrentMark) {
       bool purged_classes;
 
       {
-        G1CMTraceTime trace("System Dictionary Unloading", G1Log::finest());
+        GCTraceTime(Trace, gc) trace("System Dictionary Unloading", g1h->gc_timer_cm());
         purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */);
       }
 
       {
-        G1CMTraceTime trace("Parallel Unloading", G1Log::finest());
+        GCTraceTime(Trace, gc) trace("Parallel Unloading", g1h->gc_timer_cm());
         weakRefsWorkParallelPart(&g1_is_alive, purged_classes);
       }
     }
 
     if (G1StringDedup::is_enabled()) {
-      G1CMTraceTime trace("String Deduplication Unlink", G1Log::finest());
+      GCTraceTime(Trace, gc) trace("String Deduplication Unlink", g1h->gc_timer_cm());
       G1StringDedup::unlink(&g1_is_alive);
     }
   }
@@ -2301,7 +2251,7 @@
   HandleMark   hm;
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-  G1CMTraceTime trace("Finalize Marking", G1Log::finer());
+  GCTraceTime(Debug, gc) trace("Finalize Marking", g1h->gc_timer_cm());
 
   g1h->ensure_parsability(false);
 
@@ -2614,12 +2564,13 @@
 }
 
 void ConcurrentMark::print_stats() {
-  if (G1MarkingVerboseLevel > 0) {
-    gclog_or_tty->print_cr("---------------------------------------------------------------------");
-    for (size_t i = 0; i < _active_tasks; ++i) {
-      _tasks[i]->print_stats();
-      gclog_or_tty->print_cr("---------------------------------------------------------------------");
-    }
+  if (!log_is_enabled(Debug, gc, stats)) {
+    return;
+  }
+  log_debug(gc, stats)("---------------------------------------------------------------------");
+  for (size_t i = 0; i < _active_tasks; ++i) {
+    _tasks[i]->print_stats();
+    log_debug(gc, stats)("---------------------------------------------------------------------");
   }
 }
 
@@ -2663,16 +2614,21 @@
 
 static void print_ms_time_info(const char* prefix, const char* name,
                                NumberSeq& ns) {
-  gclog_or_tty->print_cr("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).",
+  log_trace(gc, marking)("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).",
                          prefix, ns.num(), name, ns.sum()/1000.0, ns.avg());
   if (ns.num() > 0) {
-    gclog_or_tty->print_cr("%s         [std. dev = %8.2f ms, max = %8.2f ms]",
+    log_trace(gc, marking)("%s         [std. dev = %8.2f ms, max = %8.2f ms]",
                            prefix, ns.sd(), ns.maximum());
   }
 }
 
 void ConcurrentMark::print_summary_info() {
-  gclog_or_tty->print_cr(" Concurrent marking:");
+  LogHandle(gc, marking) log;
+  if (!log.is_trace()) {
+    return;
+  }
+
+  log.trace(" Concurrent marking:");
   print_ms_time_info("  ", "init marks", _init_times);
   print_ms_time_info("  ", "remarks", _remark_times);
   {
@@ -2681,25 +2637,16 @@
 
   }
   print_ms_time_info("  ", "cleanups", _cleanup_times);
-  gclog_or_tty->print_cr("    Final counting total time = %8.2f s (avg = %8.2f ms).",
-                         _total_counting_time,
-                         (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 /
-                          (double)_cleanup_times.num()
-                         : 0.0));
+  log.trace("    Final counting total time = %8.2f s (avg = %8.2f ms).",
+            _total_counting_time, (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
   if (G1ScrubRemSets) {
-    gclog_or_tty->print_cr("    RS scrub total time = %8.2f s (avg = %8.2f ms).",
-                           _total_rs_scrub_time,
-                           (_cleanup_times.num() > 0 ? _total_rs_scrub_time * 1000.0 /
-                            (double)_cleanup_times.num()
-                           : 0.0));
+    log.trace("    RS scrub total time = %8.2f s (avg = %8.2f ms).",
+              _total_rs_scrub_time, (_cleanup_times.num() > 0 ? _total_rs_scrub_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
   }
-  gclog_or_tty->print_cr("  Total stop_world time = %8.2f s.",
-                         (_init_times.sum() + _remark_times.sum() +
-                          _cleanup_times.sum())/1000.0);
-  gclog_or_tty->print_cr("  Total concurrent time = %8.2f s "
-                "(%8.2f s marking).",
-                cmThread()->vtime_accum(),
-                cmThread()->vtime_mark_accum());
+  log.trace("  Total stop_world time = %8.2f s.",
+            (_init_times.sum() + _remark_times.sum() + _cleanup_times.sum())/1000.0);
+  log.trace("  Total concurrent time = %8.2f s (%8.2f s marking).",
+            cmThread()->vtime_accum(), cmThread()->vtime_mark_accum());
 }
 
 void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
@@ -3079,15 +3026,15 @@
 }
 
 void CMTask::print_stats() {
-  gclog_or_tty->print_cr("Marking Stats, task = %u, calls = %d",
-                         _worker_id, _calls);
-  gclog_or_tty->print_cr("  Elapsed time = %1.2lfms, Termination time = %1.2lfms",
-                         _elapsed_time_ms, _termination_time_ms);
-  gclog_or_tty->print_cr("  Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms",
-                         _step_times_ms.num(), _step_times_ms.avg(),
-                         _step_times_ms.sd());
-  gclog_or_tty->print_cr("                    max = %1.2lfms, total = %1.2lfms",
-                         _step_times_ms.maximum(), _step_times_ms.sum());
+  log_debug(gc, stats)("Marking Stats, task = %u, calls = %d",
+                       _worker_id, _calls);
+  log_debug(gc, stats)("  Elapsed time = %1.2lfms, Termination time = %1.2lfms",
+                       _elapsed_time_ms, _termination_time_ms);
+  log_debug(gc, stats)("  Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms",
+                       _step_times_ms.num(), _step_times_ms.avg(),
+                       _step_times_ms.sd());
+  log_debug(gc, stats)("                    max = %1.2lfms, total = %1.2lfms",
+                       _step_times_ms.maximum(), _step_times_ms.sum());
 }
 
 bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) {
@@ -3587,9 +3534,8 @@
 #define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%"
 
 G1PrintRegionLivenessInfoClosure::
-G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
-  : _out(out),
-    _total_used_bytes(0), _total_capacity_bytes(0),
+G1PrintRegionLivenessInfoClosure(const char* phase_name)
+  : _total_used_bytes(0), _total_capacity_bytes(0),
     _total_prev_live_bytes(0), _total_next_live_bytes(0),
     _hum_used_bytes(0), _hum_capacity_bytes(0),
     _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
@@ -3599,38 +3545,37 @@
   double now = os::elapsedTime();
 
   // Print the header of the output.
-  _out->cr();
-  _out->print_cr(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now);
-  _out->print_cr(G1PPRL_LINE_PREFIX" HEAP"
-                 G1PPRL_SUM_ADDR_FORMAT("reserved")
-                 G1PPRL_SUM_BYTE_FORMAT("region-size"),
-                 p2i(g1_reserved.start()), p2i(g1_reserved.end()),
-                 HeapRegion::GrainBytes);
-  _out->print_cr(G1PPRL_LINE_PREFIX);
-  _out->print_cr(G1PPRL_LINE_PREFIX
-                G1PPRL_TYPE_H_FORMAT
-                G1PPRL_ADDR_BASE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_DOUBLE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT,
-                "type", "address-range",
-                "used", "prev-live", "next-live", "gc-eff",
-                "remset", "code-roots");
-  _out->print_cr(G1PPRL_LINE_PREFIX
-                G1PPRL_TYPE_H_FORMAT
-                G1PPRL_ADDR_BASE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_DOUBLE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT
-                G1PPRL_BYTE_H_FORMAT,
-                "", "",
-                "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
-                "(bytes)", "(bytes)");
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now);
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" HEAP"
+                          G1PPRL_SUM_ADDR_FORMAT("reserved")
+                          G1PPRL_SUM_BYTE_FORMAT("region-size"),
+                          p2i(g1_reserved.start()), p2i(g1_reserved.end()),
+                          HeapRegion::GrainBytes);
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
+                          G1PPRL_TYPE_H_FORMAT
+                          G1PPRL_ADDR_BASE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_DOUBLE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT,
+                          "type", "address-range",
+                          "used", "prev-live", "next-live", "gc-eff",
+                          "remset", "code-roots");
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
+                          G1PPRL_TYPE_H_FORMAT
+                          G1PPRL_ADDR_BASE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_DOUBLE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT
+                          G1PPRL_BYTE_H_FORMAT,
+                          "", "",
+                          "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
+                          "(bytes)", "(bytes)");
 }
 
 // It takes as a parameter a reference to one of the _hum_* fields, it
@@ -3701,18 +3646,18 @@
   _total_strong_code_roots_bytes += strong_code_roots_bytes;
 
   // Print a line for this particular region.
-  _out->print_cr(G1PPRL_LINE_PREFIX
-                 G1PPRL_TYPE_FORMAT
-                 G1PPRL_ADDR_BASE_FORMAT
-                 G1PPRL_BYTE_FORMAT
-                 G1PPRL_BYTE_FORMAT
-                 G1PPRL_BYTE_FORMAT
-                 G1PPRL_DOUBLE_FORMAT
-                 G1PPRL_BYTE_FORMAT
-                 G1PPRL_BYTE_FORMAT,
-                 type, p2i(bottom), p2i(end),
-                 used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
-                 remset_bytes, strong_code_roots_bytes);
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
+                          G1PPRL_TYPE_FORMAT
+                          G1PPRL_ADDR_BASE_FORMAT
+                          G1PPRL_BYTE_FORMAT
+                          G1PPRL_BYTE_FORMAT
+                          G1PPRL_BYTE_FORMAT
+                          G1PPRL_DOUBLE_FORMAT
+                          G1PPRL_BYTE_FORMAT
+                          G1PPRL_BYTE_FORMAT,
+                          type, p2i(bottom), p2i(end),
+                          used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
+                          remset_bytes, strong_code_roots_bytes);
 
   return false;
 }
@@ -3721,23 +3666,22 @@
   // add static memory usages to remembered set sizes
   _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
   // Print the footer of the output.
-  _out->print_cr(G1PPRL_LINE_PREFIX);
-  _out->print_cr(G1PPRL_LINE_PREFIX
-                 " SUMMARY"
-                 G1PPRL_SUM_MB_FORMAT("capacity")
-                 G1PPRL_SUM_MB_PERC_FORMAT("used")
-                 G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
-                 G1PPRL_SUM_MB_PERC_FORMAT("next-live")
-                 G1PPRL_SUM_MB_FORMAT("remset")
-                 G1PPRL_SUM_MB_FORMAT("code-roots"),
-                 bytes_to_mb(_total_capacity_bytes),
-                 bytes_to_mb(_total_used_bytes),
-                 perc(_total_used_bytes, _total_capacity_bytes),
-                 bytes_to_mb(_total_prev_live_bytes),
-                 perc(_total_prev_live_bytes, _total_capacity_bytes),
-                 bytes_to_mb(_total_next_live_bytes),
-                 perc(_total_next_live_bytes, _total_capacity_bytes),
-                 bytes_to_mb(_total_remset_bytes),
-                 bytes_to_mb(_total_strong_code_roots_bytes));
-  _out->cr();
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
+  log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
+                         " SUMMARY"
+                         G1PPRL_SUM_MB_FORMAT("capacity")
+                         G1PPRL_SUM_MB_PERC_FORMAT("used")
+                         G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
+                         G1PPRL_SUM_MB_PERC_FORMAT("next-live")
+                         G1PPRL_SUM_MB_FORMAT("remset")
+                         G1PPRL_SUM_MB_FORMAT("code-roots"),
+                         bytes_to_mb(_total_capacity_bytes),
+                         bytes_to_mb(_total_used_bytes),
+                         perc(_total_used_bytes, _total_capacity_bytes),
+                         bytes_to_mb(_total_prev_live_bytes),
+                         perc(_total_prev_live_bytes, _total_capacity_bytes),
+                         bytes_to_mb(_total_next_live_bytes),
+                         perc(_total_next_live_bytes, _total_capacity_bytes),
+                         bytes_to_mb(_total_remset_bytes),
+                         bytes_to_mb(_total_strong_code_roots_bytes));
 }
--- a/hotspot/src/share/vm/gc/g1/concurrentMark.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMark.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -978,8 +978,6 @@
 // after we sort the old regions at the end of the cleanup operation.
 class G1PrintRegionLivenessInfoClosure: public HeapRegionClosure {
 private:
-  outputStream* _out;
-
   // Accumulators for these values.
   size_t _total_used_bytes;
   size_t _total_capacity_bytes;
@@ -1024,7 +1022,7 @@
 public:
   // The header and footer are printed in the constructor and
   // destructor respectively.
-  G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name);
+  G1PrintRegionLivenessInfoClosure(const char* phase_name);
   virtual bool doHeapRegion(HeapRegion* r);
   ~G1PrintRegionLivenessInfoClosure();
 };
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,12 +26,13 @@
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1MMUTracker.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTrace.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/vmThread.hpp"
 
@@ -78,20 +79,6 @@
   }
 };
 
-// We want to avoid that the logging from the concurrent thread is mixed
-// with the logging from a STW GC. So, if necessary join the STS to ensure
-// that the logging is done either before or after the STW logging.
-void ConcurrentMarkThread::cm_log(bool doit, bool join_sts, const char* fmt, ...) {
-  if (doit) {
-    SuspendibleThreadSetJoiner sts_joiner(join_sts);
-    va_list args;
-    va_start(args, fmt);
-    gclog_or_tty->gclog_stamp();
-    gclog_or_tty->vprint_cr(fmt, args);
-    va_end(args);
-  }
-}
-
 // Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
 void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) {
   if (g1_policy->adaptive_young_list_length()) {
@@ -143,8 +130,11 @@
         _cm->scanRootRegions();
       }
 
-      double mark_start_sec = os::elapsedTime();
-      cm_log(G1Log::fine(), true, "[GC concurrent-mark-start]");
+      // It would be nice to use the GCTraceConcTime class here but
+      // the "end" logging is inside the loop and not at the end of
+      // a scope. Mimicking the same log output as GCTraceConcTime instead.
+      jlong mark_start = os::elapsed_counter();
+      log_info(gc)("Concurrent Mark (%.3fs)", TimeHelper::counter_to_seconds(mark_start));
 
       int iter = 0;
       do {
@@ -154,20 +144,22 @@
         }
 
         double mark_end_time = os::elapsedVTime();
-        double mark_end_sec = os::elapsedTime();
+        jlong mark_end = os::elapsed_counter();
         _vtime_mark_accum += (mark_end_time - cycle_start);
         if (!cm()->has_aborted()) {
           delay_to_keep_mmu(g1_policy, true /* remark */);
-
-          cm_log(G1Log::fine(), true, "[GC concurrent-mark-end, %1.7lf secs]", mark_end_sec - mark_start_sec);
+          log_info(gc)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
+                       TimeHelper::counter_to_seconds(mark_start),
+                       TimeHelper::counter_to_seconds(mark_end),
+                       TimeHelper::counter_to_millis(mark_end - mark_start));
 
           CMCheckpointRootsFinalClosure final_cl(_cm);
-          VM_CGC_Operation op(&final_cl, "GC remark", true /* needs_pll */);
+          VM_CGC_Operation op(&final_cl, "Pause Remark", true /* needs_pll */);
           VMThread::execute(&op);
         }
         if (cm()->restart_for_overflow()) {
-          cm_log(G1TraceMarkStackOverflow, true, "Restarting conc marking because of MS overflow in remark (restart #%d).", iter);
-          cm_log(G1Log::fine(), true, "[GC concurrent-mark-restart-for-overflow]");
+          log_debug(gc)("Restarting conc marking because of MS overflow in remark (restart #%d).", iter);
+          log_info(gc)("Concurrent Mark restart for overflow");
         }
       } while (cm()->restart_for_overflow());
 
@@ -181,7 +173,7 @@
         delay_to_keep_mmu(g1_policy, false /* cleanup */);
 
         CMCleanUp cl_cl(_cm);
-        VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
+        VM_CGC_Operation op(&cl_cl, "Pause Cleanup", false /* needs_pll */);
         VMThread::execute(&op);
       } else {
         // We don't want to update the marking status if a GC pause
@@ -201,8 +193,7 @@
         // place, it would wait for us to process the regions
         // reclaimed by cleanup.
 
-        double cleanup_start_sec = os::elapsedTime();
-        cm_log(G1Log::fine(), false, "[GC concurrent-cleanup-start]");
+        GCTraceConcTime(Info, gc) tt("Concurrent Cleanup");
 
         // Now do the concurrent cleanup operation.
         _cm->completeCleanup();
@@ -217,9 +208,6 @@
         // while it's trying to join the STS, which is conditional on
         // the GC workers finishing.
         g1h->reset_free_regions_coming();
-
-        double cleanup_end_sec = os::elapsedTime();
-        cm_log(G1Log::fine(), true, "[GC concurrent-cleanup-end, %1.7lf secs]", cleanup_end_sec - cleanup_start_sec);
       }
       guarantee(cm()->cleanup_list_is_empty(),
                 "at this point there should be no regions on the cleanup list");
@@ -253,7 +241,7 @@
         if (!cm()->has_aborted()) {
           g1_policy->record_concurrent_mark_cleanup_completed();
         } else {
-          cm_log(G1Log::fine(), false, "[GC concurrent-mark-abort]");
+          log_info(gc)("Concurrent Mark abort");
         }
       }
 
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -40,7 +40,6 @@
   double _vtime_accum;  // Accumulated virtual time.
 
   double _vtime_mark_accum;
-  void cm_log(bool doit, bool join_sts, const char* fmt, ...) ATTRIBUTE_PRINTF(4, 5);
 
  public:
   virtual void run();
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -112,7 +112,7 @@
                           fl_owner);
   set_buffer_size(G1UpdateBufferSize);
   _shared_dirty_card_queue.set_lock(lock);
-  _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
+  _free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
 }
 
 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -353,7 +353,7 @@
   assert(hr->is_empty(), "expected empty region (index %u)", hr->hrm_index());
   hr->set_archive();
   _g1h->old_set_add(hr);
-  _g1h->hr_printer()->alloc(hr, G1HRPrinter::Archive);
+  _g1h->hr_printer()->alloc(hr);
   _allocated_regions.append(hr);
   _allocation_region = hr;
 
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/space.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 #include "services/memTracker.hpp"
@@ -50,14 +51,9 @@
 
   storage->set_mapping_changed_listener(&_listener);
 
-  if (TraceBlockOffsetTable) {
-    gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
-    gclog_or_tty->print_cr("  "
-                  "  rs.base(): " PTR_FORMAT
-                  "  rs.size(): " SIZE_FORMAT
-                  "  rs end(): " PTR_FORMAT,
-                  p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
-  }
+  log_trace(gc, bot)("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
+  log_trace(gc, bot)("    rs.base(): " PTR_FORMAT "  rs.size(): " SIZE_FORMAT "  rs end(): " PTR_FORMAT,
+                     p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
 }
 
 bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -36,10 +36,8 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
-#include "gc/g1/g1ErgoVerbose.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1MarkSweep.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
@@ -59,11 +57,12 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
@@ -224,11 +223,9 @@
   MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
   while (!_secondary_free_list.is_empty() || free_regions_coming()) {
     if (!_secondary_free_list.is_empty()) {
-      if (G1ConcRegionFreeingVerbose) {
-        gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                               "secondary_free_list has %u entries",
-                               _secondary_free_list.length());
-      }
+      log_develop_trace(gc, freelist)("G1ConcRegionFreeing [region alloc] : "
+                                      "secondary_free_list has %u entries",
+                                      _secondary_free_list.length());
       // It looks as if there are free regions available on the
       // secondary_free_list. Let's move them to the free_list and try
       // again to allocate from it.
@@ -237,11 +234,9 @@
       assert(_hrm.num_free_regions() > 0, "if the secondary_free_list was not "
              "empty we should have moved at least one entry to the free_list");
       HeapRegion* res = _hrm.allocate_free_region(is_old);
-      if (G1ConcRegionFreeingVerbose) {
-        gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                               "allocated " HR_FORMAT " from secondary_free_list",
-                               HR_FORMAT_PARAMS(res));
-      }
+      log_develop_trace(gc, freelist)("G1ConcRegionFreeing [region alloc] : "
+                                      "allocated " HR_FORMAT " from secondary_free_list",
+                                      HR_FORMAT_PARAMS(res));
       return res;
     }
 
@@ -251,10 +246,8 @@
     SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag);
   }
 
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                           "could not allocate from secondary_free_list");
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [region alloc] : "
+                                  "could not allocate from secondary_free_list");
   return NULL;
 }
 
@@ -266,10 +259,8 @@
   HeapRegion* res;
   if (G1StressConcRegionFreeing) {
     if (!_secondary_free_list.is_empty()) {
-      if (G1ConcRegionFreeingVerbose) {
-        gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                               "forced to look at the secondary_free_list");
-      }
+      log_develop_trace(gc, freelist)("G1ConcRegionFreeing [region alloc] : "
+                                      "forced to look at the secondary_free_list");
       res = new_region_try_secondary_free_list(is_old);
       if (res != NULL) {
         return res;
@@ -280,10 +271,8 @@
   res = _hrm.allocate_free_region(is_old);
 
   if (res == NULL) {
-    if (G1ConcRegionFreeingVerbose) {
-      gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                             "res == NULL, trying the secondary_free_list");
-    }
+    log_develop_trace(gc, freelist)("G1ConcRegionFreeing [region alloc] : "
+                                    "res == NULL, trying the secondary_free_list");
     res = new_region_try_secondary_free_list(is_old);
   }
   if (res == NULL && do_expand && _expand_heap_after_alloc_failure) {
@@ -293,11 +282,9 @@
     // reconsider the use of _expand_heap_after_alloc_failure.
     assert(SafepointSynchronize::is_at_safepoint(), "invariant");
 
-    ergo_verbose1(ErgoHeapSizing,
-                  "attempt heap expansion",
-                  ergo_format_reason("region allocation request failed")
-                  ergo_format_byte("allocation request"),
-                  word_size * HeapWordSize);
+    log_debug(gc, ergo, heap)("Attempt heap expansion (region allocation request failed). Allocation request: " SIZE_FORMAT "B",
+                              word_size * HeapWordSize);
+
     if (expand(word_size * HeapWordSize)) {
       // Given that expand() succeeded in expanding the heap, and we
       // always expand the heap by an amount aligned to the heap
@@ -423,11 +410,7 @@
   for (uint i = first; i <= last; ++i) {
     hr = region_at(i);
     _humongous_set.add(hr);
-    if (i == first) {
-      _hr_printer.alloc(G1HRPrinter::StartsHumongous, hr, hr->top());
-    } else {
-      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->top());
-    }
+    _hr_printer.alloc(hr);
   }
 
   return new_obj;
@@ -485,11 +468,9 @@
     if (first != G1_NO_HRM_INDEX) {
       // We found something. Make sure these regions are committed, i.e. expand
       // the heap. Alternatively we could do a defragmentation GC.
-      ergo_verbose1(ErgoHeapSizing,
-                    "attempt heap expansion",
-                    ergo_format_reason("humongous allocation request failed")
-                    ergo_format_byte("allocation request"),
-                    word_size * HeapWordSize);
+      log_debug(gc, ergo, heap)("Attempt heap expansion (humongous allocation request failed). Allocation request: " SIZE_FORMAT "B",
+                                    word_size * HeapWordSize);
+
 
       _hrm.expand_at(first, obj_regions);
       g1_policy()->record_new_heap_size(num_regions());
@@ -808,11 +789,9 @@
     }
     increase_used(word_size * HeapWordSize);
     if (commits != 0) {
-      ergo_verbose1(ErgoHeapSizing,
-                    "attempt heap expansion",
-                    ergo_format_reason("allocate archive regions")
-                    ergo_format_byte("total size"),
-                    HeapRegion::GrainWords * HeapWordSize * commits);
+      log_debug(gc, ergo, heap)("Attempt heap expansion (allocate archive regions). Total size: " SIZE_FORMAT "B",
+                                HeapRegion::GrainWords * HeapWordSize * commits);
+
     }
 
     // Mark each G1 region touched by the range as archive, add it to the old set,
@@ -824,9 +803,9 @@
     while (curr_region != NULL) {
       assert(curr_region->is_empty() && !curr_region->is_pinned(),
              "Region already in use (index %u)", curr_region->hrm_index());
-      _hr_printer.alloc(curr_region, G1HRPrinter::Archive);
       curr_region->set_allocation_context(AllocationContext::system());
       curr_region->set_archive();
+      _hr_printer.alloc(curr_region);
       _old_set.add(curr_region);
       if (curr_region != last_region) {
         curr_region->set_top(curr_region->end());
@@ -993,11 +972,8 @@
   }
 
   if (uncommitted_regions != 0) {
-    ergo_verbose1(ErgoHeapSizing,
-                  "attempt heap shrinking",
-                  ergo_format_reason("uncommitted archive regions")
-                  ergo_format_byte("total size"),
-                  HeapRegion::GrainWords * HeapWordSize * uncommitted_regions);
+    log_debug(gc, ergo, heap)("Attempt heap shrinking (uncommitted archive regions). Total size: " SIZE_FORMAT "B",
+                              HeapRegion::GrainWords * HeapWordSize * uncommitted_regions);
   }
   decrease_used(size_used);
 }
@@ -1215,19 +1191,7 @@
 public:
   bool doHeapRegion(HeapRegion* hr) {
     assert(!hr->is_young(), "not expecting to find young regions");
-    if (hr->is_free()) {
-      // We only generate output for non-empty regions.
-    } else if (hr->is_starts_humongous()) {
-      _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
-    } else if (hr->is_continues_humongous()) {
-      _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
-    } else if (hr->is_archive()) {
-      _hr_printer->post_compaction(hr, G1HRPrinter::Archive);
-    } else if (hr->is_old()) {
-      _hr_printer->post_compaction(hr, G1HRPrinter::Old);
-    } else {
-      ShouldNotReachHere();
-    }
+    _hr_printer->post_compaction(hr);
     return false;
   }
 
@@ -1236,8 +1200,11 @@
 };
 
 void G1CollectedHeap::print_hrm_post_compaction() {
-  PostCompactionPrinterClosure cl(hr_printer());
-  heap_region_iterate(&cl);
+  if (_hr_printer.is_active()) {
+    PostCompactionPrinterClosure cl(hr_printer());
+    heap_region_iterate(&cl);
+  }
+
 }
 
 bool G1CollectedHeap::do_full_collection(bool explicit_gc,
@@ -1258,7 +1225,6 @@
   SvcGCMarker sgcm(SvcGCMarker::FULL);
   ResourceMark rm;
 
-  G1Log::update_level();
   print_heap_before_gc();
   trace_heap_before_gc(gc_tracer);
 
@@ -1276,10 +1242,10 @@
 
     // Timing
     assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant");
-    TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+    GCTraceCPUTime tcpu;
 
     {
-      GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL);
+      GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
       TraceCollectorStats tcs(g1mm()->full_collection_counters());
       TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
 
@@ -1330,11 +1296,6 @@
       _allocator->abandon_gc_alloc_regions();
       g1_rem_set()->cleanupHRRS();
 
-      // We should call this after we retire any currently active alloc
-      // regions so that all the ALLOC / RETIRE events are generated
-      // before the start GC event.
-      _hr_printer.start_gc(true /* full */, (size_t) total_collections());
-
       // We may have added regions to the current incremental collection
       // set between the last GC or pause and now. We need to clear the
       // incremental collection set and then start rebuilding it afresh
@@ -1401,14 +1362,10 @@
 
       resize_if_necessary_after_full_collection();
 
-      if (_hr_printer.is_active()) {
-        // We should do this after we potentially resize the heap so
-        // that all the COMMIT / UNCOMMIT events are generated before
-        // the end GC event.
-
-        print_hrm_post_compaction();
-        _hr_printer.end_gc(true /* full */, (size_t) total_collections());
-      }
+      // We should do this after we potentially resize the heap so
+      // that all the COMMIT / UNCOMMIT events are generated before
+      // the compaction events.
+      print_hrm_post_compaction();
 
       G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
       if (hot_card_cache->use_cache()) {
@@ -1477,10 +1434,6 @@
 
       g1_policy()->record_full_collection_end();
 
-      if (G1Log::fine()) {
-        g1_policy()->print_heap_transition();
-      }
-
       // We must call G1MonitoringSupport::update_sizes() in the same scoping level
       // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
       // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
@@ -1490,9 +1443,7 @@
       gc_epilogue(true);
     }
 
-    if (G1Log::finer()) {
-      g1_policy()->print_detailed_heap_transition(true /* full */);
-    }
+    g1_policy()->print_detailed_heap_transition();
 
     print_heap_after_gc();
     trace_heap_after_gc(gc_tracer);
@@ -1570,30 +1521,22 @@
   if (capacity_after_gc < minimum_desired_capacity) {
     // Don't expand unless it's significant
     size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
-    ergo_verbose4(ErgoHeapSizing,
-                  "attempt heap expansion",
-                  ergo_format_reason("capacity lower than "
-                                     "min desired capacity after Full GC")
-                  ergo_format_byte("capacity")
-                  ergo_format_byte("occupancy")
-                  ergo_format_byte_perc("min desired capacity"),
-                  capacity_after_gc, used_after_gc,
-                  minimum_desired_capacity, (double) MinHeapFreeRatio);
+
+    log_debug(gc, ergo, heap)("Attempt heap expansion (capacity lower than min desired capacity after Full GC). "
+                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
+                              capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
+
     expand(expand_bytes);
 
     // No expansion, now see if we want to shrink
   } else if (capacity_after_gc > maximum_desired_capacity) {
     // Capacity too large, compute shrinking size
     size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity;
-    ergo_verbose4(ErgoHeapSizing,
-                  "attempt heap shrinking",
-                  ergo_format_reason("capacity higher than "
-                                     "max desired capacity after Full GC")
-                  ergo_format_byte("capacity")
-                  ergo_format_byte("occupancy")
-                  ergo_format_byte_perc("max desired capacity"),
-                  capacity_after_gc, used_after_gc,
-                  maximum_desired_capacity, (double) MaxHeapFreeRatio);
+
+    log_debug(gc, ergo, heap)("Attempt heap shrinking (capacity higher than max desired capacity after Full GC). "
+                              "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
+                              capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
+
     shrink(shrink_bytes);
   }
 }
@@ -1699,11 +1642,10 @@
   verify_region_sets_optional();
 
   size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes);
-  ergo_verbose1(ErgoHeapSizing,
-                "attempt heap expansion",
-                ergo_format_reason("allocation request failed")
-                ergo_format_byte("allocation request"),
-                word_size * HeapWordSize);
+  log_debug(gc, ergo, heap)("Attempt heap expansion (allocation request failed). Allocation request: " SIZE_FORMAT "B",
+                            word_size * HeapWordSize);
+
+
   if (expand(expand_bytes)) {
     _hrm.verify_optional();
     verify_region_sets_optional();
@@ -1718,16 +1660,12 @@
   size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
   aligned_expand_bytes = align_size_up(aligned_expand_bytes,
                                        HeapRegion::GrainBytes);
-  ergo_verbose2(ErgoHeapSizing,
-                "expand the heap",
-                ergo_format_byte("requested expansion amount")
-                ergo_format_byte("attempted expansion amount"),
-                expand_bytes, aligned_expand_bytes);
+
+  log_debug(gc, ergo, heap)("Expand the heap. requested expansion amount:" SIZE_FORMAT "B expansion amount:" SIZE_FORMAT "B",
+                            expand_bytes, aligned_expand_bytes);
 
   if (is_maximal_no_gc()) {
-    ergo_verbose0(ErgoHeapSizing,
-                      "did not expand the heap",
-                      ergo_format_reason("heap already fully expanded"));
+    log_debug(gc, ergo, heap)("Did not expand the heap (heap already fully expanded)");
     return false;
   }
 
@@ -1745,9 +1683,8 @@
     assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition");
     g1_policy()->record_new_heap_size(num_regions());
   } else {
-    ergo_verbose0(ErgoHeapSizing,
-                  "did not expand the heap",
-                  ergo_format_reason("heap expansion operation failed"));
+    log_debug(gc, ergo, heap)("Did not expand the heap (heap expansion operation failed)");
+
     // The expansion of the virtual storage space was unsuccessful.
     // Let's see if it was because we ran out of swap.
     if (G1ExitOnExpansionFailure &&
@@ -1769,18 +1706,13 @@
   uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove);
   size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes;
 
-  ergo_verbose3(ErgoHeapSizing,
-                "shrink the heap",
-                ergo_format_byte("requested shrinking amount")
-                ergo_format_byte("aligned shrinking amount")
-                ergo_format_byte("attempted shrinking amount"),
-                shrink_bytes, aligned_shrink_bytes, shrunk_bytes);
+
+  log_debug(gc, ergo, heap)("Shrink the heap. requested shrinking amount: " SIZE_FORMAT "B aligned shrinking amount: " SIZE_FORMAT "B attempted shrinking amount: " SIZE_FORMAT "B",
+                            shrink_bytes, aligned_shrink_bytes, shrunk_bytes);
   if (num_regions_removed > 0) {
     g1_policy()->record_new_heap_size(num_regions());
   } else {
-    ergo_verbose0(ErgoHeapSizing,
-                  "did not shrink the heap",
-                  ergo_format_reason("heap shrinking operation failed"));
+    log_debug(gc, ergo, heap)("Did not expand the heap (heap shrinking operation failed)");
   }
 }
 
@@ -1892,8 +1824,8 @@
                                          translation_factor,
                                          mtGC);
   if (TracePageSizes) {
-    gclog_or_tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
-                           description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
+    tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT,
+                  description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size);
   }
   return result;
 }
@@ -1902,16 +1834,10 @@
   CollectedHeap::pre_initialize();
   os::enable_vtime();
 
-  G1Log::init();
-
   // Necessary to satisfy locking discipline assertions.
 
   MutexLocker x(Heap_lock);
 
-  // We have to initialize the printer before committing the heap, as
-  // it will be used then.
-  _hr_printer.set_active(G1PrintHeapRegions);
-
   // While there are no constraints in the GC code that HeapWordSize
   // be any particular value, there are multiple other areas in the
   // system which believe this to be true (e.g. oop->object_size in some
@@ -2104,7 +2030,7 @@
 
 void G1CollectedHeap::stop() {
   // Stop all concurrent threads. We do this to make sure these threads
-  // do not continue to execute and access resources (e.g. gclog_or_tty)
+  // do not continue to execute and access resources (e.g. logging)
   // that are destroyed during shutdown.
   _cg1r->stop();
   _cmThread->stop();
@@ -2221,9 +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) {
-      gclog_or_tty->print_cr("Region " HR_FORMAT " has GC time stamp = %d, "
-                             "expected %d", HR_FORMAT_PARAMS(hr),
-                             region_gc_time_stamp, _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);
       _failures = true;
     }
     return false;
@@ -2816,12 +2741,13 @@
     if (!oopDesc::is_null(heap_oop)) {
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       if (_g1h->is_obj_dead_cond(obj, _vo)) {
-        gclog_or_tty->print_cr("Root location " PTR_FORMAT " "
-                               "points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
+        LogHandle(gc, verify) log;
+        log.info("Root location " PTR_FORMAT " points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
         if (_vo == VerifyOption_G1UseMarkWord) {
-          gclog_or_tty->print_cr("  Mark word: " INTPTR_FORMAT, (intptr_t)obj->mark());
+          log.info("  Mark word: " PTR_FORMAT, p2i(obj->mark()));
         }
-        obj->print_on(gclog_or_tty);
+        ResourceMark rm;
+        obj->print_on(log.info_stream());
         _failures = true;
       }
     }
@@ -2866,10 +2792,10 @@
       // Verify that the strong code root list for this region
       // contains the nmethod
       if (!hrrs->strong_code_roots_list_contains(_nm)) {
-        gclog_or_tty->print_cr("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_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()));
         _failures = true;
       }
     }
@@ -3047,12 +2973,8 @@
         r->object_iterate(&not_dead_yet_cl);
         if (_vo != VerifyOption_G1UseNextMarking) {
           if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
-            gclog_or_tty->print_cr("[" 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_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());
             _failures = true;
           }
         } else {
@@ -3100,85 +3022,75 @@
   }
 };
 
-void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
-  if (SafepointSynchronize::is_at_safepoint()) {
-    assert(Thread::current()->is_VM_thread(),
-           "Expected to be executed serially by the VM thread at this point");
-
-    if (!silent) { gclog_or_tty->print("Roots "); }
-    VerifyRootsClosure rootsCl(vo);
-    VerifyKlassClosure klassCl(this, &rootsCl);
-    CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
-
-    // We apply the relevant closures to all the oops in the
-    // system dictionary, class loader data graph, the string table
-    // and the nmethods in the code cache.
-    G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
-    G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
-
-    {
-      G1RootProcessor root_processor(this, 1);
-      root_processor.process_all_roots(&rootsCl,
-                                       &cldCl,
-                                       &blobsCl);
-    }
-
-    bool failures = rootsCl.failures() || codeRootsCl.failures();
-
-    if (vo != VerifyOption_G1UseMarkWord) {
-      // If we're verifying during a full GC then the region sets
-      // will have been torn down at the start of the GC. Therefore
-      // verifying the region sets will fail. So we only verify
-      // the region sets when not in a full GC.
-      if (!silent) { gclog_or_tty->print("HeapRegionSets "); }
-      verify_region_sets();
+void G1CollectedHeap::verify(VerifyOption vo) {
+  if (!SafepointSynchronize::is_at_safepoint()) {
+    log_info(gc, verify)("Skipping verification. Not at safepoint.");
+  }
+
+  assert(Thread::current()->is_VM_thread(),
+         "Expected to be executed serially by the VM thread at this point");
+
+  log_debug(gc, verify)("Roots");
+  VerifyRootsClosure rootsCl(vo);
+  VerifyKlassClosure klassCl(this, &rootsCl);
+  CLDToKlassAndOopClosure cldCl(&klassCl, &rootsCl, false);
+
+  // We apply the relevant closures to all the oops in the
+  // system dictionary, class loader data graph, the string table
+  // and the nmethods in the code cache.
+  G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
+  G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
+
+  {
+    G1RootProcessor root_processor(this, 1);
+    root_processor.process_all_roots(&rootsCl,
+                                     &cldCl,
+                                     &blobsCl);
+  }
+
+  bool failures = rootsCl.failures() || codeRootsCl.failures();
+
+  if (vo != VerifyOption_G1UseMarkWord) {
+    // If we're verifying during a full GC then the region sets
+    // will have been torn down at the start of the GC. Therefore
+    // verifying the region sets will fail. So we only verify
+    // the region sets when not in a full GC.
+    log_debug(gc, verify)("HeapRegionSets");
+    verify_region_sets();
+  }
+
+  log_debug(gc, verify)("HeapRegions");
+  if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
+
+    G1ParVerifyTask task(this, vo);
+    workers()->run_task(&task);
+    if (task.failures()) {
+      failures = true;
     }
 
-    if (!silent) { gclog_or_tty->print("HeapRegions "); }
-    if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
-
-      G1ParVerifyTask task(this, vo);
-      workers()->run_task(&task);
-      if (task.failures()) {
-        failures = true;
-      }
-
-    } else {
-      VerifyRegionClosure blk(false, vo);
-      heap_region_iterate(&blk);
-      if (blk.failures()) {
-        failures = true;
-      }
-    }
-
-    if (G1StringDedup::is_enabled()) {
-      if (!silent) gclog_or_tty->print("StrDedup ");
-      G1StringDedup::verify();
+  } else {
+    VerifyRegionClosure blk(false, vo);
+    heap_region_iterate(&blk);
+    if (blk.failures()) {
+      failures = true;
     }
-
-    if (failures) {
-      gclog_or_tty->print_cr("Heap:");
-      // 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().
-      print_extended_on(gclog_or_tty);
-      gclog_or_tty->cr();
-      gclog_or_tty->flush();
-    }
-    guarantee(!failures, "there should not have been any failures");
-  } else {
-    if (!silent) {
-      gclog_or_tty->print("(SKIPPING Roots, HeapRegionSets, HeapRegions, RemSet");
-      if (G1StringDedup::is_enabled()) {
-        gclog_or_tty->print(", StrDedup");
-      }
-      gclog_or_tty->print(") ");
-    }
-  }
-}
-
-void G1CollectedHeap::verify(bool silent) {
-  verify(silent, VerifyOption_G1UsePrevMarking);
+  }
+
+  if (G1StringDedup::is_enabled()) {
+    log_debug(gc, verify)("StrDedup");
+    G1StringDedup::verify();
+  }
+
+  if (failures) {
+    log_info(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;
+    print_extended_on(log.info_stream());
+  }
+  guarantee(!failures, "there should not have been any failures");
 }
 
 double G1CollectedHeap::verify(bool guard, const char* msg) {
@@ -3196,12 +3108,12 @@
 }
 
 void G1CollectedHeap::verify_before_gc() {
-  double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+  double verify_time_ms = verify(VerifyBeforeGC, "Before GC");
   g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
 }
 
 void G1CollectedHeap::verify_after_gc() {
-  double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+  double verify_time_ms = verify(VerifyAfterGC, "After GC");
   g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
 }
 
@@ -3311,12 +3223,8 @@
     // to that.
     g1_policy()->print_tracing_info();
   }
-  if (G1SummarizeRSetStats) {
-    g1_rem_set()->print_summary_info();
-  }
-  if (G1SummarizeConcMark) {
-    concurrent_mark()->print_summary_info();
-  }
+  g1_rem_set()->print_summary_info();
+  concurrent_mark()->print_summary_info();
   g1_policy()->print_yg_surv_rate_info();
 }
 
@@ -3334,28 +3242,27 @@
     size_t occupied = hrrs->occupied();
     _occupied_sum += occupied;
 
-    gclog_or_tty->print_cr("Printing RSet for region " HR_FORMAT,
-                           HR_FORMAT_PARAMS(r));
+    tty->print_cr("Printing RSet for region " HR_FORMAT, HR_FORMAT_PARAMS(r));
     if (occupied == 0) {
-      gclog_or_tty->print_cr("  RSet is empty");
+      tty->print_cr("  RSet is empty");
     } else {
       hrrs->print();
     }
-    gclog_or_tty->print_cr("----------");
+    tty->print_cr("----------");
     return false;
   }
 
   PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) {
-    gclog_or_tty->cr();
-    gclog_or_tty->print_cr("========================================");
-    gclog_or_tty->print_cr("%s", msg);
-    gclog_or_tty->cr();
+    tty->cr();
+    tty->print_cr("========================================");
+    tty->print_cr("%s", msg);
+    tty->cr();
   }
 
   ~PrintRSetsClosure() {
-    gclog_or_tty->print_cr("Occupied Sum: " SIZE_FORMAT, _occupied_sum);
-    gclog_or_tty->print_cr("========================================");
-    gclog_or_tty->cr();
+    tty->print_cr("Occupied Sum: " SIZE_FORMAT, _occupied_sum);
+    tty->print_cr("========================================");
+    tty->cr();
   }
 };
 
@@ -3413,20 +3320,12 @@
   accumulate_statistics_all_tlabs();
   ensure_parsability(true);
 
-  if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) &&
-      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
-    g1_rem_set()->print_periodic_summary_info("Before GC RS summary");
-  }
+  g1_rem_set()->print_periodic_summary_info("Before GC RS summary", total_collections());
 }
 
 void G1CollectedHeap::gc_epilogue(bool full) {
-
-  if (G1SummarizeRSetStats &&
-      (G1SummarizeRSetStatsPeriod > 0) &&
-      // we are at the end of the GC. Total collections has already been increased.
-      ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
-    g1_rem_set()->print_periodic_summary_info("After GC RS summary");
-  }
+  // we are at the end of the GC. Total collections has already been increased.
+  g1_rem_set()->print_periodic_summary_info("After GC RS summary", total_collections() - 1);
 
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
@@ -3672,7 +3571,14 @@
   st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
 }
 
-void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const {
+void G1CollectedHeap::print_taskqueue_stats() const {
+  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+    return;
+  }
+  LogHandle(gc, task, stats) log;
+  ResourceMark rm;
+  outputStream* st = log.trace_stream();
+
   print_taskqueue_stats_hdr(st);
 
   TaskQueueStats totals;
@@ -3694,41 +3600,17 @@
 }
 #endif // TASKQUEUE_STATS
 
-void G1CollectedHeap::log_gc_header() {
-  if (!G1Log::fine()) {
-    return;
-  }
-
-  gclog_or_tty->gclog_stamp();
-
-  GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
-    .append(collector_state()->gcs_are_young() ? "(young)" : "(mixed)")
-    .append(collector_state()->during_initial_mark_pause() ? " (initial-mark)" : "");
-
-  gclog_or_tty->print("[%s", (const char*)gc_cause_str);
-}
-
-void G1CollectedHeap::log_gc_footer(double pause_time_sec) {
-  if (!G1Log::fine()) {
-    return;
-  }
-
-  if (G1Log::finer()) {
-    if (evacuation_failed()) {
-      gclog_or_tty->print(" (to-space exhausted)");
-    }
-    gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
-    g1_policy()->print_phases(pause_time_sec);
-    g1_policy()->print_detailed_heap_transition();
-  } else {
-    if (evacuation_failed()) {
-      gclog_or_tty->print("--");
-    }
-    g1_policy()->print_heap_transition();
-    gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
-  }
-  gclog_or_tty->flush();
-}
+void G1CollectedHeap::log_gc_footer(double pause_time_counter) {
+  if (evacuation_failed()) {
+    log_info(gc)("To-space exhausted");
+  }
+
+  double pause_time_sec = TimeHelper::counter_to_seconds(pause_time_counter);
+  g1_policy()->print_phases(pause_time_sec);
+
+  g1_policy()->print_detailed_heap_transition();
+}
+
 
 void G1CollectedHeap::wait_for_root_region_scanning() {
   double scan_wait_start = os::elapsedTime();
@@ -3764,7 +3646,6 @@
 
   wait_for_root_region_scanning();
 
-  G1Log::update_level();
   print_heap_before_gc();
   trace_heap_before_gc(_gc_tracer_stw);
 
@@ -3801,16 +3682,25 @@
 
     _gc_tracer_stw->report_yc_type(collector_state()->yc_type());
 
-    TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+    GCTraceCPUTime tcpu;
 
     uint active_workers = AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
                                                                   workers()->active_workers(),
                                                                   Threads::number_of_non_daemon_threads());
     workers()->set_active_workers(active_workers);
+    FormatBuffer<> gc_string("Pause ");
+    if (collector_state()->during_initial_mark_pause()) {
+      gc_string.append("Initial Mark");
+    } else if (collector_state()->gcs_are_young()) {
+      gc_string.append("Young");
+    } else {
+      gc_string.append("Mixed");
+    }
+    GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true);
 
     double pause_start_sec = os::elapsedTime();
+    double pause_start_counter = os::elapsed_counter();
     g1_policy()->note_gc_start(active_workers);
-    log_gc_header();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
     TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -3868,11 +3758,6 @@
         // of the collection set!).
         _allocator->release_mutator_alloc_region();
 
-        // We should call this after we retire the mutator alloc
-        // region(s) so that all the ALLOC / RETIRE events are generated
-        // before the start GC event.
-        _hr_printer.start_gc(false /* full */, (size_t) total_collections());
-
         // This timing is only used by the ergonomics to handle our pause target.
         // It is unclear why this should not include the full pause. We will
         // investigate this in CR 7178365.
@@ -3996,7 +3881,7 @@
           size_t expand_bytes = g1_policy()->expansion_amount();
           if (expand_bytes > 0) {
             size_t bytes_before = capacity();
-            // No need for an ergo verbose message here,
+            // No need for an ergo logging here,
             // expansion_amount() does this when it returns a value > 0.
             double expand_ms;
             if (!expand(expand_bytes, &expand_ms)) {
@@ -4056,12 +3941,6 @@
         // CM reference discovery will be re-enabled if necessary.
       }
 
-      // We should do this after we potentially expand the heap so
-      // that all the COMMIT events are generated before the end GC
-      // event, and after we retire the GC alloc regions so that all
-      // RETIRE events are generated before the end GC event.
-      _hr_printer.end_gc(false /* full */, (size_t) total_collections());
-
 #ifdef TRACESPINNING
       ParallelTaskTerminator::print_termination_counts();
 #endif
@@ -4070,7 +3949,7 @@
     }
 
     // Print the remainder of the GC log output.
-    log_gc_footer(os::elapsedTime() - pause_start_sec);
+    log_gc_footer(os::elapsed_counter() - pause_start_counter);
 
     // It is not yet to safe to tell the concurrent mark to
     // start as we have some optional output below. We don't want the
@@ -4080,7 +3959,7 @@
     _hrm.verify_optional();
     verify_region_sets_optional();
 
-    TASKQUEUE_STATS_ONLY(if (PrintTaskqueue) print_taskqueue_stats());
+    TASKQUEUE_STATS_ONLY(print_taskqueue_stats());
     TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
 
     print_heap_after_gc();
@@ -4235,13 +4114,12 @@
 
       assert(pss->queue_is_empty(), "should be empty");
 
-      if (PrintTerminationStats) {
+      if (log_is_enabled(Debug, gc, task, stats)) {
         MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
         size_t lab_waste;
         size_t lab_undo_waste;
         pss->waste(lab_waste, lab_undo_waste);
-        _g1h->print_termination_stats(gclog_or_tty,
-                                      worker_id,
+        _g1h->print_termination_stats(worker_id,
                                       (os::elapsedTime() - start_sec) * 1000.0,   /* elapsed time */
                                       strong_roots_sec * 1000.0,                  /* strong roots time */
                                       term_sec * 1000.0,                          /* evac term time */
@@ -4259,22 +4137,22 @@
   }
 };
 
-void G1CollectedHeap::print_termination_stats_hdr(outputStream* const st) {
-  st->print_raw_cr("GC Termination Stats");
-  st->print_raw_cr("     elapsed  --strong roots-- -------termination------- ------waste (KiB)------");
-  st->print_raw_cr("thr     ms        ms      %        ms      %    attempts  total   alloc    undo");
-  st->print_raw_cr("--- --------- --------- ------ --------- ------ -------- ------- ------- -------");
-}
-
-void G1CollectedHeap::print_termination_stats(outputStream* const st,
-                                              uint worker_id,
+void G1CollectedHeap::print_termination_stats_hdr() {
+  log_debug(gc, task, stats)("GC Termination Stats");
+  log_debug(gc, task, stats)("     elapsed  --strong roots-- -------termination------- ------waste (KiB)------");
+  log_debug(gc, task, stats)("thr     ms        ms      %%        ms      %%    attempts  total   alloc    undo");
+  log_debug(gc, task, stats)("--- --------- --------- ------ --------- ------ -------- ------- ------- -------");
+}
+
+void G1CollectedHeap::print_termination_stats(uint worker_id,
                                               double elapsed_ms,
                                               double strong_roots_ms,
                                               double term_ms,
                                               size_t term_attempts,
                                               size_t alloc_buffer_waste,
                                               size_t undo_waste) const {
-  st->print_cr("%3d %9.2f %9.2f %6.2f "
+  log_debug(gc, task, stats)
+              ("%3d %9.2f %9.2f %6.2f "
                "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
                SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
                worker_id, elapsed_ms, strong_roots_ms, strong_roots_ms * 100 / elapsed_ms,
@@ -4323,13 +4201,11 @@
               "claim value %d after unlink less than initial symbol table size %d",
               SymbolTable::parallel_claimed_index(), _initial_symbol_table_size);
 
-    if (G1TraceStringSymbolTableScrubbing) {
-      gclog_or_tty->print_cr("Cleaned string and symbol table, "
-                             "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
-                             "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
-                             strings_processed(), strings_removed(),
-                             symbols_processed(), symbols_removed());
-    }
+    log_debug(gc, stringdedup)("Cleaned string and symbol table, "
+                               "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
+                               "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
+                               strings_processed(), strings_removed(),
+                               symbols_processed(), symbols_removed());
   }
 
   void work(uint worker_id) {
@@ -5169,10 +5045,7 @@
       ClassLoaderDataGraph::clear_claimed_marks();
     }
 
-    // The individual threads will set their evac-failure closures.
-    if (PrintTerminationStats) {
-      print_termination_stats_hdr(gclog_or_tty);
-    }
+    print_termination_stats_hdr();
 
     workers()->run_task(&g1_par_task);
     end_par_time_sec = os::elapsedTime();
@@ -5306,9 +5179,9 @@
   free_region(hr, free_list, par);
 }
 
-void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed,
-                                           const HeapRegionSetCount& humongous_regions_removed) {
-  if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) {
+void G1CollectedHeap::remove_from_old_sets(const uint old_regions_removed,
+                                           const uint humongous_regions_removed) {
+  if (old_regions_removed > 0 || humongous_regions_removed > 0) {
     MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
     _old_set.bulk_remove(old_regions_removed);
     _humongous_set.bulk_remove(humongous_regions_removed);
@@ -5411,11 +5284,8 @@
             "tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
-    gclog_or_tty->cr();
-    gclog_or_tty->print_cr("## wrong marked address on %s bitmap: " PTR_FORMAT,
-                           bitmap_name, p2i(result));
-    gclog_or_tty->print_cr("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT,
-                           bitmap_name, p2i(tams), p2i(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));
     return false;
   }
   return true;
@@ -5440,9 +5310,8 @@
     res_n = verify_no_bits_over_tams("next", next_bitmap, ntams, end);
   }
   if (!res_p || !res_n) {
-    gclog_or_tty->print_cr("#### Bitmap verification failed for " HR_FORMAT,
-                           HR_FORMAT_PARAMS(hr));
-    gclog_or_tty->print_cr("#### Caller: %s", caller);
+    log_info(gc, verify)("#### Bitmap verification failed for " HR_FORMAT, HR_FORMAT_PARAMS(hr));
+    log_info(gc, verify)("#### Caller: %s", caller);
     return false;
   }
   return true;
@@ -5494,42 +5363,42 @@
     InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
     if (hr->is_humongous()) {
       if (hr->in_collection_set()) {
-        gclog_or_tty->print_cr("\n## humongous region %u in CSet", i);
+        log_info(gc, verify)("## humongous region %u in CSet", i);
         _failures = true;
         return true;
       }
       if (cset_state.is_in_cset()) {
-        gclog_or_tty->print_cr("\n## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
+        log_info(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()) {
-        gclog_or_tty->print_cr("\n## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
+        log_info(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()) {
-        gclog_or_tty->print_cr("\n## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
+        log_info(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()) {
-        gclog_or_tty->print_cr("\n## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                               hr->in_collection_set(), cset_state.value(), i);
+        log_info(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())) {
-          gclog_or_tty->print_cr("\n## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                                 hr->is_young(), cset_state.value(), i);
+          log_info(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())) {
-          gclog_or_tty->print_cr("\n## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                                 hr->is_old(), cset_state.value(), i);
+          log_info(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
+                               hr->is_old(), cset_state.value(), i);
           _failures = true;
           return true;
         }
@@ -5697,12 +5566,12 @@
  private:
   FreeRegionList* _free_region_list;
   HeapRegionSet* _proxy_set;
-  HeapRegionSetCount _humongous_regions_removed;
+  uint _humongous_regions_removed;
   size_t _freed_bytes;
  public:
 
   G1FreeHumongousRegionClosure(FreeRegionList* free_region_list) :
-    _free_region_list(free_region_list), _humongous_regions_removed(), _freed_bytes(0) {
+    _free_region_list(free_region_list), _humongous_regions_removed(0), _freed_bytes(0) {
   }
 
   virtual bool doHeapRegion(HeapRegion* r) {
@@ -5746,9 +5615,7 @@
     uint region_idx = r->hrm_index();
     if (!g1h->is_humongous_reclaim_candidate(region_idx) ||
         !r->rem_set()->is_empty()) {
-
-      if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT "  with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+      log_debug(gc, humongous)("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT "  with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                                region_idx,
                                (size_t)obj->size() * HeapWordSize,
                                p2i(r->bottom()),
@@ -5758,8 +5625,6 @@
                                g1h->is_humongous_reclaim_candidate(region_idx),
                                obj->is_typeArray()
                               );
-      }
-
       return false;
     }
 
@@ -5767,8 +5632,7 @@
               "Only eagerly reclaiming type arrays is supported, but the object "
               PTR_FORMAT " is not.", p2i(r->bottom()));
 
-    if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+    log_debug(gc, humongous)("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                              region_idx,
                              (size_t)obj->size() * HeapWordSize,
                              p2i(r->bottom()),
@@ -5778,7 +5642,7 @@
                              g1h->is_humongous_reclaim_candidate(region_idx),
                              obj->is_typeArray()
                             );
-    }
+
     // Need to clear mark bit of the humongous object if already set.
     if (next_bitmap->isMarked(r->bottom())) {
       next_bitmap->clear(r->bottom());
@@ -5787,7 +5651,7 @@
       HeapRegion* next = g1h->next_region_in_humongous(r);
       _freed_bytes += r->used();
       r->set_containing_set(NULL);
-      _humongous_regions_removed.increment(1u, r->capacity());
+      _humongous_regions_removed++;
       g1h->free_humongous_region(r, _free_region_list, false);
       r = next;
     } while (r != NULL);
@@ -5795,24 +5659,20 @@
     return false;
   }
 
-  HeapRegionSetCount& humongous_free_count() {
+  uint humongous_free_count() {
     return _humongous_regions_removed;
   }
 
   size_t bytes_freed() const {
     return _freed_bytes;
   }
-
-  size_t humongous_reclaimed() const {
-    return _humongous_regions_removed.length();
-  }
 };
 
 void G1CollectedHeap::eagerly_reclaim_humongous_regions() {
   assert_at_safepoint(true);
 
   if (!G1EagerReclaimHumongousObjects ||
-      (!_has_humongous_reclaim_candidates && !G1TraceEagerReclaimHumongousObjects)) {
+      (!_has_humongous_reclaim_candidates && !log_is_enabled(Debug, gc, humongous))) {
     g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms(0.0, 0);
     return;
   }
@@ -5824,8 +5684,7 @@
   G1FreeHumongousRegionClosure cl(&local_cleanup_list);
   heap_region_iterate(&cl);
 
-  HeapRegionSetCount empty_set;
-  remove_from_old_sets(empty_set, cl.humongous_free_count());
+  remove_from_old_sets(0, cl.humongous_free_count());
 
   G1HRPrinter* hrp = hr_printer();
   if (hrp->is_active()) {
@@ -5840,7 +5699,7 @@
   decrement_summary_bytes(cl.bytes_freed());
 
   g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms((os::elapsedTime() - start_time) * 1000.0,
-                                                                    cl.humongous_reclaimed());
+                                                                    cl.humongous_free_count());
 }
 
 // This routine is similar to the above but does not record
@@ -5865,10 +5724,7 @@
 }
 
 void G1CollectedHeap::set_free_regions_coming() {
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : "
-                           "setting free regions coming");
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [cm thread] : setting free regions coming");
 
   assert(!free_regions_coming(), "pre-condition");
   _free_regions_coming = true;
@@ -5883,10 +5739,7 @@
     SecondaryFreeList_lock->notify_all();
   }
 
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : "
-                           "reset free regions coming");
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [cm thread] : reset free regions coming");
 }
 
 void G1CollectedHeap::wait_while_free_regions_coming() {
@@ -5896,10 +5749,7 @@
     return;
   }
 
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : "
-                           "waiting for free regions");
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [other] : waiting for free regions");
 
   {
     MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
@@ -5908,10 +5758,7 @@
     }
   }
 
-  if (G1ConcRegionFreeingVerbose) {
-    gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : "
-                           "done waiting for free regions");
-  }
+  log_develop_trace(gc, freelist)("G1ConcRegionFreeing [other] : done waiting for free regions");
 }
 
 bool G1CollectedHeap::is_old_gc_alloc_region(HeapRegion* hr) {
@@ -5929,8 +5776,8 @@
   NoYoungRegionsClosure() : _success(true) { }
   bool doHeapRegion(HeapRegion* r) {
     if (r->is_young()) {
-      gclog_or_tty->print_cr("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
-                             p2i(r->bottom()), p2i(r->end()));
+      log_info(gc, verify)("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
+                           p2i(r->bottom()), p2i(r->end()));
       _success = false;
     }
     return false;
@@ -6104,7 +5951,7 @@
                                               false /* do_expand */);
     if (new_alloc_region != NULL) {
       set_region_short_lived_locked(new_alloc_region);
-      _hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full);
+      _hr_printer.alloc(new_alloc_region, young_list_full);
       check_bitmaps("Mutator Region Allocation", new_alloc_region);
       return new_alloc_region;
     }
@@ -6145,13 +5992,12 @@
       new_alloc_region->record_timestamp();
       if (is_survivor) {
         new_alloc_region->set_survivor();
-        _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
         check_bitmaps("Survivor Region Allocation", new_alloc_region);
       } else {
         new_alloc_region->set_old();
-        _hr_printer.alloc(new_alloc_region, G1HRPrinter::Old);
         check_bitmaps("Old Region Allocation", new_alloc_region);
       }
+      _hr_printer.alloc(new_alloc_region);
       bool during_im = collector_state()->during_initial_mark_pause();
       new_alloc_region->note_start_of_copying(during_im);
       return new_alloc_region;
@@ -6180,11 +6026,8 @@
 
   if (index != G1_NO_HRM_INDEX) {
     if (expanded) {
-      ergo_verbose1(ErgoHeapSizing,
-                    "attempt heap expansion",
-                    ergo_format_reason("requested address range outside heap bounds")
-                    ergo_format_byte("region size"),
-                    HeapRegion::GrainWords * HeapWordSize);
+      log_debug(gc, ergo, heap)("Attempt heap expansion (requested address range outside heap bounds). region size: " SIZE_FORMAT "B",
+                                HeapRegion::GrainWords * HeapWordSize);
     }
     _hrm.allocate_free_regions_starting_at(index, 1);
     return region_at(index);
@@ -6201,9 +6044,9 @@
   HeapRegionManager*   _hrm;
 
 public:
-  HeapRegionSetCount _old_count;
-  HeapRegionSetCount _humongous_count;
-  HeapRegionSetCount _free_count;
+  uint _old_count;
+  uint _humongous_count;
+  uint _free_count;
 
   VerifyRegionListsClosure(HeapRegionSet* old_set,
                            HeapRegionSet* humongous_set,
@@ -6216,13 +6059,13 @@
       // TODO
     } else if (hr->is_humongous()) {
       assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index());
-      _humongous_count.increment(1u, hr->capacity());
+      _humongous_count++;
     } else if (hr->is_empty()) {
       assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
-      _free_count.increment(1u, hr->capacity());
+      _free_count++;
     } else if (hr->is_old()) {
       assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index());
-      _old_count.increment(1u, hr->capacity());
+      _old_count++;
     } else {
       // There are no other valid region types. Check for one invalid
       // one we can identify: pinned without old or humongous set.
@@ -6233,17 +6076,9 @@
   }
 
   void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
-    guarantee(old_set->length() == _old_count.length(), "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length());
-    guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), "Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-              old_set->total_capacity_bytes(), _old_count.capacity());
-
-    guarantee(humongous_set->length() == _humongous_count.length(), "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count.length());
-    guarantee(humongous_set->total_capacity_bytes() == _humongous_count.capacity(), "Hum set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-              humongous_set->total_capacity_bytes(), _humongous_count.capacity());
-
-    guarantee(free_list->num_free_regions() == _free_count.length(), "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count.length());
-    guarantee(free_list->total_capacity_bytes() == _free_count.capacity(), "Free list capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-              free_list->total_capacity_bytes(), _free_count.capacity());
+    guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count);
+    guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count);
+    guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count);
   }
 };
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -290,8 +290,7 @@
   void verify_before_gc();
   void verify_after_gc();
 
-  void log_gc_header();
-  void log_gc_footer(double pause_time_sec);
+  void log_gc_footer(double pause_time_counter);
 
   void trace_heap(GCWhen::Type when, const GCTracer* tracer);
 
@@ -573,6 +572,9 @@
   void register_old_region_with_cset(HeapRegion* r) {
     _in_cset_fast_test.set_in_old(r->hrm_index());
   }
+  inline void register_ext_region_with_cset(HeapRegion* r) {
+    _in_cset_fast_test.set_ext(r->hrm_index());
+  }
   void clear_in_cset(const HeapRegion* hr) {
     _in_cset_fast_test.clear(hr);
   }
@@ -701,8 +703,8 @@
   void shrink_helper(size_t expand_bytes);
 
   #if TASKQUEUE_STATS
-  static void print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
-  void print_taskqueue_stats(outputStream* const st = gclog_or_tty) const;
+  static void print_taskqueue_stats_hdr(outputStream* const st);
+  void print_taskqueue_stats() const;
   void reset_taskqueue_stats();
   #endif // TASKQUEUE_STATS
 
@@ -735,10 +737,9 @@
   void post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
 
   // Print the header for the per-thread termination statistics.
-  static void print_termination_stats_hdr(outputStream* const st);
+  static void print_termination_stats_hdr();
   // Print actual per-thread termination statistics.
-  void print_termination_stats(outputStream* const st,
-                               uint worker_id,
+  void print_termination_stats(uint worker_id,
                                double elapsed_ms,
                                double strong_roots_ms,
                                double term_ms,
@@ -965,6 +966,10 @@
     return CollectedHeap::G1CollectedHeap;
   }
 
+  virtual const char* name() const {
+    return "G1";
+  }
+
   const G1CollectorState* collector_state() const { return &_collector_state; }
   G1CollectorState* collector_state() { return &_collector_state; }
 
@@ -1127,7 +1132,7 @@
   inline void old_set_remove(HeapRegion* hr);
 
   size_t non_young_capacity_bytes() {
-    return _old_set.total_capacity_bytes() + _humongous_set.total_capacity_bytes();
+    return (_old_set.length() + _humongous_set.length()) * HeapRegion::GrainBytes;
   }
 
   void set_free_regions_coming();
@@ -1152,7 +1157,7 @@
   // True iff an evacuation has failed in the most-recent collection.
   bool evacuation_failed() { return _evacuation_failed; }
 
-  void remove_from_old_sets(const HeapRegionSetCount& old_regions_removed, const HeapRegionSetCount& humongous_regions_removed);
+  void remove_from_old_sets(const uint old_regions_removed, const uint humongous_regions_removed);
   void prepend_to_freelist(FreeRegionList* list);
   void decrement_summary_bytes(size_t bytes);
 
@@ -1362,6 +1367,10 @@
 
   YoungList* young_list() const { return _young_list; }
 
+  uint old_regions_count() const { return _old_set.length(); }
+
+  uint humongous_regions_count() const { return _humongous_set.length(); }
+
   // debugging
   bool check_young_list_well_formed() {
     return _young_list->check_list_well_formed();
@@ -1479,10 +1488,7 @@
   // Currently there is only one place where this is called with
   // vo == UseMarkWord, which is to verify the marking during a
   // full GC.
-  void verify(bool silent, VerifyOption vo);
-
-  // Override; it uses the "prev" marking information
-  virtual void verify(bool silent);
+  void verify(VerifyOption vo);
 
   // The methods below are here for convenience and dispatch the
   // appropriate method depending on value of the given VerifyOption
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,9 +29,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1IHOPControl.hpp"
-#include "gc/g1/g1ErgoVerbose.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
@@ -121,6 +119,8 @@
 
   _eden_used_bytes_before_gc(0),
   _survivor_used_bytes_before_gc(0),
+  _old_used_bytes_before_gc(0),
+  _humongous_used_bytes_before_gc(0),
   _heap_used_bytes_before_gc(0),
   _metaspace_used_bytes_before_gc(0),
   _eden_capacity_bytes_before_gc(0),
@@ -177,18 +177,6 @@
   HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
   HeapRegionRemSet::setup_remset_size();
 
-  G1ErgoVerbose::initialize();
-  if (PrintAdaptiveSizePolicy) {
-    // Currently, we only use a single switch for all the heuristics.
-    G1ErgoVerbose::set_enabled(true);
-    // Given that we don't currently have a verboseness level
-    // parameter, we'll hardcode this to high. This can be easily
-    // changed in the future.
-    G1ErgoVerbose::set_level(ErgoHigh);
-  } else {
-    G1ErgoVerbose::set_enabled(false);
-  }
-
   _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
   _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
   clear_ratio_check_data();
@@ -791,7 +779,7 @@
        curr = curr->get_next_young_region()) {
     SurvRateGroup* group = curr->surv_rate_group();
     if (group == NULL && !curr->is_survivor()) {
-      gclog_or_tty->print_cr("## %s: encountered NULL surv_rate_group", name);
+      log_info(gc, verify)("## %s: encountered NULL surv_rate_group", name);
       ret = false;
     }
 
@@ -799,13 +787,12 @@
       int age = curr->age_in_surv_rate_group();
 
       if (age < 0) {
-        gclog_or_tty->print_cr("## %s: encountered negative age", name);
+        log_info(gc, verify)("## %s: encountered negative age", name);
         ret = false;
       }
 
       if (age <= prev_age) {
-        gclog_or_tty->print_cr("## %s: region ages are not strictly increasing "
-                               "(%d, %d)", name, age, prev_age);
+        log_info(gc, verify)("## %s: region ages are not strictly increasing (%d, %d)", name, age, prev_age);
         ret = false;
       }
       prev_age = age;
@@ -902,7 +889,6 @@
   collector_state()->set_during_marking(true);
   assert(!collector_state()->initiate_conc_mark_if_possible(), "we should have cleared it by now");
   collector_state()->set_during_initial_mark_pause(false);
-  _cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms;
 }
 
 void G1CollectorPolicy::record_concurrent_mark_remark_start() {
@@ -914,7 +900,6 @@
   double end_time_sec = os::elapsedTime();
   double elapsed_time_ms = (end_time_sec - _mark_remark_start_sec)*1000.0;
   _concurrent_mark_remark_times_ms->add(elapsed_time_ms);
-  _cur_mark_stop_world_time_ms += elapsed_time_ms;
   _prev_collection_pause_end_ms += elapsed_time_ms;
 
   record_pause(Remark, _mark_remark_start_sec, end_time_sec);
@@ -984,38 +969,15 @@
   size_t alloc_byte_size = alloc_word_size * HeapWordSize;
   size_t marking_request_bytes = cur_used_bytes + alloc_byte_size;
 
+  bool result = false;
   if (marking_request_bytes > marking_initiating_used_threshold) {
-    if (collector_state()->gcs_are_young() && !collector_state()->last_young_gc()) {
-      ergo_verbose5(ErgoConcCycles,
-        "request concurrent cycle initiation",
-        ergo_format_reason("occupancy higher than threshold")
-        ergo_format_byte("occupancy")
-        ergo_format_byte("allocation request")
-        ergo_format_byte_perc("threshold")
-        ergo_format_str("source"),
-        cur_used_bytes,
-        alloc_byte_size,
-        marking_initiating_used_threshold,
-        (double) marking_initiating_used_threshold / _g1->capacity() * 100,
-        source);
-      return true;
-    } else {
-      ergo_verbose5(ErgoConcCycles,
-        "do not request concurrent cycle initiation",
-        ergo_format_reason("still doing mixed collections")
-        ergo_format_byte("occupancy")
-        ergo_format_byte("allocation request")
-        ergo_format_byte_perc("threshold")
-        ergo_format_str("source"),
-        cur_used_bytes,
-        alloc_byte_size,
-        marking_initiating_used_threshold,
-        (double) InitiatingHeapOccupancyPercent,
-        source);
-    }
+    result = collector_state()->gcs_are_young() && !collector_state()->last_young_gc();
+    log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s",
+                              result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)",
+                              cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1->capacity() * 100, source);
   }
 
-  return false;
+  return result;
 }
 
 // Anything below that is considered to be zero
@@ -1029,13 +991,7 @@
   bool last_pause_included_initial_mark = false;
   bool update_stats = !_g1->evacuation_failed();
 
-#ifndef PRODUCT
-  if (G1YoungSurvRateVerbose) {
-    gclog_or_tty->cr();
-    _short_lived_surv_rate_group->print();
-    // do that for any other surv rate groups too
-  }
-#endif // PRODUCT
+  NOT_PRODUCT(_short_lived_surv_rate_group->print());
 
   record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec);
 
@@ -1230,13 +1186,9 @@
   double scan_hcc_time_ms = average_time_ms(G1GCPhaseTimes::ScanHCC);
 
   if (update_rs_time_goal_ms < scan_hcc_time_ms) {
-    ergo_verbose2(ErgoTiming,
-                  "adjust concurrent refinement thresholds",
-                  ergo_format_reason("Scanning the HCC expected to take longer than Update RS time goal")
-                  ergo_format_ms("Update RS time goal")
-                  ergo_format_ms("Scan HCC time"),
-                  update_rs_time_goal_ms,
-                  scan_hcc_time_ms);
+    log_debug(gc, ergo, refine)("Adjust concurrent refinement thresholds (scanning the HCC expected to take longer than Update RS time goal)."
+                                "Update RS time goal: %1.2fms Scan HCC time: %1.2fms",
+                                update_rs_time_goal_ms, scan_hcc_time_ms);
 
     update_rs_time_goal_ms = 0;
   } else {
@@ -1314,65 +1266,37 @@
   _eden_used_bytes_before_gc = young_list->eden_used_bytes();
   _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
   _heap_capacity_bytes_before_gc = _g1->capacity();
+  _old_used_bytes_before_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
+  _humongous_used_bytes_before_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
   _heap_used_bytes_before_gc = _g1->used();
-
-  _eden_capacity_bytes_before_gc =
-         (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
-
-  if (full) {
-    _metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes();
-  }
+  _eden_capacity_bytes_before_gc = (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
+  _metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes();
 }
 
-void G1CollectorPolicy::print_heap_transition(size_t bytes_before) const {
-  size_t bytes_after = _g1->used();
-  size_t capacity = _g1->capacity();
-
-  gclog_or_tty->print(" " SIZE_FORMAT "%s->" SIZE_FORMAT "%s(" SIZE_FORMAT "%s)",
-      byte_size_in_proper_unit(bytes_before),
-      proper_unit_for_byte_size(bytes_before),
-      byte_size_in_proper_unit(bytes_after),
-      proper_unit_for_byte_size(bytes_after),
-      byte_size_in_proper_unit(capacity),
-      proper_unit_for_byte_size(capacity));
-}
-
-void G1CollectorPolicy::print_heap_transition() const {
-  print_heap_transition(_heap_used_bytes_before_gc);
-}
-
-void G1CollectorPolicy::print_detailed_heap_transition(bool full) const {
+void G1CollectorPolicy::print_detailed_heap_transition() const {
   YoungList* young_list = _g1->young_list();
 
   size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
   size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
   size_t heap_used_bytes_after_gc = _g1->used();
+  size_t old_used_bytes_after_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
+  size_t humongous_used_bytes_after_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
 
   size_t heap_capacity_bytes_after_gc = _g1->capacity();
   size_t eden_capacity_bytes_after_gc =
     (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
+  size_t survivor_capacity_bytes_after_gc = _max_survivor_regions * HeapRegion::GrainBytes;
 
-  gclog_or_tty->print(
-    "   [Eden: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->" EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ") "
-    "Survivors: " EXT_SIZE_FORMAT "->" EXT_SIZE_FORMAT " "
-    "Heap: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->"
-    EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")]",
-    EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
-    EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
-    EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
-    EXT_SIZE_PARAMS(eden_capacity_bytes_after_gc),
-    EXT_SIZE_PARAMS(_survivor_used_bytes_before_gc),
-    EXT_SIZE_PARAMS(survivor_used_bytes_after_gc),
-    EXT_SIZE_PARAMS(_heap_used_bytes_before_gc),
-    EXT_SIZE_PARAMS(_heap_capacity_bytes_before_gc),
-    EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
-    EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
+  log_info(gc, heap)("Eden: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                     _eden_used_bytes_before_gc / K, eden_used_bytes_after_gc /K, eden_capacity_bytes_after_gc /K);
+  log_info(gc, heap)("Survivor: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                     _survivor_used_bytes_before_gc / K, survivor_used_bytes_after_gc /K, survivor_capacity_bytes_after_gc /K);
+  log_info(gc, heap)("Old: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
+                     _old_used_bytes_before_gc / K, old_used_bytes_after_gc /K);
+  log_info(gc, heap)("Humongous: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
+                     _humongous_used_bytes_before_gc / K, humongous_used_bytes_after_gc /K);
 
-  if (full) {
-    MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
-  }
-
-  gclog_or_tty->cr();
+  MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
 }
 
 void G1CollectorPolicy::print_phases(double pause_time_sec) {
@@ -1692,17 +1616,9 @@
       }
     }
 
-    ergo_verbose5(ErgoHeapSizing,
-                  "attempt heap expansion",
-                  ergo_format_reason("recent GC overhead higher than "
-                                     "threshold after GC")
-                  ergo_format_perc("recent GC overhead")
-                  ergo_format_perc("current threshold")
-                  ergo_format_byte("uncommitted")
-                  ergo_format_byte_perc("base expansion amount and scale"),
-                  recent_gc_overhead, threshold,
-                  uncommitted_bytes,
-                  expand_bytes, scale_factor * 100);
+    log_debug(gc, ergo, heap)("Attempt heap expansion (recent GC overhead higher than threshold after GC) "
+                              "recent GC overhead: %1.2f %% threshold: %1.2f %% uncommitted: " SIZE_FORMAT "B base expansion amount and scale: " SIZE_FORMAT "B (%1.2f%%)",
+                              recent_gc_overhead, threshold, uncommitted_bytes, expand_bytes, scale_factor * 100);
 
     expand_bytes = static_cast<size_t>(expand_bytes * scale_factor);
 
@@ -1785,19 +1701,11 @@
   // even while we are still in the process of reclaiming memory.
   bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
   if (!during_cycle) {
-    ergo_verbose1(ErgoConcCycles,
-                  "request concurrent cycle initiation",
-                  ergo_format_reason("requested by GC cause")
-                  ergo_format_str("GC cause"),
-                  GCCause::to_string(gc_cause));
+    log_debug(gc, ergo)("Request concurrent cycle initiation (requested by GC cause). GC cause: %s", GCCause::to_string(gc_cause));
     collector_state()->set_initiate_conc_mark_if_possible(true);
     return true;
   } else {
-    ergo_verbose1(ErgoConcCycles,
-                  "do not request concurrent cycle initiation",
-                  ergo_format_reason("concurrent cycle already in progress")
-                  ergo_format_str("GC cause"),
-                  GCCause::to_string(gc_cause));
+    log_debug(gc, ergo)("Do not request concurrent cycle initiation (concurrent cycle already in progress). GC cause: %s", GCCause::to_string(gc_cause));
     return false;
   }
 }
@@ -1825,9 +1733,7 @@
     if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) {
       // Initiate a new initial mark if there is no marking or reclamation going on.
       initiate_conc_mark();
-      ergo_verbose0(ErgoConcCycles,
-                    "initiate concurrent cycle",
-                    ergo_format_reason("concurrent cycle initiation requested"));
+      log_debug(gc, ergo)("Initiate concurrent cycle (concurrent cycle initiation requested)");
     } else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) {
       // Initiate a user requested initial mark. An initial mark must be young only
       // GC, so the collector state must be updated to reflect this.
@@ -1836,9 +1742,7 @@
 
       abort_time_to_mixed_tracking();
       initiate_conc_mark();
-      ergo_verbose0(ErgoConcCycles,
-                    "initiate concurrent cycle",
-                    ergo_format_reason("user requested concurrent cycle"));
+      log_debug(gc, ergo)("Initiate concurrent cycle (user requested concurrent cycle)");
     } else {
       // The concurrent marking thread is still finishing up the
       // previous cycle. If we start one right now the two cycles
@@ -1852,9 +1756,7 @@
       // and, if it's in a yield point, it's waiting for us to
       // finish. So, at this point we will not start a cycle and we'll
       // let the concurrent marking thread complete the last one.
-      ergo_verbose0(ErgoConcCycles,
-                    "do not initiate concurrent cycle",
-                    ergo_format_reason("concurrent cycle already in progress"));
+      log_debug(gc, ergo)("Do not initiate concurrent cycle (concurrent cycle already in progress)");
     }
   }
 }
@@ -1925,7 +1827,6 @@
   double end_sec = os::elapsedTime();
   double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
   _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
-  _cur_mark_stop_world_time_ms += elapsed_time_ms;
   _prev_collection_pause_end_ms += elapsed_time_ms;
 
   record_pause(Cleanup, _mark_cleanup_start_sec, end_sec);
@@ -2200,9 +2101,7 @@
 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
                                                 const char* false_action_str) const {
   if (cset_chooser()->is_empty()) {
-    ergo_verbose0(ErgoMixedGCs,
-                  false_action_str,
-                  ergo_format_reason("candidate old regions not available"));
+    log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str);
     return false;
   }
 
@@ -2211,27 +2110,12 @@
   double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
   double threshold = (double) G1HeapWastePercent;
   if (reclaimable_perc <= threshold) {
-    ergo_verbose4(ErgoMixedGCs,
-              false_action_str,
-              ergo_format_reason("reclaimable percentage not over threshold")
-              ergo_format_region("candidate old regions")
-              ergo_format_byte_perc("reclaimable")
-              ergo_format_perc("threshold"),
-              cset_chooser()->remaining_regions(),
-              reclaimable_bytes,
-              reclaimable_perc, threshold);
+    log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
+                        false_action_str, cset_chooser()->remaining_regions(), reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
     return false;
   }
-
-  ergo_verbose4(ErgoMixedGCs,
-                true_action_str,
-                ergo_format_reason("candidate old regions available")
-                ergo_format_region("candidate old regions")
-                ergo_format_byte_perc("reclaimable")
-                ergo_format_perc("threshold"),
-                cset_chooser()->remaining_regions(),
-                reclaimable_bytes,
-                reclaimable_perc, threshold);
+  log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
+                      true_action_str, cset_chooser()->remaining_regions(), reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
   return true;
 }
 
@@ -2287,13 +2171,8 @@
   double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
   double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
 
-  ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
-                "start choosing CSet",
-                ergo_format_size("_pending_cards")
-                ergo_format_ms("predicted base time")
-                ergo_format_ms("remaining time")
-                ergo_format_ms("target pause time"),
-                _pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
+  log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
+                            _pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
 
   collector_state()->set_last_gc_was_young(collector_state()->gcs_are_young());
 
@@ -2329,15 +2208,8 @@
   _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
   time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
 
-  ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
-                "add young regions to CSet",
-                ergo_format_region("eden")
-                ergo_format_region("survivors")
-                ergo_format_ms("predicted young region time")
-                ergo_format_ms("target pause time"),
-                eden_region_length, survivor_region_length,
-                _inc_cset_predicted_elapsed_time_ms,
-                target_pause_time_ms);
+  log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
+                            eden_region_length, survivor_region_length, _inc_cset_predicted_elapsed_time_ms, target_pause_time_ms);
 
   // The number of recorded young regions is the incremental
   // collection set's current size
@@ -2366,12 +2238,8 @@
     while (hr != NULL) {
       if (old_cset_region_length() >= max_old_cset_length) {
         // Added maximum number of old regions to the CSet.
-        ergo_verbose2(ErgoCSetConstruction,
-                      "finish adding old regions to CSet",
-                      ergo_format_reason("old CSet region num reached max")
-                      ergo_format_region("old")
-                      ergo_format_region("max"),
-                      old_cset_region_length(), max_old_cset_length);
+        log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). old %u regions, max %u regions",
+                                  old_cset_region_length(), max_old_cset_length);
         break;
       }
 
@@ -2385,17 +2253,9 @@
         // We've added enough old regions that the amount of uncollected
         // reclaimable space is at or below the waste threshold. Stop
         // adding old regions to the CSet.
-        ergo_verbose5(ErgoCSetConstruction,
-                      "finish adding old regions to CSet",
-                      ergo_format_reason("reclaimable percentage not over threshold")
-                      ergo_format_region("old")
-                      ergo_format_region("max")
-                      ergo_format_byte_perc("reclaimable")
-                      ergo_format_perc("threshold"),
-                      old_cset_region_length(),
-                      max_old_cset_length,
-                      reclaimable_bytes,
-                      reclaimable_perc, threshold);
+        log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
+                                  "old %u regions, max %u regions, reclaimable: " SIZE_FORMAT "B (%1.2f%%) threshold: " UINTX_FORMAT "%%",
+                                  old_cset_region_length(), max_old_cset_length, reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
         break;
       }
 
@@ -2407,15 +2267,9 @@
           if (old_cset_region_length() >= min_old_cset_length) {
             // We have added the minimum number of old regions to the CSet,
             // we are done with this CSet.
-            ergo_verbose4(ErgoCSetConstruction,
-                          "finish adding old regions to CSet",
-                          ergo_format_reason("predicted time is too high")
-                          ergo_format_ms("predicted time")
-                          ergo_format_ms("remaining time")
-                          ergo_format_region("old")
-                          ergo_format_region("min"),
-                          predicted_time_ms, time_remaining_ms,
-                          old_cset_region_length(), min_old_cset_length);
+            log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high). "
+                                      "predicted time: %1.2fms, remaining time: %1.2fms old %u regions, min %u regions",
+                                      predicted_time_ms, time_remaining_ms, old_cset_region_length(), min_old_cset_length);
             break;
           }
 
@@ -2427,12 +2281,9 @@
         if (old_cset_region_length() >= min_old_cset_length) {
           // In the non-auto-tuning case, we'll finish adding regions
           // to the CSet if we reach the minimum.
-          ergo_verbose2(ErgoCSetConstruction,
-                        "finish adding old regions to CSet",
-                        ergo_format_reason("old CSet region num reached min")
-                        ergo_format_region("old")
-                        ergo_format_region("min"),
-                        old_cset_region_length(), min_old_cset_length);
+
+          log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached min). old %u regions, min %u regions",
+                                    old_cset_region_length(), min_old_cset_length);
           break;
         }
       }
@@ -2447,26 +2298,16 @@
       hr = cset_chooser()->peek();
     }
     if (hr == NULL) {
-      ergo_verbose0(ErgoCSetConstruction,
-                    "finish adding old regions to CSet",
-                    ergo_format_reason("candidate old regions not available"));
+      log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
     }
 
     if (expensive_region_num > 0) {
       // We print the information once here at the end, predicated on
       // whether we added any apparently expensive regions or not, to
       // avoid generating output per region.
-      ergo_verbose4(ErgoCSetConstruction,
-                    "added expensive regions to CSet",
-                    ergo_format_reason("old CSet region num not reached min")
-                    ergo_format_region("old")
-                    ergo_format_region("expensive")
-                    ergo_format_region("min")
-                    ergo_format_ms("remaining time"),
-                    old_cset_region_length(),
-                    expensive_region_num,
-                    min_old_cset_length,
-                    time_remaining_ms);
+      log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
+                                "old %u regions, expensive: %u regions, min %u regions, remaining time: %1.2fms",
+                                old_cset_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
     }
 
     cset_chooser()->verify();
@@ -2474,13 +2315,8 @@
 
   stop_incremental_cset_building();
 
-  ergo_verbose3(ErgoCSetConstruction,
-                "finish choosing CSet",
-                ergo_format_region("old")
-                ergo_format_ms("predicted old region time")
-                ergo_format_ms("time remaining"),
-                old_cset_region_length(),
-                predicted_old_time_ms, time_remaining_ms);
+  log_debug(gc, ergo, cset)("Finish choosing CSet. old %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
+                            old_cset_region_length(), predicted_old_time_ms, time_remaining_ms);
 
   double non_young_end_time_sec = os::elapsedTime();
   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
@@ -2539,14 +2375,14 @@
 void TraceYoungGenTimeData::print_summary(const char* str,
                                           const NumberSeq* seq) const {
   double sum = seq->sum();
-  gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
+  tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
                 str, sum / 1000.0, seq->avg());
 }
 
 void TraceYoungGenTimeData::print_summary_sd(const char* str,
                                              const NumberSeq* seq) const {
   print_summary(str, seq);
-  gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+  tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
                 "(num", seq->num(), seq->sd(), seq->maximum());
 }
 
@@ -2555,18 +2391,18 @@
     return;
   }
 
-  gclog_or_tty->print_cr("ALL PAUSES");
+  tty->print_cr("ALL PAUSES");
   print_summary_sd("   Total", &_total);
-  gclog_or_tty->cr();
-  gclog_or_tty->cr();
-  gclog_or_tty->print_cr("   Young GC Pauses: %8d", _young_pause_num);
-  gclog_or_tty->print_cr("   Mixed GC Pauses: %8d", _mixed_pause_num);
-  gclog_or_tty->cr();
+  tty->cr();
+  tty->cr();
+  tty->print_cr("   Young GC Pauses: %8d", _young_pause_num);
+  tty->print_cr("   Mixed GC Pauses: %8d", _mixed_pause_num);
+  tty->cr();
 
-  gclog_or_tty->print_cr("EVACUATION PAUSES");
+  tty->print_cr("EVACUATION PAUSES");
 
   if (_young_pause_num == 0 && _mixed_pause_num == 0) {
-    gclog_or_tty->print_cr("none");
+    tty->print_cr("none");
   } else {
     print_summary_sd("   Evacuation Pauses", &_total);
     print_summary("      Root Region Scan Wait", &_root_region_scan_wait);
@@ -2581,9 +2417,9 @@
     print_summary("      Clear CT", &_clear_ct);
     print_summary("      Other", &_other);
   }
-  gclog_or_tty->cr();
+  tty->cr();
 
-  gclog_or_tty->print_cr("MISC");
+  tty->print_cr("MISC");
   print_summary_sd("   Stop World", &_all_stop_world_times_ms);
   print_summary_sd("   Yields", &_all_yield_times_ms);
 }
@@ -2600,11 +2436,11 @@
   }
 
   if (_all_full_gc_times.num() > 0) {
-    gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
+    tty->print("\n%4d full_gcs: total time = %8.2f s",
       _all_full_gc_times.num(),
       _all_full_gc_times.sum() / 1000.0);
-    gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg());
-    gclog_or_tty->print_cr("                     [std. dev = %8.2f ms, max = %8.2f ms]",
+    tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg());
+    tty->print_cr("                     [std. dev = %8.2f ms, max = %8.2f ms]",
       _all_full_gc_times.sd(),
       _all_full_gc_times.maximum());
   }
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -159,6 +159,7 @@
   uint max_desired_young_length() {
     return _max_desired_young_length;
   }
+
   bool adaptive_young_list_length() const {
     return _adaptive_size;
   }
@@ -503,7 +504,6 @@
 
   // This set of variables tracks the collector efficiency, in order to
   // determine whether we should initiate a new marking.
-  double _cur_mark_stop_world_time_ms;
   double _mark_remark_start_sec;
   double _mark_cleanup_start_sec;
 
@@ -659,9 +659,7 @@
 
   // Print heap sizing transition (with less and more detail).
 
-  void print_heap_transition(size_t bytes_before) const;
-  void print_heap_transition() const;
-  void print_detailed_heap_transition(bool full = false) const;
+  void print_detailed_heap_transition() const;
 
   virtual void print_phases(double pause_time_sec);
 
@@ -828,6 +826,8 @@
 
   size_t _eden_used_bytes_before_gc;         // Eden occupancy before GC
   size_t _survivor_used_bytes_before_gc;     // Survivor occupancy before GC
+  size_t _old_used_bytes_before_gc;          // Old occupancy before GC
+  size_t _humongous_used_bytes_before_gc;    // Humongous occupancy before GC
   size_t _heap_used_bytes_before_gc;         // Heap occupancy before GC
   size_t _metaspace_used_bytes_before_gc;    // Metaspace occupancy before GC
 
--- a/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011, 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/g1ErgoVerbose.hpp"
-#include "utilities/ostream.hpp"
-
-ErgoLevel G1ErgoVerbose::_level;
-bool G1ErgoVerbose::_enabled[ErgoHeuristicNum];
-
-void G1ErgoVerbose::initialize() {
-  set_level(ErgoLow);
-  set_enabled(false);
-}
-
-void G1ErgoVerbose::set_level(ErgoLevel level) {
-  _level = level;
-}
-
-void G1ErgoVerbose::set_enabled(ErgoHeuristic n, bool enabled) {
-  assert(0 <= n && n < ErgoHeuristicNum, "pre-condition");
-  _enabled[n] = enabled;
-}
-
-void G1ErgoVerbose::set_enabled(bool enabled) {
-  for (int n = 0; n < ErgoHeuristicNum; n += 1) {
-    set_enabled((ErgoHeuristic) n, enabled);
-  }
-}
-
-const char* G1ErgoVerbose::to_string(int tag) {
-  ErgoHeuristic n = extract_heuristic(tag);
-  switch (n) {
-  case ErgoHeapSizing:        return "Heap Sizing";
-  case ErgoCSetConstruction:  return "CSet Construction";
-  case ErgoConcCycles:        return "Concurrent Cycles";
-  case ErgoMixedGCs:          return "Mixed GCs";
-  case ErgoTiming:            return "Timing";
-  case ErgoIHOP:              return "IHOP";
-  default:
-    ShouldNotReachHere();
-    // Keep the Windows compiler happy
-    return NULL;
-  }
-}
--- a/hotspot/src/share/vm/gc/g1/g1ErgoVerbose.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
-#define SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
-
-#include "memory/allocation.hpp"
-#include "utilities/debug.hpp"
-
-// The log of G1's heuristic decisions comprises of a series of
-// records which have a similar format in order to maintain
-// consistency across records and ultimately easier parsing of the
-// output, if we ever choose to do that. Each record consists of:
-// * A time stamp to be able to easily correlate each record with
-// other events.
-// * A unique string to allow us to easily identify such records.
-// * The name of the heuristic the record corresponds to.
-// * An action string which describes the action that G1 did or is
-// about to do.
-// * An optional reason string which describes the reason for the
-// action.
-// * An optional number of name/value pairs which contributed to the
-// decision to take the action described in the record.
-//
-// Each record is associated with a "tag" which is the combination of
-// the heuristic the record corresponds to, as well as the min level
-// of verboseness at which the record should be printed. The tag is
-// checked against the current settings to determine whether the record
-// should be printed or not.
-
-// The available verboseness levels.
-typedef enum {
-  // Determine which part of the tag is occupied by the level.
-  ErgoLevelShift = 8,
-  ErgoLevelMask = ~((1 << ErgoLevelShift) - 1),
-
-  // ErgoLow is 0 so that we don't have to explicitly or a heuristic
-  // id with ErgoLow to keep its use simpler.
-  ErgoLow = 0,
-  ErgoHigh = 1 << ErgoLevelShift
-} ErgoLevel;
-
-// The available heuristics.
-typedef enum {
-  // Determines which part of the tag is occupied by the heuristic id.
-  ErgoHeuristicMask = ~ErgoLevelMask,
-
-  ErgoHeapSizing = 0,
-  ErgoCSetConstruction,
-  ErgoConcCycles,
-  ErgoMixedGCs,
-  ErgoTiming,
-  ErgoIHOP,
-
-  ErgoHeuristicNum
-} ErgoHeuristic;
-
-class G1ErgoVerbose : AllStatic {
-private:
-  // Determines the minimum verboseness level at which records will be
-  // printed.
-  static ErgoLevel _level;
-  // Determines which heuristics are currently enabled.
-  static bool _enabled[ErgoHeuristicNum];
-
-  static ErgoLevel extract_level(int tag) {
-    return (ErgoLevel) (tag & ErgoLevelMask);
-  }
-
-  static ErgoHeuristic extract_heuristic(int tag) {
-    return (ErgoHeuristic) (tag & ErgoHeuristicMask);
-  }
-
-public:
-  // Needs to be explicitly called at GC initialization.
-  static void initialize();
-
-  static void set_level(ErgoLevel level);
-  static void set_enabled(ErgoHeuristic h, bool enabled);
-  // It is applied to all heuristics.
-  static void set_enabled(bool enabled);
-
-  static bool enabled(int tag) {
-    ErgoLevel level = extract_level(tag);
-    ErgoHeuristic n = extract_heuristic(tag);
-    return level <= _level && _enabled[n];
-  }
-
-  // Extract the heuristic id from the tag and return a string with
-  // its name.
-  static const char* to_string(int tag);
-};
-
-// The macros below generate the format string for values of different
-// types and/or metrics.
-
-// The reason for the action is optional and is handled specially: the
-// reason string is concatenated here so it's not necessary to pass it
-// as a parameter.
-#define ergo_format_reason(_reason_) ", reason: " _reason_
-
-// Single parameter format strings
-#define ergo_format_str(_name_)      ", " _name_ ": %s"
-#define ergo_format_region(_name_)   ", " _name_ ": %u regions"
-#define ergo_format_byte(_name_)     ", " _name_ ": " SIZE_FORMAT " bytes"
-#define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
-#define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
-#define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
-#define ergo_format_size(_name_)     ", " _name_ ": " SIZE_FORMAT
-
-// Double parameter format strings
-#define ergo_format_byte_perc(_name_)                                   \
-                             ", " _name_ ": " SIZE_FORMAT " bytes (%1.2f %%)"
-
-// Generates the format string
-#define ergo_format(_extra_format_)                           \
-  " %1.3f: [G1Ergonomics (%s) %s" _extra_format_ "]"
-
-// Conditionally, prints an ergonomic decision record. _extra_format_
-// is the format string for the optional items we'd like to print
-// (i.e., the decision's reason and any associated values). This
-// string should be built up using the ergo_*_format macros (see
-// above) to ensure consistency.
-//
-// Since we cannot rely on the compiler supporting variable argument
-// macros, this macro accepts a fixed number of arguments and passes
-// them to the print method. For convenience, we have wrapper macros
-// below which take a specific number of arguments and set the rest to
-// a default value.
-#define ergo_verbose_common(_tag_, _action_, _extra_format_,                \
-                            _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
-  do {                                                                      \
-    if (G1ErgoVerbose::enabled((_tag_))) {                                  \
-      gclog_or_tty->print_cr(ergo_format(_extra_format_),                   \
-                             os::elapsedTime(),                             \
-                             G1ErgoVerbose::to_string((_tag_)),             \
-                             (_action_),                                    \
-                             (_arg0_), (_arg1_), (_arg2_),                  \
-                             (_arg3_), (_arg4_), (_arg5_));                 \
-    }                                                                       \
-  } while (0)
-
-
-#define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
-
-#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
-  ergo_verbose6(_tag_, _action_, _extra_format_ "%s",                   \
-                _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
-
-#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
-  ergo_verbose5(_tag_, _action_, _extra_format_ "%s",                   \
-                _arg0_, _arg1_, _arg2_, _arg3_, "")
-
-#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_)                           \
-  ergo_verbose4(_tag_, _action_, _extra_format_ "%s",                   \
-                _arg0_, _arg1_, _arg2_, "")
-
-#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_)                                   \
-  ergo_verbose3(_tag_, _action_, _extra_format_ "%s",                   \
-                _arg0_, _arg1_, "")
-
-#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
-                      _arg0_)                                           \
-  ergo_verbose2(_tag_, _action_, _extra_format_ "%s",                   \
-                _arg0_, "")
-
-
-#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
-  ergo_verbose1(_tag_, _action_, _extra_format_ "%s",                   \
-                "")
-
-#define ergo_verbose(_tag_, _action_)                                   \
-  ergo_verbose0(_tag_, _action_, "")
-
-
-#endif // SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,91 +26,97 @@
 #include "memory/allocation.inline.hpp"
 #include "gc/g1/g1EvacStats.hpp"
 #include "gc/shared/gcId.hpp"
+#include "logging/log.hpp"
 #include "trace/tracing.hpp"
 
 void G1EvacStats::adjust_desired_plab_sz() {
-  if (PrintPLAB) {
-    gclog_or_tty->print(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
+  if (!ResizePLAB) {
+    log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
                         "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
                         "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
                         "regions filled = %u direct_allocated = " SIZE_FORMAT " "
                         "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") ",
                         _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
                         _regions_filled, _direct_allocated, _failure_used, _failure_waste);
+    // Clear accumulators for next round.
+    reset();
+    return;
   }
 
-  if (ResizePLAB) {
-
-    assert(is_object_aligned(max_size()) && min_size() <= max_size(),
-           "PLAB clipping computation may be incorrect");
+  assert(is_object_aligned(max_size()) && min_size() <= max_size(),
+         "PLAB clipping computation may be incorrect");
 
-    if (_allocated == 0) {
-      assert((_unused == 0),
-             "Inconsistency in PLAB stats: "
-             "_allocated: " SIZE_FORMAT ", "
-             "_wasted: " SIZE_FORMAT ", "
-             "_region_end_waste: " SIZE_FORMAT ", "
-             "_unused: " SIZE_FORMAT ", "
-             "_used  : " SIZE_FORMAT,
-             _allocated, _wasted, _region_end_waste, _unused, used());
-      _allocated = 1;
-    }
-    // The size of the PLAB caps the amount of space that can be wasted at the
-    // end of the collection. In the worst case the last PLAB could be completely
-    // empty.
-    // This allows us to calculate the new PLAB size to achieve the
-    // TargetPLABWastePct given the latest memory usage and that the last buffer
-    // will be G1LastPLABAverageOccupancy full.
-    //
-    // E.g. assume that if in the current GC 100 words were allocated and a
-    // TargetPLABWastePct of 10 had been set.
-    //
-    // So we could waste up to 10 words to meet that percentage. Given that we
-    // also assume that that buffer is typically half-full, the new desired PLAB
-    // size is set to 20 words.
-    //
-    // The amount of allocation performed should be independent of the number of
-    // threads, so should the maximum waste we can spend in total. So if
-    // we used n threads to allocate, each of them can spend maximum waste/n words in
-    // a first rough approximation. The number of threads only comes into play later
-    // when actually retrieving the actual desired PLAB size.
-    //
-    // After calculating this optimal PLAB size the algorithm applies the usual
-    // exponential decaying average over this value to guess the next PLAB size.
-    //
-    // We account region end waste fully to PLAB allocation (in the calculation of
-    // what we consider as "used_for_waste_calculation" below). This is not
-    // completely fair, but is a conservative assumption because PLABs may be sized
-    // flexibly while we cannot adjust inline allocations.
-    // Allocation during GC will try to minimize region end waste so this impact
-    // should be minimal.
-    //
-    // We need to cover overflow when calculating the amount of space actually used
-    // by objects in PLABs when subtracting the region end waste.
-    // Region end waste may be higher than actual allocation. This may occur if many
-    // threads do not allocate anything but a few rather large objects. In this
-    // degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
-    // which is an okay reaction.
-    size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
+  if (_allocated == 0) {
+    assert((_unused == 0),
+           "Inconsistency in PLAB stats: "
+           "_allocated: " SIZE_FORMAT ", "
+           "_wasted: " SIZE_FORMAT ", "
+           "_region_end_waste: " SIZE_FORMAT ", "
+           "_unused: " SIZE_FORMAT ", "
+           "_used  : " SIZE_FORMAT,
+           _allocated, _wasted, _region_end_waste, _unused, used());
+    _allocated = 1;
+  }
+  // The size of the PLAB caps the amount of space that can be wasted at the
+  // end of the collection. In the worst case the last PLAB could be completely
+  // empty.
+  // This allows us to calculate the new PLAB size to achieve the
+  // TargetPLABWastePct given the latest memory usage and that the last buffer
+  // will be G1LastPLABAverageOccupancy full.
+  //
+  // E.g. assume that if in the current GC 100 words were allocated and a
+  // TargetPLABWastePct of 10 had been set.
+  //
+  // So we could waste up to 10 words to meet that percentage. Given that we
+  // also assume that that buffer is typically half-full, the new desired PLAB
+  // size is set to 20 words.
+  //
+  // The amount of allocation performed should be independent of the number of
+  // threads, so should the maximum waste we can spend in total. So if
+  // we used n threads to allocate, each of them can spend maximum waste/n words in
+  // a first rough approximation. The number of threads only comes into play later
+  // when actually retrieving the actual desired PLAB size.
+  //
+  // After calculating this optimal PLAB size the algorithm applies the usual
+  // exponential decaying average over this value to guess the next PLAB size.
+  //
+  // We account region end waste fully to PLAB allocation (in the calculation of
+  // what we consider as "used_for_waste_calculation" below). This is not
+  // completely fair, but is a conservative assumption because PLABs may be sized
+  // flexibly while we cannot adjust inline allocations.
+  // Allocation during GC will try to minimize region end waste so this impact
+  // should be minimal.
+  //
+  // We need to cover overflow when calculating the amount of space actually used
+  // by objects in PLABs when subtracting the region end waste.
+  // Region end waste may be higher than actual allocation. This may occur if many
+  // threads do not allocate anything but a few rather large objects. In this
+  // degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
+  // which is an okay reaction.
+  size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
 
-    size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
-    size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
-    // Take historical weighted average
-    _filter.sample(cur_plab_sz);
-    // Clip from above and below, and align to object boundary
-    size_t plab_sz;
-    plab_sz = MAX2(min_size(), (size_t)_filter.average());
-    plab_sz = MIN2(max_size(), plab_sz);
-    plab_sz = align_object_size(plab_sz);
-    // Latch the result
-    _desired_net_plab_sz = plab_sz;
-    if (PrintPLAB) {
-      gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
-    }
-  }
-  if (PrintPLAB) {
-    gclog_or_tty->cr();
-  }
+  size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
+  size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
+  // Take historical weighted average
+  _filter.sample(cur_plab_sz);
+  // Clip from above and below, and align to object boundary
+  size_t plab_sz;
+  plab_sz = MAX2(min_size(), (size_t)_filter.average());
+  plab_sz = MIN2(max_size(), plab_sz);
+  plab_sz = align_object_size(plab_sz);
+  // Latch the result
+  _desired_net_plab_sz = plab_sz;
+
+  log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
+                      "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
+                      "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
+                      "regions filled = %u direct_allocated = " SIZE_FORMAT " "
+                      "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") "
+                      " (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ")",
+                      _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
+                      _regions_filled, _direct_allocated, _failure_used, _failure_waste,
+                      cur_plab_sz, plab_sz);
+
   // Clear accumulators for next round.
   reset();
 }
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,10 +26,10 @@
 #include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/workerDataArray.inline.hpp"
 #include "memory/allocation.hpp"
+#include "logging/log.hpp"
 #include "runtime/os.hpp"
 
 // Helper class for avoiding interleaved logging
@@ -73,66 +73,60 @@
     va_end(ap);
   }
 
-  void print_cr() {
-    gclog_or_tty->print_cr("%s", _buffer);
+  const char* to_string() {
     _cur = _indent_level * INDENT_CHARS;
-  }
-
-  void append_and_print_cr(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3) {
-    va_list ap;
-    va_start(ap, format);
-    vappend(format, ap);
-    va_end(ap);
-    print_cr();
+    return _buffer;
   }
 };
 
+static const char* Indents[4] = {"", "   ", "      ", "         "};
+
 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
   _max_gc_threads(max_gc_threads)
 {
   assert(max_gc_threads > 0, "Must have some GC threads");
 
-  _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2);
-  _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start:", false, 2);
+  _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning:", true, 2);
 
   // Root scanning phases
-  _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3);
-  _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots:", true, 3);
+  _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots:", true, 3);
+  _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots:", true, 3);
+  _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots:", true, 3);
+  _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots:", true, 3);
+  _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots:", true, 3);
+  _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots:", true, 3);
+  _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots:", true, 3);
+  _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots:", true, 3);
+  _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots:", true, 3);
+  _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots:", true, 3);
+  _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD:", true, 3);
+  _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots:", true, 3);
+  _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering:", true, 3);
 
-  _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC (ms)", true, G1Log::LevelFiner, 3);
+  _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS:", true, 2);
+  _gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC:", true, 3);
   _gc_par_phases[ScanHCC]->set_enabled(ConcurrentG1Refine::hot_card_cache_enabled());
-  _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2);
-  _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS:", true, 2);
+  _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning:", true, 2);
+  _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy:", true, 2);
+  _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination:", true, 2);
+  _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total:", true, 2);
+  _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End:", false, 2);
+  _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other:", true, 2);
 
-  _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3);
+  _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:", true, 3);
   _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers);
 
-  _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3);
+  _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts:", true, 3);
   _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts);
 
-  _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2);
-  _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup:", true, 2);
+  _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup:", true, 2);
 
-  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3);
-  _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, 3);
+  _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:", true, 3);
   _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
 }
 
@@ -173,16 +167,8 @@
   }
 }
 
-void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
-  LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
-}
-
-void G1GCPhaseTimes::print_stats(int level, const char* str, size_t value) {
-  LineBuffer(level).append_and_print_cr("[%s: " SIZE_FORMAT "]", str, value);
-}
-
-void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
-  LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %u]", str, value, workers);
+void G1GCPhaseTimes::print_stats(const char* indent, const char* str, double value) {
+  log_debug(gc, phases)("%s%s: %.1lf ms", indent, str, value);
 }
 
 double G1GCPhaseTimes::accounted_time_ms() {
@@ -284,10 +270,6 @@
   void print(G1GCPhaseTimes::GCParPhases phase_id) {
     WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id];
 
-    if (phase->_log_level > G1Log::level() || !phase->_enabled) {
-      return;
-    }
-
     if (phase->_length == 1) {
       print_single_length(phase_id, phase);
     } else {
@@ -295,69 +277,71 @@
     }
   }
 
+
  private:
-
   void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
     // No need for min, max, average and sum for only one worker
-    LineBuffer buf(phase->_indent_level);
-    buf.append_and_print_cr("[%s:  %.1lf]", phase->_title, _phase_times->get_time_ms(phase_id, 0));
+    log_debug(gc, phases)("%s%s:  %.1lf", Indents[phase->_indent_level], phase->_title, _phase_times->get_time_ms(phase_id, 0));
 
-    if (phase->_thread_work_items != NULL) {
-      LineBuffer buf2(phase->_thread_work_items->_indent_level);
-      buf2.append_and_print_cr("[%s:  " SIZE_FORMAT "]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
+    WorkerDataArray<size_t>* work_items = phase->_thread_work_items;
+    if (work_items != NULL) {
+      log_debug(gc, phases)("%s%s:  " SIZE_FORMAT, Indents[work_items->_indent_level], work_items->_title, _phase_times->sum_thread_work_items(phase_id));
     }
   }
 
-  void print_time_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
-    uint active_length = _phase_times->_active_gc_threads;
-    for (uint i = 0; i < active_length; ++i) {
-      buf.append("  %.1lf", _phase_times->get_time_ms(phase_id, i));
+  void print_time_values(const char* indent, G1GCPhaseTimes::GCParPhases phase_id) {
+    if (log_is_enabled(Trace, gc)) {
+      LineBuffer buf(0);
+      uint active_length = _phase_times->_active_gc_threads;
+      for (uint i = 0; i < active_length; ++i) {
+        buf.append(" %4.1lf", _phase_times->get_time_ms(phase_id, i));
+      }
+      const char* line = buf.to_string();
+      log_trace(gc, phases)("%s%-25s%s", indent, "", line);
     }
-    buf.print_cr();
   }
 
-  void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
-    uint active_length = _phase_times->_active_gc_threads;
-    for (uint i = 0; i < active_length; ++i) {
-      buf.append("  " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
+  void print_count_values(const char* indent, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
+    if (log_is_enabled(Trace, gc)) {
+      LineBuffer buf(0);
+      uint active_length = _phase_times->_active_gc_threads;
+      for (uint i = 0; i < active_length; ++i) {
+        buf.append("  " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
+      }
+      const char* line = buf.to_string();
+      log_trace(gc, phases)("%s%-25s%s", indent, "", line);
     }
-    buf.print_cr();
   }
 
   void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
-    LineBuffer buf(thread_work_items->_indent_level);
-    buf.append("[%s:", thread_work_items->_title);
-
-    if (G1Log::finest()) {
-      print_count_values(buf, phase_id, thread_work_items);
-    }
+    const char* indent = Indents[thread_work_items->_indent_level];
 
     assert(thread_work_items->_print_sum, "%s does not have print sum true even though it is a count", thread_work_items->_title);
 
-    buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
+    log_debug(gc, phases)("%s%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT,
+        indent, thread_work_items->_title,
         _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
         _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
+
+    print_count_values(indent, phase_id, thread_work_items);
   }
 
   void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
-    LineBuffer buf(phase->_indent_level);
-    buf.append("[%s:", phase->_title);
+    const char* indent = Indents[phase->_indent_level];
 
-    if (G1Log::finest()) {
-      print_time_values(buf, phase_id, phase);
+    if (phase->_print_sum) {
+      log_debug(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf, Sum: %4.1lf",
+          indent, phase->_title,
+          _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
+          _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id), _phase_times->sum_time_ms(phase_id));
+    } else {
+      log_debug(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf",
+          indent, phase->_title,
+          _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
+          _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
     }
 
-    buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
-        _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
-        _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
-
-    if (phase->_print_sum) {
-      // for things like the start and end times the sum is not
-      // that relevant
-      buf.append(", Sum: %.1lf", _phase_times->sum_time_ms(phase_id));
-    }
-
-    buf.append_and_print_cr("]");
+    print_time_values(indent, phase_id);
 
     if (phase->_thread_work_items != NULL) {
       print_thread_work_items(phase_id, phase->_thread_work_items);
@@ -371,67 +355,59 @@
   G1GCParPhasePrinter par_phase_printer(this);
 
   if (_root_region_scan_wait_time_ms > 0.0) {
-    print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
+    print_stats(Indents[1], "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
   }
 
-  print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
+  print_stats(Indents[1], "Parallel Time", _cur_collection_par_time_ms);
   for (int i = 0; i <= GCMainParPhasesLast; i++) {
     par_phase_printer.print((GCParPhases) i);
   }
 
-  print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
-  print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
+  print_stats(Indents[1], "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+  print_stats(Indents[1], "Code Root Purge", _cur_strong_code_root_purge_time_ms);
   if (G1StringDedup::is_enabled()) {
-    print_stats(1, "String Dedup Fixup", _cur_string_dedup_fixup_time_ms, _active_gc_threads);
+    print_stats(Indents[1], "String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
     for (int i = StringDedupPhasesFirst; i <= StringDedupPhasesLast; i++) {
       par_phase_printer.print((GCParPhases) i);
     }
   }
-  print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
-  print_stats(1, "Expand Heap After Collection", _cur_expand_heap_time_ms);
-
+  print_stats(Indents[1], "Clear CT", _cur_clear_ct_time_ms);
+  print_stats(Indents[1], "Expand Heap After Collection", _cur_expand_heap_time_ms);
   double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
-  print_stats(1, "Other", misc_time_ms);
+  print_stats(Indents[1], "Other", misc_time_ms);
   if (_cur_verify_before_time_ms > 0.0) {
-    print_stats(2, "Verify Before", _cur_verify_before_time_ms);
+    print_stats(Indents[2], "Verify Before", _cur_verify_before_time_ms);
   }
   if (G1CollectedHeap::heap()->evacuation_failed()) {
     double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
       _cur_evac_fail_restore_remsets;
-    print_stats(2, "Evacuation Failure", evac_fail_handling);
-    if (G1Log::finest()) {
-      print_stats(3, "Recalculate Used", _cur_evac_fail_recalc_used);
-      print_stats(3, "Remove Self Forwards", _cur_evac_fail_remove_self_forwards);
-      print_stats(3, "Restore RemSet", _cur_evac_fail_restore_remsets);
-    }
+    print_stats(Indents[2], "Evacuation Failure", evac_fail_handling);
+    log_trace(gc, phases)("%sRecalculate Used: %.1lf ms", Indents[3], _cur_evac_fail_recalc_used);
+    log_trace(gc, phases)("%sRemove Self Forwards: %.1lf ms", Indents[3], _cur_evac_fail_remove_self_forwards);
+    log_trace(gc, phases)("%sRestore RemSet: %.1lf ms", Indents[3], _cur_evac_fail_restore_remsets);
   }
-  print_stats(2, "Choose CSet",
+  print_stats(Indents[2], "Choose CSet",
     (_recorded_young_cset_choice_time_ms +
     _recorded_non_young_cset_choice_time_ms));
-  print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
-  print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
-  print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
+  print_stats(Indents[2], "Ref Proc", _cur_ref_proc_time_ms);
+  print_stats(Indents[2], "Ref Enq", _cur_ref_enq_time_ms);
+  print_stats(Indents[2], "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
   par_phase_printer.print(RedirtyCards);
   if (G1EagerReclaimHumongousObjects) {
-    print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
-    if (G1Log::finest()) {
-      print_stats(3, "Humongous Total", _cur_fast_reclaim_humongous_total);
-      print_stats(3, "Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
-    }
-    print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
-    if (G1Log::finest()) {
-      print_stats(3, "Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
-    }
+    print_stats(Indents[2], "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
+
+    log_trace(gc, phases)("%sHumongous Total: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_total);
+    log_trace(gc, phases)("%sHumongous Candidate: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_candidates);
+    print_stats(Indents[2], "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
+    log_trace(gc, phases)("%sHumongous Reclaimed: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_reclaimed);
   }
-  print_stats(2, "Free CSet",
+  print_stats(Indents[2], "Free CSet",
     (_recorded_young_free_cset_time_ms +
     _recorded_non_young_free_cset_time_ms));
-  if (G1Log::finest()) {
-    print_stats(3, "Young Free CSet", _recorded_young_free_cset_time_ms);
-    print_stats(3, "Non-Young Free CSet", _recorded_non_young_free_cset_time_ms);
-  }
+  log_trace(gc, phases)("%sYoung Free CSet: %.1lf ms", Indents[3], _recorded_young_free_cset_time_ms);
+  log_trace(gc, phases)("%sNon-Young Free CSet: %.1lf ms", Indents[3], _recorded_non_young_free_cset_time_ms);
   if (_cur_verify_after_time_ms > 0.0) {
-    print_stats(2, "Verify After", _cur_verify_after_time_ms);
+    print_stats(Indents[2], "Verify After", _cur_verify_after_time_ms);
   }
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -119,9 +119,7 @@
   double _cur_verify_after_time_ms;
 
   // Helper methods for detailed logging
-  void print_stats(int level, const char* str, double value);
-  void print_stats(int level, const char* str, size_t value);
-  void print_stats(int level, const char* str, double value, uint workers);
+  void print_stats(const char*, const char* str, double value);
 
   void note_gc_end();
 
--- a/hotspot/src/share/vm/gc/g1/g1HRPrinter.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2011, 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/g1HRPrinter.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "utilities/ostream.hpp"
-
-const char* G1HRPrinter::action_name(ActionType action) {
-  switch(action) {
-    case Alloc:          return "ALLOC";
-    case AllocForce:     return "ALLOC-FORCE";
-    case Retire:         return "RETIRE";
-    case Reuse:          return "REUSE";
-    case CSet:           return "CSET";
-    case EvacFailure:    return "EVAC-FAILURE";
-    case Cleanup:        return "CLEANUP";
-    case PostCompaction: return "POST-COMPACTION";
-    case Commit:         return "COMMIT";
-    case Uncommit:       return "UNCOMMIT";
-    default:             ShouldNotReachHere();
-  }
-  // trying to keep the Windows compiler happy
-  return NULL;
-}
-
-const char* G1HRPrinter::region_type_name(RegionType type) {
-  switch (type) {
-    case Unset:              return NULL;
-    case Eden:               return "Eden";
-    case Survivor:           return "Survivor";
-    case Old:                return "Old";
-    case StartsHumongous:    return "StartsH";
-    case ContinuesHumongous: return "ContinuesH";
-    case Archive:            return "Archive";
-    default:                 ShouldNotReachHere();
-  }
-  // trying to keep the Windows compiler happy
-  return NULL;
-}
-
-const char* G1HRPrinter::phase_name(PhaseType phase) {
-  switch (phase) {
-    case StartGC:     return "StartGC";
-    case EndGC:       return "EndGC";
-    case StartFullGC: return "StartFullGC";
-    case EndFullGC:   return "EndFullGC";
-    default:          ShouldNotReachHere();
-  }
-  // trying to keep the Windows compiler happy
-  return NULL;
-}
-
-#define G1HR_PREFIX     " G1HR"
-
-void G1HRPrinter::print(ActionType action, RegionType type,
-                        HeapRegion* hr, HeapWord* top) {
-  const char* action_str = action_name(action);
-  const char* type_str   = region_type_name(type);
-  HeapWord* bottom = hr->bottom();
-
-  if (type_str != NULL) {
-    if (top != NULL) {
-      gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT " " PTR_FORMAT,
-                             action_str, type_str, p2i(bottom), p2i(top));
-    } else {
-      gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT,
-                             action_str, type_str, p2i(bottom));
-    }
-  } else {
-    if (top != NULL) {
-      gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT " " PTR_FORMAT,
-                             action_str, p2i(bottom), p2i(top));
-    } else {
-      gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT,
-                             action_str, p2i(bottom));
-    }
-  }
-}
-
-void G1HRPrinter::print(ActionType action, HeapWord* bottom, HeapWord* end) {
-  const char* action_str = action_name(action);
-
-  gclog_or_tty->print_cr(G1HR_PREFIX " %s [" PTR_FORMAT "," PTR_FORMAT "]",
-                         action_str, p2i(bottom), p2i(end));
-}
-
-void G1HRPrinter::print(PhaseType phase, size_t phase_num) {
-  const char* phase_str = phase_name(phase);
-  gclog_or_tty->print_cr(G1HR_PREFIX " #%s " SIZE_FORMAT, phase_str, phase_num);
-}
--- a/hotspot/src/share/vm/gc/g1/g1HRPrinter.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1HRPrinter.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,157 +26,84 @@
 #define SHARE_VM_GC_G1_G1HRPRINTER_HPP
 
 #include "gc/g1/heapRegion.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 
 #define SKIP_RETIRED_FULL_REGIONS 1
 
 class G1HRPrinter VALUE_OBJ_CLASS_SPEC {
-public:
-  typedef enum {
-    Alloc,
-    AllocForce,
-    Retire,
-    Reuse,
-    CSet,
-    EvacFailure,
-    Cleanup,
-    PostCompaction,
-    Commit,
-    Uncommit
-  } ActionType;
-
-  typedef enum {
-    Unset,
-    Eden,
-    Survivor,
-    Old,
-    StartsHumongous,
-    ContinuesHumongous,
-    Archive
-  } RegionType;
-
-  typedef enum {
-    StartGC,
-    EndGC,
-    StartFullGC,
-    EndFullGC
-  } PhaseType;
 
 private:
-  bool _active;
 
-  static const char* action_name(ActionType action);
-  static const char* region_type_name(RegionType type);
-  static const char* phase_name(PhaseType phase);
-
-  // Print an action event. This version is used in most scenarios and
-  // only prints the region's bottom. The parameters type and top are
-  // optional (the "not set" values are Unset and NULL).
-  static void print(ActionType action, RegionType type,
-                    HeapRegion* hr, HeapWord* top);
-
-  // Print an action event. This version prints both the region's
-  // bottom and end. Used for Commit / Uncommit events.
-  static void print(ActionType action, HeapWord* bottom, HeapWord* end);
-
-  // Print a phase event.
-  static void print(PhaseType phase, size_t phase_num);
+  // Print an action event.
+  static void print(const char* action, HeapRegion* hr) {
+    log_trace(gc, region)("G1HR %s(%s) [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]",
+                          action, hr->get_type_str(), p2i(hr->bottom()), p2i(hr->top()), p2i(hr->end()));
+  }
 
 public:
   // In some places we iterate over a list in order to generate output
   // for the list's elements. By exposing this we can avoid this
   // iteration if the printer is not active.
-  const bool is_active() { return _active; }
+  const bool is_active() { return log_is_enabled(Trace, gc, region); }
 
-  // Have to set this explicitly as we have to do this during the
-  // heap's initialize() method, not in the constructor.
-  void set_active(bool active) { _active = active; }
-
-  // The methods below are convenient wrappers for the print() methods.
+  // The methods below are convenient wrappers for the print() method.
 
-  void alloc(HeapRegion* hr, RegionType type, bool force = false) {
+  void alloc(HeapRegion* hr, bool force = false) {
     if (is_active()) {
-      print((!force) ? Alloc : AllocForce, type, hr, NULL);
-    }
-  }
-
-  void alloc(RegionType type, HeapRegion* hr, HeapWord* top) {
-    if (is_active()) {
-      print(Alloc, type, hr, top);
+      print((force) ? "ALLOC-FORCE" : "ALLOC", hr);
     }
   }
 
   void retire(HeapRegion* hr) {
     if (is_active()) {
       if (!SKIP_RETIRED_FULL_REGIONS || hr->top() < hr->end()) {
-        print(Retire, Unset, hr, hr->top());
+        print("RETIRE", hr);
       }
     }
   }
 
   void reuse(HeapRegion* hr) {
     if (is_active()) {
-      print(Reuse, Unset, hr, NULL);
+      print("REUSE", hr);
     }
   }
 
   void cset(HeapRegion* hr) {
     if (is_active()) {
-      print(CSet, Unset, hr, NULL);
+      print("CSET", hr);
     }
   }
 
   void evac_failure(HeapRegion* hr) {
     if (is_active()) {
-      print(EvacFailure, Unset, hr, NULL);
+      print("EVAC-FAILURE", hr);
     }
   }
 
   void cleanup(HeapRegion* hr) {
     if (is_active()) {
-      print(Cleanup, Unset, hr, NULL);
-    }
-  }
-
-  void post_compaction(HeapRegion* hr, RegionType type) {
-    if (is_active()) {
-      print(PostCompaction, type, hr, hr->top());
+      print("CLEANUP", hr);
     }
   }
 
-  void commit(HeapWord* bottom, HeapWord* end) {
+  void post_compaction(HeapRegion* hr) {
     if (is_active()) {
-      print(Commit, bottom, end);
-    }
-  }
-
-  void uncommit(HeapWord* bottom, HeapWord* end) {
-    if (is_active()) {
-      print(Uncommit, bottom, end);
+      print("POST-COMPACTION", hr);
     }
   }
 
-  void start_gc(bool full, size_t gc_num) {
+  void commit(HeapRegion* hr) {
     if (is_active()) {
-      if (!full) {
-        print(StartGC, gc_num);
-      } else {
-        print(StartFullGC, gc_num);
-      }
+      print("COMMIT", hr);
     }
   }
 
-  void end_gc(bool full, size_t gc_num) {
+  void uncommit(HeapRegion* hr) {
     if (is_active()) {
-      if (!full) {
-        print(EndGC, gc_num);
-      } else {
-        print(EndFullGC, gc_num);
-      }
+      print("UNCOMMIT", hr);
     }
   }
-
-  G1HRPrinter() : _active(false) { }
 };
 
 #endif // SHARE_VM_GC_G1_G1HRPRINTER_HPP
--- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -24,10 +24,10 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1ErgoVerbose.hpp"
 #include "gc/g1/g1IHOPControl.hpp"
 #include "gc/g1/g1Predictions.hpp"
 #include "gc/shared/gcTrace.hpp"
+#include "logging/log.hpp"
 
 G1IHOPControl::G1IHOPControl(double initial_ihop_percent, size_t target_occupancy) :
   _initial_ihop_percent(initial_ihop_percent),
@@ -47,20 +47,14 @@
 
 void G1IHOPControl::print() {
   size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold();
-  ergo_verbose6(ErgoIHOP,
-                "basic information",
-                ergo_format_reason("value update")
-                ergo_format_byte_perc("threshold")
-                ergo_format_byte("target occupancy")
-                ergo_format_byte("current occupancy")
-                ergo_format_double("recent old gen allocation rate")
-                ergo_format_double("recent marking phase length"),
-                cur_conc_mark_start_threshold,
-                cur_conc_mark_start_threshold * 100.0 / _target_occupancy,
-                _target_occupancy,
-                G1CollectedHeap::heap()->used(),
-                _last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
-                last_marking_length_s());
+  log_debug(gc, ihop)("Basic information (value update), threshold: " SIZE_FORMAT "B (%1.2f), target occupancy: " SIZE_FORMAT "B, current occupancy: " SIZE_FORMAT "B,"
+                      " recent old gen allocation rate: %1.2f, recent marking phase length: %1.2f",
+                      cur_conc_mark_start_threshold,
+                      cur_conc_mark_start_threshold * 100.0 / _target_occupancy,
+                      _target_occupancy,
+                      G1CollectedHeap::heap()->used(),
+                      _last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
+                      last_marking_length_s());
 }
 
 void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
@@ -192,21 +186,14 @@
 void G1AdaptiveIHOPControl::print() {
   G1IHOPControl::print();
   size_t actual_target = actual_target_threshold();
-  ergo_verbose6(ErgoIHOP,
-                "adaptive IHOP information",
-                ergo_format_reason("value update")
-                ergo_format_byte_perc("threshold")
-                ergo_format_byte("internal target occupancy")
-                ergo_format_double("predicted old gen allocation rate")
-                ergo_format_double("predicted marking phase length")
-                ergo_format_str("prediction active"),
-                get_conc_mark_start_threshold(),
-                percent_of(get_conc_mark_start_threshold(), actual_target),
-                actual_target,
-                _predictor->get_new_prediction(&_allocation_rate_s),
-                _predictor->get_new_prediction(&_marking_times_s),
-                have_enough_data_for_prediction() ? "true" : "false"
-                );
+  log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: " SIZE_FORMAT "B (%1.2f), internal target occupancy: " SIZE_FORMAT "B,"
+                      " predicted old gen allocation rate: %1.2f, predicted marking phase length: %1.2f, prediction active: %s",
+                      get_conc_mark_start_threshold(),
+                      percent_of(get_conc_mark_start_threshold(), actual_target),
+                      actual_target,
+                      _predictor->get_new_prediction(&_allocation_rate_s),
+                      _predictor->get_new_prediction(&_marking_times_s),
+                      have_enough_data_for_prediction() ? "true" : "false");
 }
 
 void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) {
--- a/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1InCSetState.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -53,8 +53,12 @@
     // frequency of the checks.
     // The most common check is whether the region is in the collection set or not,
     // this encoding allows us to use an > 0 check.
-    // The other values are simply encoded in increasing generation order, which
-    // makes getting the next generation fast by a simple increment.
+    // The positive values are encoded in increasing generation order, which
+    // makes getting the next generation fast by a simple increment. They are also
+    // used to index into arrays.
+    // The negative values are used for objects requiring various special cases,
+    // for example eager reclamation of humongous objects.
+    Ext          = -2,    // Extension point
     Humongous    = -1,    // The region is humongous
     NotInCSet    =  0,    // The region is not in the collection set.
     Young        =  1,    // The region is in the collection set and a young region.
@@ -76,10 +80,11 @@
   bool is_humongous() const            { return _value == Humongous; }
   bool is_young() const                { return _value == Young; }
   bool is_old() const                  { return _value == Old; }
+  bool is_ext() const                  { return _value == Ext; }
 
 #ifdef ASSERT
-  bool is_default() const              { return !is_in_cset_or_humongous(); }
-  bool is_valid() const                { return (_value >= Humongous) && (_value < Num); }
+  bool is_default() const              { return _value == NotInCSet; }
+  bool is_valid() const                { return (_value >= Ext) && (_value < Num); }
   bool is_valid_gen() const            { return (_value >= Young && _value <= Old); }
 #endif
 };
@@ -105,6 +110,12 @@
     set_by_index(index, InCSetState::Humongous);
   }
 
+  void set_ext(uintptr_t index) {
+    assert(get_by_index(index).is_default(),
+           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
+    set_by_index(index, InCSetState::Ext);
+  }
+
   void clear_humongous(uintptr_t index) {
     set_by_index(index, InCSetState::NotInCSet);
   }
--- a/hotspot/src/share/vm/gc/g1/g1Log.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2012, 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/g1Log.hpp"
-#include "gc/g1/g1_globals.hpp"
-#include "runtime/globals_extension.hpp"
-
-G1Log::LogLevel G1Log::_level = G1Log::LevelNone;
-
-
-// Updates _level based on PrintGC and PrintGCDetails values (unless
-// G1LogLevel is set explicitly)
-// - PrintGC maps to "fine".
-// - PrintGCDetails maps to "finer".
-void G1Log::update_level() {
-  if (FLAG_IS_DEFAULT(G1LogLevel)) {
-    _level = LevelNone;
-    if (PrintGCDetails) {
-      _level = LevelFiner;
-    } else if (PrintGC) {
-      _level = LevelFine;
-    }
-  }
-}
-
-
-// If G1LogLevel has not been set up we will use the values of PrintGC
-// and PrintGCDetails for the logging level.
-void G1Log::init() {
-  if (!FLAG_IS_DEFAULT(G1LogLevel)) {
-    // PrintGC flags change won't have any affect, because G1LogLevel
-    // is set explicitly
-    if (G1LogLevel[0] == '\0' || strncmp("none", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
-      _level = LevelNone;
-    } else if (strncmp("fine", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
-      _level = LevelFine;
-    } else if (strncmp("finer", G1LogLevel, 5) == 0 && G1LogLevel[5] == '\0') {
-      _level = LevelFiner;
-    } else if (strncmp("finest", G1LogLevel, 6) == 0 && G1LogLevel[6] == '\0') {
-      _level = LevelFinest;
-    } else {
-      warning("Unknown logging level '%s', should be one of 'fine', 'finer' or 'finest'.", G1LogLevel);
-    }
-  } else {
-    update_level();
-  }
-}
-
--- a/hotspot/src/share/vm/gc/g1/g1Log.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_G1LOG_HPP
-#define SHARE_VM_GC_G1_G1LOG_HPP
-
-#include "memory/allocation.hpp"
-
-class G1Log : public AllStatic {
- public:
-  typedef enum {
-    LevelNone,
-    LevelFine,
-    LevelFiner,
-    LevelFinest
-  } LogLevel;
-
- private:
-  static LogLevel _level;
-
- public:
-  inline static bool fine() {
-    return _level >= LevelFine;
-  }
-
-  inline static bool finer() {
-    return _level >= LevelFiner;
-  }
-
-  inline static bool finest() {
-    return _level == LevelFinest;
-  }
-
-  static LogLevel level() {
-    return _level;
-  }
-
-  static void init();
-
-  // Update to log level to reflect runtime changes to manageable flags
-  static void update_level();
-};
-
-#endif // SHARE_VM_GC_G1_G1LOG_HPP
--- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,7 +29,6 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1MarkSweep.hpp"
 #include "gc/g1/g1RootProcessor.hpp"
 #include "gc/g1/g1StringDedup.hpp"
@@ -38,7 +37,7 @@
 #include "gc/shared/gcLocker.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/modRefBarrierSet.hpp"
 #include "gc/shared/referencePolicy.hpp"
@@ -123,7 +122,7 @@
 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer());
+  GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", gc_timer());
 
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
@@ -183,13 +182,8 @@
     // fail. At the end of the GC, the original mark word values
     // (including hash values) are restored to the appropriate
     // objects.
-    if (!VerifySilently) {
-      gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying ");
-    }
-    g1h->verify(VerifySilently, VerifyOption_G1UseMarkWord);
-    if (!VerifySilently) {
-      gclog_or_tty->print_cr("]");
-    }
+    GCTraceTime(Info, gc, verify)("During GC (full)");
+    g1h->verify(VerifyOption_G1UseMarkWord);
   }
 
   gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
@@ -203,7 +197,7 @@
   // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
   // tracking expects us to do so. See comment under phase4.
 
-  GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer());
+  GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", gc_timer());
 
   prepare_compaction();
 }
@@ -236,7 +230,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer());
+  GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", gc_timer());
 
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -297,7 +291,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-  GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer());
+  GCTraceTime(Trace, gc) tm("Phase 4: Move objects", gc_timer());
 
   G1SpaceCompactClosure blk;
   g1h->heap_region_iterate(&blk);
@@ -335,7 +329,7 @@
   FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
 
   hr->set_containing_set(NULL);
-  _humongous_regions_removed.increment(1u, hr->capacity());
+  _humongous_regions_removed++;
 
   _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */);
   prepare_for_compaction(hr, end);
@@ -364,8 +358,7 @@
 void G1PrepareCompactClosure::update_sets() {
   // We'll recalculate total used bytes and recreate the free list
   // at the end of the GC, so no point in updating those values here.
-  HeapRegionSetCount empty_set;
-  _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed);
+  _g1h->remove_from_old_sets(0, _humongous_regions_removed);
 }
 
 bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -92,7 +92,7 @@
   G1CollectedHeap* _g1h;
   ModRefBarrierSet* _mrbs;
   CompactPoint _cp;
-  HeapRegionSetCount _humongous_regions_removed;
+  uint _humongous_regions_removed;
 
   virtual void prepare_for_compaction(HeapRegion* hr, HeapWord* end);
   void prepare_for_compaction_work(CompactPoint* cp, HeapRegion* hr, HeapWord* end);
@@ -103,7 +103,7 @@
   G1PrepareCompactClosure() :
     _g1h(G1CollectedHeap::heap()),
     _mrbs(_g1h->g1_barrier_set()),
-    _humongous_regions_removed() { }
+    _humongous_regions_removed(0) { }
 
   void update_sets();
   bool doHeapRegion(HeapRegion* hr);
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,7 +31,8 @@
 #include "utilities/stack.inline.hpp"
 
 G1ParCopyHelper::G1ParCopyHelper(G1CollectedHeap* g1,  G1ParScanThreadState* par_scan_state) :
-  G1ParClosureSuper(g1, par_scan_state),
+  _g1(g1),
+  _par_scan_state(par_scan_state),
   _worker_id(par_scan_state->worker_id()),
   _scanned_klass(NULL),
   _cm(_g1->concurrent_mark())
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -86,8 +86,10 @@
 };
 
 // Add back base class for metadata
-class G1ParCopyHelper : public G1ParClosureSuper {
+class G1ParCopyHelper : public OopClosure {
 protected:
+  G1CollectedHeap* _g1;
+  G1ParScanThreadState* _par_scan_state;
   uint _worker_id;              // Cache value from par_scan_state.
   Klass* _scanned_klass;
   ConcurrentMark* _cm;
@@ -121,17 +123,15 @@
   G1MarkPromotedFromRoot
 };
 
-template <G1Barrier barrier, G1Mark do_mark_object>
+template <G1Barrier barrier, G1Mark do_mark_object, bool use_ext>
 class G1ParCopyClosure : public G1ParCopyHelper {
 public:
   G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
-      G1ParCopyHelper(g1, par_scan_state) {
-    assert(ref_processor() == NULL, "sanity");
-  }
+      G1ParCopyHelper(g1, par_scan_state) { }
 
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(oop* p)       { do_oop_nv(p); }
-  virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(oop* p)       { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 };
 
 class G1KlassScanClosure : public KlassClosure {
@@ -144,20 +144,15 @@
   void do_klass(Klass* klass);
 };
 
-class FilterIntoCSClosure: public ExtendedOopClosure {
+class FilterIntoCSClosure: public OopClosure {
   G1CollectedHeap* _g1;
   OopClosure* _oc;
-  DirtyCardToOopClosure* _dcto_cl;
 public:
-  FilterIntoCSClosure(  DirtyCardToOopClosure* dcto_cl,
-                        G1CollectedHeap* g1,
-                        OopClosure* oc) :
-    _dcto_cl(dcto_cl), _g1(g1), _oc(oc) { }
+  FilterIntoCSClosure(G1CollectedHeap* g1, OopClosure* oc) : _g1(g1), _oc(oc) { }
 
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(oop* p)        { do_oop_nv(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
-  bool apply_to_weak_ref_discovered_field() { return true; }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(oop* p)        { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
 };
 
 class FilterOutOfRegionClosure: public ExtendedOopClosure {
@@ -206,43 +201,43 @@
 // during an evacuation pause) to record cards containing
 // pointers into the collection set.
 
-class G1Mux2Closure : public ExtendedOopClosure {
+class G1Mux2Closure : public OopClosure {
   OopClosure* _c1;
   OopClosure* _c2;
 public:
   G1Mux2Closure(OopClosure *c1, OopClosure *c2);
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(oop* p)        { do_oop_nv(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(oop* p)        { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
 };
 
 // A closure that returns true if it is actually applied
 // to a reference
 
-class G1TriggerClosure : public ExtendedOopClosure {
+class G1TriggerClosure : public OopClosure {
   bool _triggered;
 public:
   G1TriggerClosure();
   bool triggered() const { return _triggered; }
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(oop* p)        { do_oop_nv(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(oop* p)        { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
 };
 
 // A closure which uses a triggering closure to determine
 // whether to apply an oop closure.
 
-class G1InvokeIfNotTriggeredClosure: public ExtendedOopClosure {
+class G1InvokeIfNotTriggeredClosure: public OopClosure {
   G1TriggerClosure* _trigger_cl;
   OopClosure* _oop_cl;
 public:
   G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t, OopClosure* oc);
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(oop* p)        { do_oop_nv(p); }
-  virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(oop* p)        { do_oop_work(p); }
+  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
 };
 
-class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure {
+class G1UpdateRSOrPushRefOopClosure: public OopClosure {
   G1CollectedHeap* _g1;
   G1RemSet* _g1_rem_set;
   HeapRegion* _from;
@@ -268,11 +263,9 @@
     return result;
   }
 
-  bool apply_to_weak_ref_discovered_field() { return true; }
-
-  template <class T> void do_oop_nv(T* p);
-  virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
-  virtual void do_oop(oop* p)       { do_oop_nv(p); }
+  template <class T> void do_oop_work(T* p);
+  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+  virtual void do_oop(oop* p)       { do_oop_work(p); }
 };
 
 #endif // SHARE_VM_GC_G1_G1OOPCLOSURES_HPP
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -42,7 +42,7 @@
  */
 
 template <class T>
-inline void FilterIntoCSClosure::do_oop_nv(T* p) {
+inline void FilterIntoCSClosure::do_oop_work(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop) &&
       _g1->is_in_cset_or_humongous(oopDesc::decode_heap_oop_not_null(heap_oop))) {
@@ -90,6 +90,8 @@
     } else {
       if (state.is_humongous()) {
         _g1->set_humongous_is_live(obj);
+      } else if (state.is_ext()) {
+        _par_scan_state->do_oop_ext(p);
       }
       _par_scan_state->update_rs(_from, p, obj);
     }
@@ -102,12 +104,15 @@
 
   if (!oopDesc::is_null(heap_oop)) {
     oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (_g1->is_in_cset_or_humongous(obj)) {
+    const InCSetState state = _g1->in_cset_state(obj);
+    if (state.is_in_cset_or_humongous()) {
       Prefetch::write(obj->mark_addr(), 0);
       Prefetch::read(obj->mark_addr(), (HeapWordSize*2));
 
       // Place on the references queue
       _par_scan_state->push_on_queue(p);
+    } else if (state.is_ext()) {
+      _par_scan_state->do_oop_ext(p);
     } else {
       assert(!_g1->obj_in_cs(obj), "checking");
     }
@@ -131,27 +136,27 @@
 }
 
 template <class T>
-inline void G1Mux2Closure::do_oop_nv(T* p) {
+inline void G1Mux2Closure::do_oop_work(T* p) {
   // Apply first closure; then apply the second.
   _c1->do_oop(p);
   _c2->do_oop(p);
 }
 
 template <class T>
-inline void G1TriggerClosure::do_oop_nv(T* p) {
+inline void G1TriggerClosure::do_oop_work(T* p) {
   // Record that this closure was actually applied (triggered).
   _triggered = true;
 }
 
 template <class T>
-inline void G1InvokeIfNotTriggeredClosure::do_oop_nv(T* p) {
+inline void G1InvokeIfNotTriggeredClosure::do_oop_work(T* p) {
   if (!_trigger_cl->triggered()) {
     _oop_cl->do_oop(p);
   }
 }
 
 template <class T>
-inline void G1UpdateRSOrPushRefOopClosure::do_oop_nv(T* p) {
+inline void G1UpdateRSOrPushRefOopClosure::do_oop_work(T* p) {
   oop obj = oopDesc::load_decode_heap_oop(p);
   if (obj == NULL) {
     return;
@@ -249,9 +254,9 @@
   _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
 }
 
-template <G1Barrier barrier, G1Mark do_mark_object>
+template <G1Barrier barrier, G1Mark do_mark_object, bool use_ext>
 template <class T>
-void G1ParCopyClosure<barrier, do_mark_object>::do_oop_nv(T* p) {
+void G1ParCopyClosure<barrier, do_mark_object, use_ext>::do_oop_work(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
 
   if (oopDesc::is_null(heap_oop)) {
@@ -286,6 +291,10 @@
     if (state.is_humongous()) {
       _g1->set_humongous_is_live(obj);
     }
+
+    if (use_ext && state.is_ext()) {
+      _par_scan_state->do_oop_ext(p);
+    }
     // The object is not in collection set. If we're a root scanning
     // closure during an initial mark pause then attempt to mark the object.
     if (do_mark_object == G1MarkFromRoot) {
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -96,6 +96,7 @@
   bool verify_task(StarTask ref) const;
 #endif // ASSERT
 
+  template <class T> void do_oop_ext(T* ref);
   template <class T> void push_on_queue(T* ref);
 
   template <class T> void update_rs(HeapRegion* from, T* p, oop o) {
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -50,8 +50,8 @@
   } else if (in_cset_state.is_humongous()) {
     _g1h->set_humongous_is_live(obj);
   } else {
-    assert(!in_cset_state.is_in_cset_or_humongous(),
-           "In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value());
+    assert(in_cset_state.is_default() || in_cset_state.is_ext(),
+           "In_cset_state must be NotInCSet or Ext here, but is " CSETSTATE_FORMAT, in_cset_state.value());
   }
 
   assert(obj != NULL, "Must be");
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState_ext.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState_ext.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,3 +29,10 @@
 G1ParScanThreadState* G1ParScanThreadStateSet::new_par_scan_state(uint worker_id, size_t young_cset_length) {
   return new G1ParScanThreadState(_g1h, worker_id, young_cset_length);
 }
+
+template <typename T>
+void G1ParScanThreadState::do_oop_ext(T* ref) {
+}
+
+template void G1ParScanThreadState::do_oop_ext<oop>(oop* ref);
+template void G1ParScanThreadState::do_oop_ext<narrowOop>(narrowOop* ref);
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -52,7 +52,7 @@
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
   }
-  if (G1SummarizeRSetStats) {
+  if (log_is_enabled(Trace, gc, remset)) {
     _prev_period_summary.initialize(this);
   }
   // Initialize the card queue set used to hold cards containing
@@ -109,17 +109,6 @@
   }
 }
 
-void ScanRSClosure::printCard(HeapRegion* card_region, size_t card_index,
-    HeapWord* card_start) {
-  gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") "
-      "RS names card " SIZE_FORMAT_HEX ": "
-      "[" PTR_FORMAT ", " PTR_FORMAT ")",
-      _worker_i,
-      p2i(card_region->bottom()), p2i(card_region->end()),
-      card_index,
-      p2i(card_start), p2i(card_start + G1BlockOffsetSharedArray::N_words));
-}
-
 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
   double scan_start = os::elapsedTime();
   r->strong_code_roots_do(_code_root_cl);
@@ -152,10 +141,6 @@
     }
     if (current_card < jump_to_card) continue;
     HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
-#if 0
-    gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
-        card_start, card_start + CardTableModRefBS::card_size_in_words);
-#endif
 
     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
     _cards++;
@@ -463,7 +448,7 @@
   update_rs_oop_cl.set_from(r);
 
   G1TriggerClosure trigger_cl;
-  FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl);
+  FilterIntoCSClosure into_cs_cl(_g1, &trigger_cl);
   G1InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
   G1Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
 
@@ -526,31 +511,36 @@
   return has_refs_into_cset;
 }
 
-void G1RemSet::print_periodic_summary_info(const char* header) {
-  G1RemSetSummary current;
-  current.initialize(this);
+void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
+  if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
+      (period_count % G1SummarizeRSetStatsPeriod == 0)) {
+
+    if (!_prev_period_summary.initialized()) {
+      _prev_period_summary.initialize(this);
+    }
 
-  _prev_period_summary.subtract_from(&current);
-  print_summary_info(&_prev_period_summary, header);
+    G1RemSetSummary current;
+    current.initialize(this);
+    _prev_period_summary.subtract_from(&current);
 
-  _prev_period_summary.set(&current);
+    LogHandle(gc, remset) log;
+    log.trace("%s", header);
+    ResourceMark rm;
+    _prev_period_summary.print_on(log.trace_stream());
+
+    _prev_period_summary.set(&current);
+  }
 }
 
 void G1RemSet::print_summary_info() {
-  G1RemSetSummary current;
-  current.initialize(this);
-
-  print_summary_info(&current, " Cumulative RS summary");
-}
-
-void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
-  assert(summary != NULL, "just checking");
-
-  if (header != NULL) {
-    gclog_or_tty->print_cr("%s", header);
+  LogHandle(gc, remset, exit) log;
+  if (log.is_trace()) {
+    log.trace(" Cumulative RS summary");
+    G1RemSetSummary current;
+    current.initialize(this);
+    ResourceMark rm;
+    current.print_on(log.trace_stream());
   }
-
-  summary->print_on(gclog_or_tty);
 }
 
 void G1RemSet::prepare_for_verify() {
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -33,6 +33,7 @@
 class G1CollectedHeap;
 class ConcurrentG1Refine;
 class G1ParPushHeapRSClosure;
+class outputStream;
 
 // A G1RemSet in which each heap region has a rem set that records the
 // external heap references into it.  Uses a mod ref bs to track updates,
@@ -63,8 +64,6 @@
   // references into the collection set.
   G1ParPushHeapRSClosure** _cset_rs_update_cl;
 
-  // Print the given summary info
-  virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
 public:
   // This is called to reset dual hash tables after the gc pause
   // is finished and the initial hash table is no longer being
@@ -135,7 +134,7 @@
   virtual void print_summary_info();
 
   // Print accumulated summary info from the last time called.
-  virtual void print_periodic_summary_info(const char* header);
+  virtual void print_periodic_summary_info(const char* header, uint period_count);
 
   // Prepare remembered set for verification.
   virtual void prepare_for_verify();
@@ -199,10 +198,6 @@
 
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   virtual void do_oop(oop* p)       { do_oop_work(p); }
-
-  // Override: this closure is idempotent.
-  //  bool idempotent() { return true; }
-  bool apply_to_weak_ref_discovered_field() { return true; }
 };
 
 #endif // SHARE_VM_GC_G1_G1REMSET_HPP
--- a/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSetSummary.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -271,7 +271,7 @@
   void print_summary_on(outputStream* out) {
     RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
 
-    out->print_cr("\n Current rem set statistics");
+    out->print_cr(" Current rem set statistics");
     out->print_cr("  Total per region rem sets sizes = " SIZE_FORMAT "K."
                   " Max = " SIZE_FORMAT "K.",
                   round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
@@ -323,7 +323,7 @@
 };
 
 void G1RemSetSummary::print_on(outputStream* out) {
-  out->print_cr("\n Recent concurrent refinement statistics");
+  out->print_cr(" Recent concurrent refinement statistics");
   out->print_cr("  Processed " SIZE_FORMAT " cards",
                 num_concurrent_refined_cards());
   out->print_cr("  Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total());
--- a/hotspot/src/share/vm/gc/g1/g1RemSetSummary.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSetSummary.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -85,6 +85,7 @@
 
   // initialize and get the first sampling
   void initialize(G1RemSet* remset);
+  bool const initialized() { return _rs_threads_vtimes != NULL; }
 
   void print_on(outputStream* out);
 
--- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/satbMarkQueue.hpp"
 #include "gc/shared/memset_with_concurrent_readers.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -147,17 +148,10 @@
   assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
   assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
 
-  if (TraceCardTableModRefBS) {
-    gclog_or_tty->print_cr("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: ");
-    gclog_or_tty->print_cr("  "
-                  "  &_byte_map[0]: " INTPTR_FORMAT
-                  "  &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
-                  p2i(&_byte_map[0]),
-                  p2i(&_byte_map[_last_valid_index]));
-    gclog_or_tty->print_cr("  "
-                  "  byte_map_base: " INTPTR_FORMAT,
-                  p2i(byte_map_base));
-  }
+  log_trace(gc, barrier)("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: ");
+  log_trace(gc, barrier)("    &_byte_map[0]: " INTPTR_FORMAT "  &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
+                         p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
+  log_trace(gc, barrier)("    byte_map_base: " INTPTR_FORMAT,  p2i(byte_map_base));
 }
 
 void
--- a/hotspot/src/share/vm/gc/g1/g1SharedClosures.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1SharedClosures.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,15 +31,15 @@
 class G1ParScanThreadState;
 
 // Simple holder object for a complete set of closures used by the G1 evacuation code.
-template <G1Mark Mark>
+template <G1Mark Mark, bool use_ext = false>
 class G1SharedClosures VALUE_OBJ_CLASS_SPEC {
 public:
-  G1ParCopyClosure<G1BarrierNone,  Mark> _oops;
-  G1ParCopyClosure<G1BarrierKlass, Mark> _oop_in_klass;
-  G1KlassScanClosure                     _klass_in_cld_closure;
-  CLDToKlassAndOopClosure                _clds;
-  G1CodeBlobClosure                      _codeblobs;
-  BufferingOopClosure                    _buffered_oops;
+  G1ParCopyClosure<G1BarrierNone,  Mark, use_ext> _oops;
+  G1ParCopyClosure<G1BarrierKlass, Mark, use_ext> _oop_in_klass;
+  G1KlassScanClosure                              _klass_in_cld_closure;
+  CLDToKlassAndOopClosure                         _clds;
+  G1CodeBlobClosure                               _codeblobs;
+  BufferingOopClosure                             _buffered_oops;
 
   G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty_klasses, bool must_claim_cld) :
     _oops(g1h, pss),
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/g1StringDedupQueue.hpp"
 #include "gc/shared/gcLocker.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -152,10 +153,9 @@
   }
 }
 
-void G1StringDedupQueue::print_statistics(outputStream* st) {
-  st->print_cr(
-    "   [Queue]\n"
-    "      [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
+void G1StringDedupQueue::print_statistics() {
+  log_debug(gc, stringdedup)("   [Queue]");
+  log_debug(gc, stringdedup)("      [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
 }
 
 void G1StringDedupQueue::verify() {
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -94,7 +94,7 @@
 
   static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl);
 
-  static void print_statistics(outputStream* st);
+  static void print_statistics();
   static void verify();
 };
 
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupStat.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1StringDedupStat.hpp"
+#include "logging/log.hpp"
 
 G1StringDedupStat::G1StringDedupStat() :
   _inspected(0),
@@ -68,7 +69,7 @@
   _block_elapsed       += stat._block_elapsed;
 }
 
-void G1StringDedupStat::print_summary(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
+void G1StringDedupStat::print_summary(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
   double total_deduped_bytes_percent = 0.0;
 
   if (total_stat._new_bytes > 0) {
@@ -76,10 +77,8 @@
     total_deduped_bytes_percent = (double)total_stat._deduped_bytes / (double)total_stat._new_bytes * 100.0;
   }
 
-  st->date_stamp(PrintGCDateStamps);
-  st->stamp(PrintGCTimeStamps);
-  st->print_cr(
-    "[GC concurrent-string-deduplication, "
+  log_info(gc, stringdedup)(
+    "Concurrent String Deduplication "
     G1_STRDEDUP_BYTES_FORMAT_NS "->" G1_STRDEDUP_BYTES_FORMAT_NS "(" G1_STRDEDUP_BYTES_FORMAT_NS "), avg "
     G1_STRDEDUP_PERCENT_FORMAT_NS ", " G1_STRDEDUP_TIME_FORMAT "]",
     G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes),
@@ -89,7 +88,7 @@
     last_stat._exec_elapsed);
 }
 
-void G1StringDedupStat::print_statistics(outputStream* st, const G1StringDedupStat& stat, bool total) {
+void G1StringDedupStat::print_statistics(const G1StringDedupStat& stat, bool total) {
   double young_percent               = 0.0;
   double old_percent                 = 0.0;
   double skipped_percent             = 0.0;
@@ -134,29 +133,24 @@
   }
 
   if (total) {
-    st->print_cr(
+    log_debug(gc, stringdedup)(
       "   [Total Exec: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Idle: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
       stat._exec, stat._exec_elapsed, stat._idle, stat._idle_elapsed, stat._block, stat._block_elapsed);
   } else {
-    st->print_cr(
+    log_debug(gc, stringdedup)(
       "   [Last Exec: " G1_STRDEDUP_TIME_FORMAT ", Idle: " G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
       stat._exec_elapsed, stat._idle_elapsed, stat._block, stat._block_elapsed);
   }
-  st->print_cr(
-    "      [Inspected:    " G1_STRDEDUP_OBJECTS_FORMAT "]\n"
-    "         [Skipped:   " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
-    "         [Hashed:    " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
-    "         [Known:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
-    "         [New:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]\n"
-    "      [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
-    "         [Young:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n"
-    "         [Old:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
-    stat._inspected,
-    stat._skipped, skipped_percent,
-    stat._hashed, hashed_percent,
-    stat._known, known_percent,
-    stat._new, new_percent, G1_STRDEDUP_BYTES_PARAM(stat._new_bytes),
-    stat._deduped, deduped_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_bytes), deduped_bytes_percent,
-    stat._deduped_young, deduped_young_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_young_bytes), deduped_young_bytes_percent,
-    stat._deduped_old, deduped_old_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_old_bytes), deduped_old_bytes_percent);
+  log_debug(gc, stringdedup)("      [Inspected:    " G1_STRDEDUP_OBJECTS_FORMAT "]", stat._inspected);
+  log_debug(gc, stringdedup)("         [Skipped:   " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._skipped, skipped_percent);
+  log_debug(gc, stringdedup)("         [Hashed:    " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._hashed, hashed_percent);
+  log_debug(gc, stringdedup)("         [Known:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._known, known_percent);
+  log_debug(gc, stringdedup)("         [New:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]",
+                             stat._new, new_percent, G1_STRDEDUP_BYTES_PARAM(stat._new_bytes));
+  log_debug(gc, stringdedup)("      [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
+                             stat._deduped, deduped_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_bytes), deduped_bytes_percent);
+  log_debug(gc, stringdedup)("         [Young:     " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
+                             stat._deduped_young, deduped_young_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_young_bytes), deduped_young_bytes_percent);
+  log_debug(gc, stringdedup)("         [Old:       " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
+                             stat._deduped_old, deduped_old_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_old_bytes), deduped_old_bytes_percent);
 }
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupStat.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupStat.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -135,8 +135,8 @@
 
   void add(const G1StringDedupStat& stat);
 
-  static void print_summary(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
-  static void print_statistics(outputStream* st, const G1StringDedupStat& stat, bool total);
+  static void print_summary(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
+  static void print_statistics(const G1StringDedupStat& stat, bool total);
 };
 
 #endif // SHARE_VM_GC_G1_G1STRINGDEDUPSTAT_HPP
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/g1StringDedupTable.hpp"
 #include "gc/shared/gcLocker.hpp"
+#include "logging/log.hpp"
 #include "memory/padded.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
@@ -568,19 +569,16 @@
   _entry_cache->trim(max_cache_size);
 }
 
-void G1StringDedupTable::print_statistics(outputStream* st) {
-  st->print_cr(
-    "   [Table]\n"
-    "      [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]\n"
-    "      [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n"
-    "      [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n"
-    "      [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n"
-    "      [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n"
-    "      [Age Threshold: " UINTX_FORMAT "]",
-    G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)),
-    _table->_size, _min_size, _max_size,
-    _table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed,
-    _resize_count, _table->_shrink_threshold, _shrink_load_factor * 100.0, _table->_grow_threshold, _grow_load_factor * 100.0,
-    _rehash_count, _rehash_threshold, _table->_hash_seed,
-    StringDeduplicationAgeThreshold);
+void G1StringDedupTable::print_statistics() {
+  LogHandle(gc, stringdedup) log;
+  log.debug("   [Table]");
+  log.debug("      [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]",
+            G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)));
+  log.debug("      [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]", _table->_size, _min_size, _max_size);
+  log.debug("      [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]",
+            _table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed);
+  log.debug("      [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]",
+            _resize_count, _table->_shrink_threshold, _shrink_load_factor * 100.0, _table->_grow_threshold, _grow_load_factor * 100.0);
+  log.debug("      [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]", _rehash_count, _rehash_threshold, _table->_hash_seed);
+  log.debug("      [Age Threshold: " UINTX_FORMAT "]", StringDeduplicationAgeThreshold);
 }
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -234,7 +234,7 @@
 
   static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl, uint worker_id);
 
-  static void print_statistics(outputStream* st);
+  static void print_statistics();
   static void verify();
 };
 
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -24,12 +24,12 @@
 
 #include "precompiled.hpp"
 #include "classfile/stringTable.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/g1StringDedupQueue.hpp"
 #include "gc/g1/g1StringDedupTable.hpp"
 #include "gc/g1/g1StringDedupThread.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 
@@ -129,7 +129,7 @@
 
       // Print statistics
       total_stat.add(stat);
-      print(gclog_or_tty, stat, total_stat);
+      print(stat, total_stat);
     }
   }
 
@@ -152,14 +152,14 @@
   }
 }
 
-void G1StringDedupThread::print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
-  if (G1Log::fine() || PrintStringDeduplicationStatistics) {
-    G1StringDedupStat::print_summary(st, last_stat, total_stat);
-    if (PrintStringDeduplicationStatistics) {
-      G1StringDedupStat::print_statistics(st, last_stat, false);
-      G1StringDedupStat::print_statistics(st, total_stat, true);
-      G1StringDedupTable::print_statistics(st);
-      G1StringDedupQueue::print_statistics(st);
+void G1StringDedupThread::print(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
+  if (log_is_enabled(Info, gc, stringdedup)) {
+    G1StringDedupStat::print_summary(last_stat, total_stat);
+    if (log_is_enabled(Debug, gc, stringdedup)) {
+      G1StringDedupStat::print_statistics(last_stat, false);
+      G1StringDedupStat::print_statistics(total_stat, true);
+      G1StringDedupTable::print_statistics();
+      G1StringDedupQueue::print_statistics();
     }
   }
 }
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupThread.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupThread.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -43,7 +43,7 @@
   G1StringDedupThread();
   ~G1StringDedupThread();
 
-  void print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
+  void print(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
 
 public:
   static void create();
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -53,32 +53,14 @@
           "Overhead of concurrent marking")                                 \
           range(0, 100)                                                     \
                                                                             \
-  develop(intx, G1MarkingVerboseLevel, 0,                                   \
-          "Level (0-4) of verboseness of the marking code")                 \
-          range(0, 4)                                                       \
-                                                                            \
-  develop(bool, G1TraceMarkStackOverflow, false,                            \
-          "If true, extra debugging code for CM restart for ovflw.")        \
-                                                                            \
-  diagnostic(bool, G1SummarizeConcMark, false,                              \
-          "Summarize concurrent mark info")                                 \
-                                                                            \
-  diagnostic(bool, G1SummarizeRSetStats, false,                             \
-          "Summarize remembered set processing info")                       \
-                                                                            \
   diagnostic(intx, G1SummarizeRSetStatsPeriod, 0,                           \
           "The period (in number of GCs) at which we will generate "        \
           "update buffer processing info "                                  \
           "(0 means do not periodically generate this info); "              \
-          "it also requires -XX:+G1SummarizeRSetStats")                     \
+          "it also requires that logging is enabled on the trace"           \
+          "level for gc+remset")                                            \
           range(0, max_intx)                                                \
                                                                             \
-  diagnostic(bool, G1TraceConcRefinement, false,                            \
-          "Trace G1 concurrent refinement")                                 \
-                                                                            \
-  experimental(bool, G1TraceStringSymbolTableScrubbing, false,              \
-          "Trace information string and symbol table scrubbing.")           \
-                                                                            \
   product(double, G1ConcMarkStepDurationMillis, 10.0,                       \
           "Target duration of individual concurrent marking steps "         \
           "in milliseconds.")                                               \
@@ -121,10 +103,6 @@
   develop(bool, G1RSBarrierRegionFilter, true,                              \
           "If true, generate region filtering code in RS barrier")          \
                                                                             \
-  diagnostic(bool, G1PrintRegionLivenessInfo, false,                        \
-            "Prints the liveness information for all regions in the heap "  \
-            "at the end of a marking cycle.")                               \
-                                                                            \
   product(size_t, G1UpdateBufferSize, 256,                                  \
           "Size of an update buffer")                                       \
           range(1, NOT_LP64(32*M) LP64_ONLY(1*G))                           \
@@ -205,12 +183,6 @@
   develop(bool, G1ScrubRemSets, true,                                       \
           "When true, do RS scrubbing after cleanup.")                      \
                                                                             \
-  develop(bool, G1RSScrubVerbose, false,                                    \
-          "When true, do RS scrubbing with verbose output.")                \
-                                                                            \
-  develop(bool, G1YoungSurvRateVerbose, false,                              \
-          "print out the survival rate of young regions according to age.") \
-                                                                            \
   develop(intx, G1YoungSurvRateNumRegionsSummary, 0,                        \
           "the number of regions for which we'll print a surv rate "        \
           "summary.")                                                       \
@@ -222,10 +194,6 @@
           "to minimize the probability of promotion failure.")              \
           range(0, 50)                                                      \
                                                                             \
-  diagnostic(bool, G1PrintHeapRegions, false,                               \
-          "If set G1 will print information on which regions are being "    \
-          "allocated and which are reclaimed.")                             \
-                                                                            \
   develop(bool, G1HRRSUseSparseTable, true,                                 \
           "When true, use sparse table to save space.")                     \
                                                                             \
@@ -254,9 +222,6 @@
           "The number of regions we will add to the secondary free list "   \
           "at every append operation")                                      \
                                                                             \
-  develop(bool, G1ConcRegionFreeingVerbose, false,                          \
-          "Enables verboseness during concurrent region freeing")           \
-                                                                            \
   develop(bool, G1StressConcRegionFreeing, false,                           \
           "It stresses the concurrent region freeing operation")            \
                                                                             \
@@ -310,18 +275,11 @@
           "Try to reclaim dead large objects that have a few stale "        \
           "references at every young GC.")                                  \
                                                                             \
-  experimental(bool, G1TraceEagerReclaimHumongousObjects, false,            \
-          "Print some information about large object liveness "             \
-          "at every young GC.")                                             \
-                                                                            \
   experimental(uintx, G1OldCSetRegionThresholdPercent, 10,                  \
           "An upper bound for the number of old CSet regions expressed "    \
           "as a percentage of the heap size.")                              \
           range(0, 100)                                                     \
                                                                             \
-  experimental(ccstr, G1LogLevel, NULL,                                     \
-          "Log level for G1 logging: fine, finer, finest")                  \
-                                                                            \
   notproduct(bool, G1EvacuationFailureALot, false,                          \
           "Force use of evacuation failure handling during certain "        \
           "evacuation pauses")                                              \
--- a/hotspot/src/share/vm/gc/g1/g1_specialized_oop_closures.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1_specialized_oop_closures.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,27 +35,15 @@
 class G1ParScanClosure;
 class G1ParPushHeapRSClosure;
 
-class FilterIntoCSClosure;
 class FilterOutOfRegionClosure;
 class G1CMOopClosure;
 class G1RootRegionScanClosure;
 
-// Specialized oop closures from g1RemSet.cpp
-class G1Mux2Closure;
-class G1TriggerClosure;
-class G1InvokeIfNotTriggeredClosure;
-class G1UpdateRSOrPushRefOopClosure;
-
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f) \
       f(G1ParScanClosure,_nv)                      \
       f(G1ParPushHeapRSClosure,_nv)                \
-      f(FilterIntoCSClosure,_nv)                   \
       f(FilterOutOfRegionClosure,_nv)              \
       f(G1CMOopClosure,_nv)                        \
-      f(G1RootRegionScanClosure,_nv)               \
-      f(G1Mux2Closure,_nv)                         \
-      f(G1TriggerClosure,_nv)                      \
-      f(G1InvokeIfNotTriggeredClosure,_nv)         \
-      f(G1UpdateRSOrPushRefOopClosure,_nv)
+      f(G1RootRegionScanClosure,_nv)
 
 #endif // SHARE_VM_GC_G1_G1_SPECIALIZED_OOP_CLOSURES_HPP
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -34,6 +34,7 @@
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/liveRange.hpp"
 #include "gc/shared/space.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -479,10 +480,8 @@
         // Object is in the region. Check that its less than top
         if (_hr->top() <= (HeapWord*)obj) {
           // Object is above top
-          gclog_or_tty->print_cr("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()));
+          log_info(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;
         }
@@ -515,23 +514,19 @@
     if (nm != NULL) {
       // Verify that the nemthod is live
       if (!nm->is_alive()) {
-        gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod "
-                               PTR_FORMAT " in its strong code roots",
-                               p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
+        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));
         _failures = true;
       } else {
         VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
         nm->oops_do(&oop_cl);
         if (!oop_cl.has_oops_in_region()) {
-          gclog_or_tty->print_cr("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_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));
           _failures = true;
         } else if (oop_cl.failures()) {
-          gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has other "
-                                 "failures for nmethod " PTR_FORMAT,
-                                 p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
+          log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has other failures for nmethod " PTR_FORMAT,
+                               p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
           _failures = true;
         }
       }
@@ -564,9 +559,8 @@
   // on its strong code root list
   if (is_empty()) {
     if (strong_code_roots_length > 0) {
-      gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is empty "
-                             "but has " SIZE_FORMAT " code root entries",
-                             p2i(bottom()), p2i(end()), strong_code_roots_length);
+      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);
       *failures = true;
     }
     return;
@@ -574,9 +568,8 @@
 
   if (is_continues_humongous()) {
     if (strong_code_roots_length > 0) {
-      gclog_or_tty->print_cr("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_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);
       *failures = true;
     }
     return;
@@ -590,7 +583,7 @@
   }
 }
 
-void HeapRegion::print() const { print_on(gclog_or_tty); }
+void HeapRegion::print() const { print_on(tty); }
 void HeapRegion::print_on(outputStream* st) const {
   st->print("|%4u", this->_hrm_index);
   st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT,
@@ -651,6 +644,7 @@
     assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
            "Precondition");
     T heap_oop = oopDesc::load_heap_oop(p);
+    LogHandle(gc, verify) log;
     if (!oopDesc::is_null(heap_oop)) {
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       bool failed = false;
@@ -659,35 +653,26 @@
                         Mutex::_no_safepoint_check_flag);
 
         if (!_failures) {
-          gclog_or_tty->cr();
-          gclog_or_tty->print_cr("----------");
+          log.info("----------");
         }
+        ResourceMark rm;
         if (!_g1h->is_in_closed_subset(obj)) {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
-          gclog_or_tty->print_cr("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(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to obj " PTR_FORMAT " not in the heap",
-                                 p2i(obj));
+          log.info("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));
         } else {
           HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
           HeapRegion* to   = _g1h->heap_region_containing((HeapWord*)obj);
-          gclog_or_tty->print_cr("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(gclog_or_tty, _containing_obj);
-          gclog_or_tty->print_cr("points to dead obj " PTR_FORMAT " in region "
-                                 "[" PTR_FORMAT ", " PTR_FORMAT ")",
-                                 p2i(obj), p2i(to->bottom()), p2i(to->end()));
-          print_object(gclog_or_tty, obj);
+          log.info("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 ")",
+                   p2i(obj), p2i(to->bottom()), p2i(to->end()));
+          print_object(log.info_stream(), obj);
         }
-        gclog_or_tty->print_cr("----------");
-        gclog_or_tty->flush();
+        log.info("----------");
         _failures = true;
         failed = true;
         _n_failures++;
@@ -714,25 +699,17 @@
                             Mutex::_no_safepoint_check_flag);
 
             if (!_failures) {
-              gclog_or_tty->cr();
-              gclog_or_tty->print_cr("----------");
+              log.info("----------");
             }
-            gclog_or_tty->print_cr("Missing rem set entry:");
-            gclog_or_tty->print_cr("Field " PTR_FORMAT " "
-                                   "of obj " PTR_FORMAT ", "
-                                   "in region " HR_FORMAT,
-                                   p2i(p), p2i(_containing_obj),
-                                   HR_FORMAT_PARAMS(from));
-            _containing_obj->print_on(gclog_or_tty);
-            gclog_or_tty->print_cr("points to obj " PTR_FORMAT " "
-                                   "in region " HR_FORMAT,
-                                   p2i(obj),
-                                   HR_FORMAT_PARAMS(to));
-            obj->print_on(gclog_or_tty);
-            gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
-                          cv_obj, cv_field);
-            gclog_or_tty->print_cr("----------");
-            gclog_or_tty->flush();
+            log.info("Missing rem set entry:");
+            log.info("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("----------");
             _failures = true;
             if (!failed) _n_failures++;
           }
@@ -766,13 +743,13 @@
                                    (vo == VerifyOption_G1UsePrevMarking &&
                                    ClassLoaderDataGraph::unload_list_contains(klass));
         if (!is_metaspace_object) {
-          gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
-                                 "not metadata", p2i(klass), p2i(obj));
+          log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
+                               "not metadata", p2i(klass), p2i(obj));
           *failures = true;
           return;
         } else if (!klass->is_klass()) {
-          gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " "
-                                 "not a klass", p2i(klass), p2i(obj));
+          log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
+                               "not a klass", p2i(klass), p2i(obj));
           *failures = true;
           return;
         } else {
@@ -787,7 +764,7 @@
           }
         }
       } else {
-        gclog_or_tty->print_cr(PTR_FORMAT " no an oop", p2i(obj));
+        log_info(gc, verify)(PTR_FORMAT " no an oop", p2i(obj));
         *failures = true;
         return;
       }
@@ -803,13 +780,13 @@
   if (is_region_humongous) {
     oop obj = oop(this->humongous_start_region()->bottom());
     if ((HeapWord*)obj > bottom() || (HeapWord*)obj + obj->size() < bottom()) {
-      gclog_or_tty->print_cr("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
+      log_info(gc, verify)("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
     }
   }
 
   if (!is_region_humongous && p != top()) {
-    gclog_or_tty->print_cr("end of last object " PTR_FORMAT " "
-                           "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
+    log_info(gc, verify)("end of last object " PTR_FORMAT " "
+                         "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
     *failures = true;
     return;
   }
@@ -823,9 +800,9 @@
     HeapWord* addr_1 = p;
     HeapWord* b_start_1 = _offsets.block_start_const(addr_1);
     if (b_start_1 != p) {
-      gclog_or_tty->print_cr("BOT look up for top: " PTR_FORMAT " "
-                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                             p2i(addr_1), p2i(b_start_1), p2i(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));
       *failures = true;
       return;
     }
@@ -835,9 +812,9 @@
     if (addr_2 < the_end) {
       HeapWord* b_start_2 = _offsets.block_start_const(addr_2);
       if (b_start_2 != p) {
-        gclog_or_tty->print_cr("BOT look up for top + 1: " PTR_FORMAT " "
-                               " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                               p2i(addr_2), p2i(b_start_2), p2i(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));
         *failures = true;
         return;
       }
@@ -849,9 +826,9 @@
     if (addr_3 < the_end) {
       HeapWord* b_start_3 = _offsets.block_start_const(addr_3);
       if (b_start_3 != p) {
-        gclog_or_tty->print_cr("BOT look up for top + diff: " PTR_FORMAT " "
-                               " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                               p2i(addr_3), p2i(b_start_3), p2i(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));
         *failures = true;
         return;
       }
@@ -861,9 +838,9 @@
     HeapWord* addr_4 = the_end - 1;
     HeapWord* b_start_4 = _offsets.block_start_const(addr_4);
     if (b_start_4 != p) {
-      gclog_or_tty->print_cr("BOT look up for end - 1: " PTR_FORMAT " "
-                             " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
-                             p2i(addr_4), p2i(b_start_4), p2i(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));
       *failures = true;
       return;
     }
@@ -914,7 +891,7 @@
 
 void G1OffsetTableContigSpace::print() const {
   print_short();
-  gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", "
+  tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", "
                 INTPTR_FORMAT ", " INTPTR_FORMAT ")",
                 p2i(bottom()), p2i(top()), p2i(_offsets.threshold()), p2i(end()));
 }
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -99,7 +99,7 @@
   if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
     for (uint i = start; i < start + num_regions; i++) {
       HeapRegion* hr = at(i);
-      G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end());
+      G1CollectedHeap::heap()->hr_printer()->uncommit(hr);
     }
   }
 
@@ -135,7 +135,7 @@
     assert(is_available(i), "Just made region %u available but is apparently not.", i);
     HeapRegion* hr = at(i);
     if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
-      G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end());
+      G1CollectedHeap::heap()->hr_printer()->commit(hr);
     }
     HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
     MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -560,20 +560,13 @@
 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
                               BitMap* region_bm, BitMap* card_bm) {
   // First eliminated garbage regions from the coarse map.
-  if (G1RSScrubVerbose) {
-    gclog_or_tty->print_cr("Scrubbing region %u:", _hr->hrm_index());
-  }
+  log_develop_trace(gc, remset, scrub)("Scrubbing region %u:", _hr->hrm_index());
 
   assert(_coarse_map.size() == region_bm->size(), "Precondition");
-  if (G1RSScrubVerbose) {
-    gclog_or_tty->print("   Coarse map: before = " SIZE_FORMAT "...",
-                        _n_coarse_entries);
-  }
+  log_develop_trace(gc, remset, scrub)("   Coarse map: before = " SIZE_FORMAT "...", _n_coarse_entries);
   _coarse_map.set_intersection(*region_bm);
   _n_coarse_entries = _coarse_map.count_one_bits();
-  if (G1RSScrubVerbose) {
-    gclog_or_tty->print_cr("   after = " SIZE_FORMAT ".", _n_coarse_entries);
-  }
+  log_develop_trace(gc, remset, scrub)("   after = " SIZE_FORMAT ".", _n_coarse_entries);
 
   // Now do the fine-grained maps.
   for (size_t i = 0; i < _max_fine_entries; i++) {
@@ -582,28 +575,19 @@
     while (cur != NULL) {
       PerRegionTable* nxt = cur->collision_list_next();
       // If the entire region is dead, eliminate.
-      if (G1RSScrubVerbose) {
-        gclog_or_tty->print_cr("     For other region %u:",
-                               cur->hr()->hrm_index());
-      }
+      log_develop_trace(gc, remset, scrub)("     For other region %u:", cur->hr()->hrm_index());
       if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
         *prev = nxt;
         cur->set_collision_list_next(NULL);
         _n_fine_entries--;
-        if (G1RSScrubVerbose) {
-          gclog_or_tty->print_cr("          deleted via region map.");
-        }
+        log_develop_trace(gc, remset, scrub)("          deleted via region map.");
         unlink_from_all(cur);
         PerRegionTable::free(cur);
       } else {
         // Do fine-grain elimination.
-        if (G1RSScrubVerbose) {
-          gclog_or_tty->print("          occ: before = %4d.", cur->occupied());
-        }
+        log_develop_trace(gc, remset, scrub)("          occ: before = %4d.", cur->occupied());
         cur->scrub(ctbs, card_bm);
-        if (G1RSScrubVerbose) {
-          gclog_or_tty->print_cr("          after = %4d.", cur->occupied());
-        }
+        log_develop_trace(gc, remset, scrub)("          after = %4d.", cur->occupied());
         // Did that empty the table completely?
         if (cur->occupied() == 0) {
           *prev = nxt;
@@ -799,15 +783,15 @@
   while (iter.has_next(card_index)) {
     HeapWord* card_start =
       G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
-    gclog_or_tty->print_cr("  Card " PTR_FORMAT, p2i(card_start));
+    tty->print_cr("  Card " PTR_FORMAT, p2i(card_start));
   }
   if (iter.n_yielded() != occupied()) {
-    gclog_or_tty->print_cr("Yielded disagrees with occupied:");
-    gclog_or_tty->print_cr("  " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6)
+    tty->print_cr("Yielded disagrees with occupied:");
+    tty->print_cr("  " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6)
                   " coarse, " SIZE_FORMAT_W(6) " fine).",
                   iter.n_yielded(),
                   iter.n_yielded_coarse(), iter.n_yielded_fine());
-    gclog_or_tty->print_cr("  " SIZE_FORMAT_W(6) " occ     (" SIZE_FORMAT_W(6)
+    tty->print_cr("  " SIZE_FORMAT_W(6) " occ     (" SIZE_FORMAT_W(6)
                            " coarse, " SIZE_FORMAT_W(6) " fine).",
                   occupied(), occ_coarse(), occ_fine());
   }
@@ -1071,7 +1055,7 @@
   while (iter.has_next(card_index)) {
     HeapWord* card_start =
       G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
-    gclog_or_tty->print_cr("  Card " PTR_FORMAT ".", p2i(card_start));
+    tty->print_cr("  Card " PTR_FORMAT ".", p2i(card_start));
     sum++;
   }
   guarantee(sum == 11 - 3 + 2048, "Failure");
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -86,7 +86,7 @@
 
   static void invalidate(uint start_idx, size_t num_regions);
 
-  static void print(outputStream* out = gclog_or_tty) PRODUCT_RETURN;
+  static void print(outputStream* out = tty) PRODUCT_RETURN;
 
   static size_t static_mem_size() {
     return _static_mem_size;
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -49,8 +49,8 @@
   // verification might fail and send us on a wild goose chase.
   check_mt_safety();
 
-  guarantee_heap_region_set(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
-                            (!is_empty() && length() > 0  && total_capacity_bytes() > 0) ,
+  guarantee_heap_region_set(( is_empty() && length() == 0) ||
+                            (!is_empty() && length() > 0),
                             "invariant");
 }
 
@@ -81,14 +81,12 @@
   out->print_cr("    free              : %s", BOOL_TO_STR(regions_free()));
   out->print_cr("  Attributes");
   out->print_cr("    length            : %14u", length());
-  out->print_cr("    total capacity    : " SIZE_FORMAT_W(14) " bytes",
-                total_capacity_bytes());
 }
 
 HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker)
   : _name(name), _verify_in_progress(false),
     _is_humongous(humongous), _is_free(free), _mt_safety_checker(mt_safety_checker),
-    _count()
+    _length(0)
 { }
 
 void FreeRegionList::set_unrealistically_long_length(uint len) {
@@ -177,7 +175,7 @@
     }
   }
 
-  _count.increment(from_list->length(), from_list->total_capacity_bytes());
+  _length += from_list->length();
   from_list->clear();
 
   verify_optional();
@@ -255,30 +253,12 @@
 }
 
 void FreeRegionList::clear() {
-  _count = HeapRegionSetCount();
+  _length = 0;
   _head = NULL;
   _tail = NULL;
   _last = NULL;
 }
 
-void FreeRegionList::print_on(outputStream* out, bool print_contents) {
-  HeapRegionSetBase::print_on(out, print_contents);
-  out->print_cr("  Linking");
-  out->print_cr("    head              : " PTR_FORMAT, p2i(_head));
-  out->print_cr("    tail              : " PTR_FORMAT, p2i(_tail));
-
-  if (print_contents) {
-    out->print_cr("  Contents");
-    FreeRegionListIterator iter(this);
-    while (iter.more_available()) {
-      HeapRegion* hr = iter.get_next();
-      hr->print_on(out);
-    }
-  }
-
-  out->cr();
-}
-
 void FreeRegionList::verify_list() {
   HeapRegion* curr = _head;
   HeapRegion* prev1 = NULL;
@@ -312,8 +292,6 @@
   guarantee(_tail == prev0, "Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index());
   guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
   guarantee(length() == count, "%s count mismatch. Expected %u, actual %u.", name(), length(), count);
-  guarantee(total_capacity_bytes() == capacity, "%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
-            name(), total_capacity_bytes(), capacity);
 }
 
 // Note on the check_mt_safety() methods below:
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,22 +27,22 @@
 
 #include "gc/g1/heapRegion.hpp"
 
-#define assert_heap_region_set(p, message)                        \
-  do {                                                            \
-    assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT,                \
-           name(), message, length(), total_capacity_bytes());    \
+#define assert_heap_region_set(p, message) \
+  do {                                     \
+    assert((p), "[%s] %s ln: %u",          \
+           name(), message, length());     \
   } while (0)
 
-#define guarantee_heap_region_set(p, message)                     \
-  do {                                                            \
-    guarantee((p), "[%s] %s ln: %u cy: " SIZE_FORMAT,             \
-              name(), message, length(), total_capacity_bytes()); \
+#define guarantee_heap_region_set(p, message) \
+  do {                                        \
+    guarantee((p), "[%s] %s ln: %u",          \
+              name(), message, length());     \
   } while (0)
 
-#define assert_free_region_list(p, message)                                              \
-  do {                                                                                   \
-    assert((p), "[%s] %s ln: %u cy: " SIZE_FORMAT " hd: " PTR_FORMAT " tl: " PTR_FORMAT, \
-           name(), message, length(), total_capacity_bytes(), p2i(_head), p2i(_tail));   \
+#define assert_free_region_list(p, message)                          \
+  do {                                                               \
+    assert((p), "[%s] %s ln: %u hd: " PTR_FORMAT " tl: " PTR_FORMAT, \
+           name(), message, length(), p2i(_head), p2i(_tail));       \
   } while (0)
 
 
@@ -63,28 +63,6 @@
 class HumongousRegionSetMtSafeChecker      : public HRSMtSafeChecker { public: void check(); };
 class OldRegionSetMtSafeChecker            : public HRSMtSafeChecker { public: void check(); };
 
-class HeapRegionSetCount VALUE_OBJ_CLASS_SPEC {
-  friend class VMStructs;
-  uint   _length;
-  size_t _capacity;
-
-public:
-  HeapRegionSetCount() : _length(0), _capacity(0) { }
-
-  const uint   length()   const { return _length;   }
-  const size_t capacity() const { return _capacity; }
-
-  void increment(uint length_to_add, size_t capacity_to_add) {
-    _length += length_to_add;
-    _capacity += capacity_to_add;
-  }
-
-  void decrement(const uint length_to_remove, const size_t capacity_to_remove) {
-    _length -= length_to_remove;
-    _capacity -= capacity_to_remove;
-  }
-};
-
 // Base class for all the classes that represent heap region sets. It
 // contains the basic attributes that each set needs to maintain
 // (e.g., length, region num, used bytes sum) plus any shared
@@ -98,10 +76,8 @@
   HRSMtSafeChecker* _mt_safety_checker;
 
 protected:
-  // The number of regions added to the set. If the set contains
-  // only humongous regions, this reflects only 'starts humongous'
-  // regions and does not include 'continues humongous' ones.
-  HeapRegionSetCount _count;
+  // The number of regions in to the set.
+  uint _length;
 
   const char* _name;
 
@@ -130,13 +106,9 @@
 public:
   const char* name() { return _name; }
 
-  uint length() const { return _count.length(); }
-
-  bool is_empty() { return _count.length() == 0; }
+  uint length() const { return _length; }
 
-  size_t total_capacity_bytes() {
-    return _count.capacity();
-  }
+  bool is_empty() { return _length == 0; }
 
   // It updates the fields of the set to reflect hr being added to
   // the set and tags the region appropriately.
@@ -181,8 +153,8 @@
   HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker):
     HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { }
 
-  void bulk_remove(const HeapRegionSetCount& removed) {
-    _count.decrement(removed.length(), removed.capacity());
+  void bulk_remove(const uint removed) {
+    _length -= removed;
   }
 };
 
@@ -250,8 +222,6 @@
   void remove_starting_at(HeapRegion* first, uint num_regions);
 
   virtual void verify();
-
-  virtual void print_on(outputStream* out, bool print_contents = false);
 };
 
 // Iterator class that provides a convenient way to iterate over the
--- a/hotspot/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegionSet.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -33,7 +33,7 @@
   assert_heap_region_set(hr->next() == NULL, "should not already be linked");
   assert_heap_region_set(hr->prev() == NULL, "should not already be linked");
 
-  _count.increment(1u, hr->capacity());
+  _length++;
   hr->set_containing_set(this);
   verify_region(hr);
 }
@@ -45,8 +45,8 @@
   assert_heap_region_set(hr->prev() == NULL, "should already be unlinked");
 
   hr->set_containing_set(NULL);
-  assert_heap_region_set(_count.length() > 0, "pre-condition");
-  _count.decrement(1u, hr->capacity());
+  assert_heap_region_set(_length > 0, "pre-condition");
+  _length--;
 }
 
 inline void FreeRegionList::add_ordered(HeapRegion* hr) {
--- a/hotspot/src/share/vm/gc/g1/satbMarkQueue.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/satbMarkQueue.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -199,9 +199,8 @@
 
 void SATBMarkQueue::print(const char* name,
                           void** buf, size_t index, size_t sz) {
-  gclog_or_tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " "
-                         "index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
-                         name, p2i(buf), index, sz);
+  tty->print_cr("  SATB BUFFER [%s] buf: " PTR_FORMAT " index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
+                name, p2i(buf), index, sz);
 }
 #endif // PRODUCT
 
@@ -222,16 +221,13 @@
 
 #ifdef ASSERT
 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
-  gclog_or_tty->print_cr("Expected SATB active state: %s",
-                         expected_active ? "ACTIVE" : "INACTIVE");
-  gclog_or_tty->print_cr("Actual SATB active states:");
-  gclog_or_tty->print_cr("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
+  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");
   for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    gclog_or_tty->print_cr("  Thread \"%s\" queue: %s", t->name(),
-                           t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
+    log_info(gc, verify)("  Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
   }
-  gclog_or_tty->print_cr("  Shared queue: %s",
-                         shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
+  log_info(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
 }
 
 void SATBMarkQueueSet::verify_active_states(bool expected_active) {
@@ -318,8 +314,8 @@
   char buffer[SATB_PRINTER_BUFFER_SIZE];
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
 
-  gclog_or_tty->cr();
-  gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg);
+  tty->cr();
+  tty->print_cr("SATB BUFFERS [%s]", msg);
 
   BufferNode* nd = _completed_buffers_head;
   int i = 0;
@@ -338,7 +334,7 @@
 
   shared_satb_queue()->print("Shared");
 
-  gclog_or_tty->cr();
+  tty->cr();
 }
 #endif // PRODUCT
 
--- a/hotspot/src/share/vm/gc/g1/survRateGroup.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/survRateGroup.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 #include "gc/g1/g1Predictions.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/survRateGroup.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 
 SurvRateGroup::SurvRateGroup(G1Predictions* predictor,
@@ -163,12 +164,11 @@
 
 #ifndef PRODUCT
 void SurvRateGroup::print() {
-  gclog_or_tty->print_cr("Surv Rate Group: %s (" SIZE_FORMAT " entries)",
-                _name, _region_num);
+  log_develop_trace(gc, survivor)("Surv Rate Group: %s (" SIZE_FORMAT " entries)", _name, _region_num);
   for (size_t i = 0; i < _region_num; ++i) {
-    gclog_or_tty->print_cr("    age " SIZE_FORMAT_W(4) "   surv rate %6.2lf %%   pred %6.2lf %%",
-                           i, _surv_rate[i] * 100.0,
-                           _predictor->get_new_prediction(_surv_rate_pred[i]) * 100.0);
+    log_develop_trace(gc, survivor)("    age " SIZE_FORMAT_W(4) "   surv rate %6.2lf %%   pred %6.2lf %%",
+                                    i, _surv_rate[i] * 100.0,
+                                    _predictor->get_new_prediction(_surv_rate_pred[i]) * 100.0);
   }
 }
 
@@ -178,22 +178,20 @@
   if (length == 0)
     return;
 
-  gclog_or_tty->cr();
-  gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1);
-  gclog_or_tty->print_cr("      age range     survival rate (avg)      samples (avg)");
-  gclog_or_tty->print_cr("  ---------------------------------------------------------");
+  log_trace(gc, survivor)("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1);
+  log_trace(gc, survivor)("      age range     survival rate (avg)      samples (avg)");
+  log_trace(gc, survivor)("  ---------------------------------------------------------");
 
   size_t index = 0;
   size_t limit = MIN2((int) length, 10);
   while (index < limit) {
-    gclog_or_tty->print_cr("           " SIZE_FORMAT_W(4)
-                           "                 %6.2lf%%             %6.2lf",
-                           index, _summary_surv_rates[index]->avg() * 100.0,
-                           (double) _summary_surv_rates[index]->num());
+    log_trace(gc, survivor)("           " SIZE_FORMAT_W(4) "                 %6.2lf%%             %6.2lf",
+                            index, _summary_surv_rates[index]->avg() * 100.0,
+                            (double) _summary_surv_rates[index]->num());
     ++index;
   }
 
-  gclog_or_tty->print_cr("  ---------------------------------------------------------");
+  log_trace(gc, survivor)("  ---------------------------------------------------------");
 
   int num = 0;
   double sum = 0.0;
@@ -205,16 +203,15 @@
     ++index;
 
     if (index == length || num % 10 == 0) {
-      gclog_or_tty->print_cr("   " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4)
-                             "                 %6.2lf%%             %6.2lf",
-                             (index-1) / 10 * 10, index-1, sum / (double) num,
-                             (double) samples / (double) num);
+      log_trace(gc, survivor)("   " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) "                 %6.2lf%%             %6.2lf",
+                              (index-1) / 10 * 10, index-1, sum / (double) num,
+                              (double) samples / (double) num);
       sum = 0.0;
       num = 0;
       samples = 0;
     }
   }
 
-  gclog_or_tty->print_cr("  ---------------------------------------------------------");
+  log_trace(gc, survivor)("  ---------------------------------------------------------");
 }
 #endif // PRODUCT
--- a/hotspot/src/share/vm/gc/g1/vmStructs_g1.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/vmStructs_g1.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -59,10 +59,7 @@
   nonstatic_field(G1MonitoringSupport, _old_committed,      size_t)           \
   nonstatic_field(G1MonitoringSupport, _old_used,           size_t)           \
                                                                               \
-  nonstatic_field(HeapRegionSetBase,   _count,          HeapRegionSetCount)   \
-                                                                              \
-  nonstatic_field(HeapRegionSetCount,  _length,         uint)                 \
-  nonstatic_field(HeapRegionSetCount,  _capacity,       size_t)               \
+  nonstatic_field(HeapRegionSetBase,   _length,         uint)                 \
                                                                               \
   nonstatic_field(PtrQueue,            _active,         bool)                 \
   nonstatic_field(PtrQueue,            _buf,            void**)               \
@@ -103,7 +100,6 @@
   declare_type(HeapRegion, G1OffsetTableContigSpace)                          \
   declare_toplevel_type(HeapRegionManager)                                    \
   declare_toplevel_type(HeapRegionSetBase)                                    \
-  declare_toplevel_type(HeapRegionSetCount)                                   \
   declare_toplevel_type(G1MonitoringSupport)                                  \
   declare_toplevel_type(PtrQueue)                                             \
                                                                               \
--- a/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/vm_operations_g1.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,10 +27,9 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/shared/gcId.hpp"
-#include "gc/g1/g1Log.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
 #include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "runtime/interfaceSupport.hpp"
 
@@ -226,10 +225,10 @@
 }
 
 void VM_CGC_Operation::doit() {
-  TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+  GCIdMark gc_id_mark(_gc_id);
+  GCTraceCPUTime tcpu;
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  GCIdMark gc_id_mark(_gc_id);
-  GCTraceTime t(_printGCMessage, G1Log::fine(), true, g1h->gc_timer_cm());
+  GCTraceTime(Info, gc) t(_printGCMessage, g1h->gc_timer_cm(), GCCause::_no_gc, true);
   IsGCActiveMark x;
   _cl->do_void();
 }
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,13 +30,11 @@
   const uint length = 3;
   const char* title = "Test array";
   const bool print_sum = false;
-  const int log_level = 3;
   const uint indent_level = 2;
 
-  WorkerDataArray<size_t> array(length, title, print_sum, log_level, indent_level);
+  WorkerDataArray<size_t> array(length, title, print_sum, indent_level);
   assert(strncmp(array.title(), title, strlen(title)) == 0 , "Expected titles to match");
   assert(array.should_print_sum() == print_sum, "Expected should_print_sum to match print_sum");
-  assert(array.log_level() == log_level, "Expected log levels to match");
   assert(array.indentation() == indent_level, "Expected indentation to match");
 
   const size_t expected[length] = {5, 3, 7};
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,7 +32,6 @@
   uint        _length;
   const char* _title;
   bool        _print_sum;
-  int         _log_level;
   uint        _indent_level;
   bool        _enabled;
 
@@ -46,7 +45,6 @@
   WorkerDataArray(uint length,
                   const char* title,
                   bool print_sum,
-                  int log_level,
                   uint indent_level);
 
   ~WorkerDataArray();
@@ -80,10 +78,6 @@
     return _print_sum;
   }
 
-  int log_level() const {
-    return _log_level;
-  }
-
   void clear();
   void set_enabled(bool enabled) {
     _enabled = enabled;
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,12 +29,10 @@
 WorkerDataArray<T>::WorkerDataArray(uint length,
                                     const char* title,
                                     bool print_sum,
-                                    int log_level,
                                     uint indent_level) :
  _title(title),
  _length(0),
  _print_sum(print_sum),
- _log_level(log_level),
  _indent_level(indent_level),
  _thread_work_items(NULL),
  _enabled(true) {
--- a/hotspot/src/share/vm/gc/g1/youngList.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/youngList.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/youngList.hpp"
+#include "logging/log.hpp"
 #include "utilities/ostream.hpp"
 
 YoungList::YoungList(G1CollectedHeap* g1h) :
@@ -98,10 +99,10 @@
   HeapRegion* last = NULL;
   while (curr != NULL) {
     if (!curr->is_young()) {
-      gclog_or_tty->print_cr("### 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_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());
       ret = false;
     }
     ++length;
@@ -111,9 +112,8 @@
   ret = ret && (length == _length);
 
   if (!ret) {
-    gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!");
-    gclog_or_tty->print_cr("###   list has %u entries, _length is %u",
-                           length, _length);
+    log_info(gc, verify)("### YOUNG LIST seems not well formed!");
+    log_info(gc, verify)("###   list has %u entries, _length is %u", length, _length);
   }
 
   return ret;
@@ -123,20 +123,19 @@
   bool ret = true;
 
   if (_length != 0) {
-    gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u",
-                  _length);
+    log_info(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
     ret = false;
   }
   if (check_sample && _last_sampled_rs_lengths != 0) {
-    gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths");
+    log_info(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
     ret = false;
   }
   if (_head != NULL) {
-    gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head");
+    log_info(gc, verify)("### YOUNG LIST does not have a NULL head");
     ret = false;
   }
   if (!ret) {
-    gclog_or_tty->print_cr("### YOUNG LIST does not seem empty");
+    log_info(gc, verify)("### YOUNG LIST does not seem empty");
   }
 
   return ret;
@@ -171,7 +170,6 @@
   _curr = _curr->get_next_young_region();
   if (_curr == NULL) {
     _last_sampled_rs_lengths = _sampled_rs_lengths;
-    // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths);
   }
 }
 
@@ -222,13 +220,13 @@
   const char* names[] = {"YOUNG", "SURVIVOR"};
 
   for (uint list = 0; list < ARRAY_SIZE(lists); ++list) {
-    gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]);
+    tty->print_cr("%s LIST CONTENTS", names[list]);
     HeapRegion *curr = lists[list];
     if (curr == NULL) {
-      gclog_or_tty->print_cr("  empty");
+      tty->print_cr("  empty");
     }
     while (curr != NULL) {
-      gclog_or_tty->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
+      tty->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
                              HR_FORMAT_PARAMS(curr),
                              p2i(curr->prev_top_at_mark_start()),
                              p2i(curr->next_top_at_mark_start()),
@@ -237,5 +235,5 @@
     }
   }
 
-  gclog_or_tty->cr();
+  tty->cr();
 }
--- a/hotspot/src/share/vm/gc/parallel/adjoiningGenerations.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/adjoiningGenerations.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,9 @@
 #include "gc/parallel/adjoiningVirtualSpaces.hpp"
 #include "gc/parallel/generationSizer.hpp"
 #include "gc/parallel/parallelScavengeHeap.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
+#include "utilities/ostream.hpp"
 
 // If boundary moving is being used, create the young gen and old
 // gen with ASPSYoungGen and ASPSOldGen, respectively.  Revert to
@@ -116,6 +119,29 @@
   return virtual_spaces()->reserved_space().size();
 }
 
+void log_before_expansion(bool old, size_t expand_in_bytes, size_t change_in_bytes, size_t max_size) {
+  LogHandle(heap, ergo) log;
+  if (!log.is_debug()) {
+   return;
+  }
+  log.debug("Before expansion of %s gen with boundary move", old ? "old" : "young");
+  log.debug("  Requested change: " SIZE_FORMAT_HEX "  Attempted change: " SIZE_FORMAT_HEX,
+                        expand_in_bytes, change_in_bytes);
+  ResourceMark rm;
+  ParallelScavengeHeap::heap()->print_on(log.debug_stream());
+  log.debug("  PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
+}
+
+void log_after_expansion(bool old, size_t max_size) {
+  LogHandle(heap, ergo) log;
+  if (!log.is_debug()) {
+   return;
+  }
+  log.debug("After expansion of %s gen with boundary move", old ? "old" : "young");
+  ResourceMark rm;
+  ParallelScavengeHeap::heap()->print_on(log.debug_stream());
+  log.debug("  PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
+}
 
 // Make checks on the current sizes of the generations and
 // the constraints on the sizes of the generations.  Push
@@ -141,17 +167,7 @@
     return;
   }
 
-  if (TraceAdaptiveGCBoundary) {
-    gclog_or_tty->print_cr("Before expansion of old gen with boundary move");
-    gclog_or_tty->print_cr("  Requested change: " SIZE_FORMAT_HEX
-                           "  Attempted change: " SIZE_FORMAT_HEX,
-      expand_in_bytes, change_in_bytes);
-    if (!PrintHeapAtGC) {
-      Universe::print_on(gclog_or_tty);
-    }
-    gclog_or_tty->print_cr("  PSOldGen max size: " SIZE_FORMAT "K",
-      old_gen()->max_gen_size()/K);
-  }
+  log_before_expansion(true, expand_in_bytes, change_in_bytes, old_gen()->max_gen_size());
 
   // Move the boundary between the generations up (smaller young gen).
   if (virtual_spaces()->adjust_boundary_up(change_in_bytes)) {
@@ -167,14 +183,7 @@
   young_gen()->space_invariants();
   old_gen()->space_invariants();
 
-  if (TraceAdaptiveGCBoundary) {
-    gclog_or_tty->print_cr("After expansion of old gen with boundary move");
-    if (!PrintHeapAtGC) {
-      Universe::print_on(gclog_or_tty);
-    }
-    gclog_or_tty->print_cr("  PSOldGen max size: " SIZE_FORMAT "K",
-      old_gen()->max_gen_size()/K);
-  }
+  log_after_expansion(true, old_gen()->max_gen_size());
 }
 
 // See comments on request_old_gen_expansion()
@@ -200,16 +209,7 @@
     return false;
   }
 
-  if (TraceAdaptiveGCBoundary) {
-    gclog_or_tty->print_cr("Before expansion of young gen with boundary move");
-    gclog_or_tty->print_cr("  Requested change: " SIZE_FORMAT_HEX "  Attempted change: " SIZE_FORMAT_HEX,
-      expand_in_bytes, change_in_bytes);
-    if (!PrintHeapAtGC) {
-      Universe::print_on(gclog_or_tty);
-    }
-    gclog_or_tty->print_cr("  PSYoungGen max size: " SIZE_FORMAT "K",
-      young_gen()->max_size()/K);
-  }
+  log_before_expansion(false, expand_in_bytes, change_in_bytes, young_gen()->max_size());
 
   // Move the boundary between the generations down (smaller old gen).
   MutexLocker x(ExpandHeap_lock);
@@ -227,14 +227,7 @@
   young_gen()->space_invariants();
   old_gen()->space_invariants();
 
-  if (TraceAdaptiveGCBoundary) {
-    gclog_or_tty->print_cr("After expansion of young gen with boundary move");
-    if (!PrintHeapAtGC) {
-      Universe::print_on(gclog_or_tty);
-    }
-    gclog_or_tty->print_cr("  PSYoungGen max size: " SIZE_FORMAT "K",
-      young_gen()->max_size()/K);
-  }
+  log_after_expansion(false, young_gen()->max_size());
 
   return result;
 }
--- a/hotspot/src/share/vm/gc/parallel/asPSOldGen.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/asPSOldGen.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -125,25 +125,21 @@
   size_t result = policy->promo_increment_aligned_down(max_contraction);
   // Also adjust for inter-generational alignment
   size_t result_aligned = align_size_down(result, gen_alignment);
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:"
-      " " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned);
-    gclog_or_tty->print_cr(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      reserved().byte_size()/K, reserved().byte_size());
+
+  LogHandle(gc, ergo) log;
+  if (log.is_trace()) {
     size_t working_promoted = (size_t) policy->avg_promoted()->padded_average();
-    gclog_or_tty->print_cr(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      working_promoted/K, working_promoted);
-    gclog_or_tty->print_cr(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      used_in_bytes()/K, used_in_bytes());
-    gclog_or_tty->print_cr(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      min_gen_size()/K, min_gen_size());
-    gclog_or_tty->print_cr(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      max_contraction/K, max_contraction);
-    gclog_or_tty->print_cr("    without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
-      policy->promo_increment(max_contraction)/K,
-      policy->promo_increment(max_contraction));
-    gclog_or_tty->print_cr(" alignment " SIZE_FORMAT_HEX, gen_alignment);
+    size_t promo_increment = policy->promo_increment(max_contraction);
+    log.trace("ASPSOldGen::available_for_contraction: " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned);
+    log.trace(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, reserved().byte_size()/K, reserved().byte_size());
+    log.trace(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, working_promoted/K, working_promoted);
+    log.trace(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, used_in_bytes()/K, used_in_bytes());
+    log.trace(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, min_gen_size()/K, min_gen_size());
+    log.trace(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, max_contraction/K, max_contraction);
+    log.trace("    without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, promo_increment/K, promo_increment);
+    log.trace(" alignment " SIZE_FORMAT_HEX, gen_alignment);
   }
+
   assert(result_aligned <= max_contraction, "arithmetic is wrong");
   return result_aligned;
 }
--- a/hotspot/src/share/vm/gc/parallel/asPSYoungGen.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/asPSYoungGen.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -111,13 +111,12 @@
     PSAdaptiveSizePolicy* policy = heap->size_policy();
     size_t result = policy->eden_increment_aligned_down(max_contraction);
     size_t result_aligned = align_size_down(result, gen_alignment);
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K",
-        result_aligned/K);
-      gclog_or_tty->print_cr("  max_contraction " SIZE_FORMAT " K", max_contraction/K);
-      gclog_or_tty->print_cr("  eden_avail " SIZE_FORMAT " K", eden_avail/K);
-      gclog_or_tty->print_cr("  gen_avail " SIZE_FORMAT " K", gen_avail/K);
-    }
+
+    log_trace(gc, ergo)("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K", result_aligned/K);
+    log_trace(gc, ergo)("  max_contraction " SIZE_FORMAT " K", max_contraction/K);
+    log_trace(gc, ergo)("  eden_avail " SIZE_FORMAT " K", eden_avail/K);
+    log_trace(gc, ergo)("  gen_avail " SIZE_FORMAT " K", gen_avail/K);
+
     return result_aligned;
   }
 
@@ -199,25 +198,17 @@
     virtual_space()->shrink_by(change);
     size_changed = true;
   } else {
-    if (Verbose && PrintGC) {
-      if (orig_size == gen_size_limit()) {
-        gclog_or_tty->print_cr("ASPSYoung generation size at maximum: "
-          SIZE_FORMAT "K", orig_size/K);
-      } else if (orig_size == min_gen_size()) {
-        gclog_or_tty->print_cr("ASPSYoung generation size at minium: "
-          SIZE_FORMAT "K", orig_size/K);
-      }
+    if (orig_size == gen_size_limit()) {
+      log_trace(gc)("ASPSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K);
+    } else if (orig_size == min_gen_size()) {
+      log_trace(gc)("ASPSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K);
     }
   }
 
   if (size_changed) {
     reset_after_change();
-    if (Verbose && PrintGC) {
-      size_t current_size  = virtual_space()->committed_size();
-      gclog_or_tty->print_cr("ASPSYoung generation size changed: "
-        SIZE_FORMAT "K->" SIZE_FORMAT "K",
-        orig_size/K, current_size/K);
-    }
+    log_trace(gc)("ASPSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
+                  orig_size/K, virtual_space()->committed_size()/K);
   }
 
   guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
@@ -245,41 +236,31 @@
     return;
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
-                  SIZE_FORMAT
-                  ", requested_survivor_size: " SIZE_FORMAT ")",
-                  requested_eden_size, requested_survivor_size);
-    gclog_or_tty->print_cr("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(eden_space()->bottom()),
-                  p2i(eden_space()->end()),
-                  pointer_delta(eden_space()->end(),
-                                eden_space()->bottom(),
-                                sizeof(char)));
-    gclog_or_tty->print_cr("    from: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(from_space()->bottom()),
-                  p2i(from_space()->end()),
-                  pointer_delta(from_space()->end(),
-                                from_space()->bottom(),
-                                sizeof(char)));
-    gclog_or_tty->print_cr("      to: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(to_space()->bottom()),
-                  p2i(to_space()->end()),
-                  pointer_delta(  to_space()->end(),
-                                  to_space()->bottom(),
-                                  sizeof(char)));
-  }
+  log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: "
+                      SIZE_FORMAT
+                      ", requested_survivor_size: " SIZE_FORMAT ")",
+                      requested_eden_size, requested_survivor_size);
+  log_trace(gc, ergo)("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
+                      SIZE_FORMAT,
+                      p2i(eden_space()->bottom()),
+                      p2i(eden_space()->end()),
+                      pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char)));
+  log_trace(gc, ergo)("    from: [" PTR_FORMAT ".." PTR_FORMAT ") "
+                      SIZE_FORMAT,
+                      p2i(from_space()->bottom()),
+                      p2i(from_space()->end()),
+                      pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char)));
+  log_trace(gc, ergo)("      to: [" PTR_FORMAT ".." PTR_FORMAT ") "
+                      SIZE_FORMAT,
+                      p2i(to_space()->bottom()),
+                      p2i(to_space()->end()),
+                      pointer_delta(  to_space()->end(), to_space()->bottom(), sizeof(char)));
 
   // There's nothing to do if the new sizes are the same as the current
   if (requested_survivor_size == to_space()->capacity_in_bytes() &&
       requested_survivor_size == from_space()->capacity_in_bytes() &&
       requested_eden_size == eden_space()->capacity_in_bytes()) {
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    capacities are the right sizes, returning");
-    }
+    log_trace(gc, ergo)("    capacities are the right sizes, returning");
     return;
   }
 
@@ -302,9 +283,7 @@
   if (eden_from_to_order) {
     // Eden, from, to
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("  Eden, from, to:");
-    }
+    log_trace(gc, ergo)("  Eden, from, to:");
 
     // Set eden
     // "requested_eden_size" is a goal for the size of eden
@@ -368,28 +347,24 @@
 
     guarantee(to_start != to_end, "to space is zero sized");
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(eden_start),
-                    p2i(eden_end),
-                    pointer_delta(eden_end, eden_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [from_start .. from_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(from_start),
-                    p2i(from_end),
-                    pointer_delta(from_end, from_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(to_start),
-                    p2i(to_end),
-                    pointer_delta(  to_end,   to_start, sizeof(char)));
-    }
+    log_trace(gc, ergo)("    [eden_start .. eden_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(eden_start),
+                        p2i(eden_end),
+                        pointer_delta(eden_end, eden_start, sizeof(char)));
+    log_trace(gc, ergo)("    [from_start .. from_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(from_start),
+                        p2i(from_end),
+                        pointer_delta(from_end, from_start, sizeof(char)));
+    log_trace(gc, ergo)("    [  to_start ..   to_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(to_start),
+                        p2i(to_end),
+                        pointer_delta(  to_end,   to_start, sizeof(char)));
   } else {
     // Eden, to, from
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("  Eden, to, from:");
-    }
+    log_trace(gc, ergo)("  Eden, to, from:");
 
     // To space gets priority over eden resizing. Note that we position
     // to space as if we were able to resize from space, even though from
@@ -422,23 +397,21 @@
     eden_end = MAX2(eden_end, eden_start + alignment);
     to_start = MAX2(to_start, eden_end);
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(eden_start),
-                    p2i(eden_end),
-                    pointer_delta(eden_end, eden_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(to_start),
-                    p2i(to_end),
-                    pointer_delta(  to_end,   to_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [from_start .. from_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(from_start),
-                    p2i(from_end),
-                    pointer_delta(from_end, from_start, sizeof(char)));
-    }
+    log_trace(gc, ergo)("    [eden_start .. eden_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(eden_start),
+                        p2i(eden_end),
+                        pointer_delta(eden_end, eden_start, sizeof(char)));
+    log_trace(gc, ergo)("    [  to_start ..   to_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(to_start),
+                        p2i(to_end),
+                        pointer_delta(  to_end,   to_start, sizeof(char)));
+    log_trace(gc, ergo)("    [from_start .. from_end): "
+                        "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(from_start),
+                        p2i(from_end),
+                        pointer_delta(from_end, from_start, sizeof(char)));
   }
 
 
@@ -457,7 +430,7 @@
   // Let's make sure the call to initialize doesn't reset "top"!
   DEBUG_ONLY(HeapWord* old_from_top = from_space()->top();)
 
-  // For PrintAdaptiveSizePolicy block  below
+  // For logging block  below
   size_t old_from = from_space()->capacity_in_bytes();
   size_t old_to   = to_space()->capacity_in_bytes();
 
@@ -506,19 +479,16 @@
 
   assert(from_space()->top() == old_from_top, "from top changed!");
 
-  if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
-    gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
-                  "collection: %d "
-                  "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
-                  "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
-                  heap->total_collections(),
-                  old_from, old_to,
-                  from_space()->capacity_in_bytes(),
-                  to_space()->capacity_in_bytes());
-    gclog_or_tty->cr();
-  }
-  space_invariants();
+  log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: "
+                "collection: %d "
+                "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
+                "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
+                ParallelScavengeHeap::heap()->total_collections(),
+                old_from, old_to,
+                from_space()->capacity_in_bytes(),
+                to_space()->capacity_in_bytes());
+
+    space_invariants();
 }
 void ASPSYoungGen::reset_after_change() {
   assert_locked_or_safepoint(Heap_lock);
--- a/hotspot/src/share/vm/gc/parallel/cardTableExtension.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/cardTableExtension.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -468,30 +468,17 @@
   // Update the covered region
   resize_update_covered_table(changed_region, new_region);
 
-  if (TraceCardTableModRefBS) {
-    int ind = changed_region;
-    gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: ");
-    gclog_or_tty->print_cr("  "
-                  "  _covered[%d].start(): " INTPTR_FORMAT
-                  "  _covered[%d].last(): " INTPTR_FORMAT,
-                  ind, p2i(_covered[ind].start()),
-                  ind, p2i(_covered[ind].last()));
-    gclog_or_tty->print_cr("  "
-                  "  _committed[%d].start(): " INTPTR_FORMAT
-                  "  _committed[%d].last(): " INTPTR_FORMAT,
-                  ind, p2i(_committed[ind].start()),
-                  ind, p2i(_committed[ind].last()));
-    gclog_or_tty->print_cr("  "
-                  "  byte_for(start): " INTPTR_FORMAT
-                  "  byte_for(last): " INTPTR_FORMAT,
-                  p2i(byte_for(_covered[ind].start())),
-                  p2i(byte_for(_covered[ind].last())));
-    gclog_or_tty->print_cr("  "
-                  "  addr_for(start): " INTPTR_FORMAT
-                  "  addr_for(last): " INTPTR_FORMAT,
-                  p2i(addr_for((jbyte*) _committed[ind].start())),
-                  p2i(addr_for((jbyte*) _committed[ind].last())));
-  }
+  int ind = changed_region;
+  log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
+  log_trace(gc, barrier)("    _covered[%d].start(): " INTPTR_FORMAT "  _covered[%d].last(): " INTPTR_FORMAT,
+                ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
+  log_trace(gc, barrier)("    _committed[%d].start(): " INTPTR_FORMAT "  _committed[%d].last(): " INTPTR_FORMAT,
+                ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
+  log_trace(gc, barrier)("    byte_for(start): " INTPTR_FORMAT "  byte_for(last): " INTPTR_FORMAT,
+                p2i(byte_for(_covered[ind].start())),  p2i(byte_for(_covered[ind].last())));
+  log_trace(gc, barrier)("    addr_for(start): " INTPTR_FORMAT "  addr_for(last): " INTPTR_FORMAT,
+                p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
+
   debug_only(verify_guard();)
 }
 
--- a/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskManager.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcId.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
@@ -465,13 +466,11 @@
          "all_workers_active() is  incorrect: "
          "active %d  ParallelGCThreads %u", active_workers(),
          ParallelGCThreads);
-  if (TraceDynamicGCThreads) {
-    gclog_or_tty->print_cr("GCTaskManager::set_active_gang(): "
-                           "all_workers_active()  %d  workers %d  "
-                           "active  %d  ParallelGCThreads %u",
-                           all_workers_active(), workers(),  active_workers(),
-                           ParallelGCThreads);
-  }
+  log_trace(gc, task)("GCTaskManager::set_active_gang(): "
+                      "all_workers_active()  %d  workers %d  "
+                      "active  %d  ParallelGCThreads %u",
+                      all_workers_active(), workers(),  active_workers(),
+                      ParallelGCThreads);
 }
 
 // Create IdleGCTasks for inactive workers.
@@ -502,15 +501,12 @@
         set_active_workers(reduced_active_workers);
         more_inactive_workers = 0;
       }
-      if (TraceDynamicGCThreads) {
-        gclog_or_tty->print_cr("JT: %d  workers %d  active  %d  "
-                                "idle %d  more %d",
-                                Threads::number_of_non_daemon_threads(),
-                                workers(),
-                                active_workers(),
-                                idle_workers(),
-                                more_inactive_workers);
-      }
+      log_trace(gc, task)("JT: %d  workers %d  active  %d  idle %d  more %d",
+                          Threads::number_of_non_daemon_threads(),
+                          workers(),
+                          active_workers(),
+                          idle_workers(),
+                          more_inactive_workers);
     }
     GCTaskQueue* q = GCTaskQueue::create();
     for(uint i = 0; i < (uint) more_inactive_workers; i++) {
@@ -536,6 +532,9 @@
 }
 
 void GCTaskManager::print_task_time_stamps() {
+  if (!log_is_enabled(Debug, gc, task, time)) {
+    return;
+  }
   for(uint i=0; i<ParallelGCThreads; i++) {
     GCTaskThread* t = thread(i);
     t->print_task_time_stamps();
@@ -828,38 +827,24 @@
 
 void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
   WaitHelper* wait_helper = manager->wait_helper();
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " IdleGCTask:::do_it()"
-      "  should_wait: %s",
+  log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask:::do_it() should_wait: %s",
       p2i(this), wait_helper->should_wait() ? "true" : "false");
-  }
+
   MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
-  if (TraceDynamicGCThreads) {
-    gclog_or_tty->print_cr("--- idle %d", which);
-  }
+  log_trace(gc, task)("--- idle %d", which);
   // Increment has to be done when the idle tasks are created.
   // manager->increment_idle_workers();
   manager->monitor()->notify_all();
   while (wait_helper->should_wait()) {
-    if (TraceGCTaskManager) {
-      tty->print_cr("[" INTPTR_FORMAT "]"
-                    " IdleGCTask::do_it()"
-        "  [" INTPTR_FORMAT "] (%s)->wait()",
-        p2i(this), p2i(manager->monitor()), manager->monitor()->name());
-    }
+    log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it()  [" INTPTR_FORMAT "] (%s)->wait()",
+      p2i(this), p2i(manager->monitor()), manager->monitor()->name());
     manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
   }
   manager->decrement_idle_workers();
-  if (TraceDynamicGCThreads) {
-    gclog_or_tty->print_cr("--- release %d", which);
-  }
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " IdleGCTask::do_it() returns"
-      "  should_wait: %s",
-      p2i(this), wait_helper->should_wait() ? "true" : "false");
-  }
+
+  log_trace(gc, task)("--- release %d", which);
+  log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it() returns should_wait: %s",
+    p2i(this), wait_helper->should_wait() ? "true" : "false");
   // Release monitor().
 }
 
--- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,9 +26,11 @@
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/gcId.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/atomic.inline.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/os.hpp"
@@ -45,11 +47,6 @@
   if (!os::create_thread(this, os::pgc_thread))
     vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources.");
 
-  if (PrintGCTaskTimeStamps) {
-    _time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
-
-    guarantee(_time_stamps != NULL, "Sanity");
-  }
   set_id(which);
   set_name("ParGC Thread#%d", which);
 }
@@ -66,21 +63,30 @@
 
 GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
   guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
+  if (_time_stamps == NULL) {
+    // We allocate the _time_stamps array lazily since logging can be enabled dynamically
+    GCTaskTimeStamp* time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
+    void* old = Atomic::cmpxchg_ptr(time_stamps, &_time_stamps, NULL);
+    if (old != NULL) {
+      // Someone already setup the time stamps
+      FREE_C_HEAP_ARRAY(GCTaskTimeStamp, time_stamps);
+    }
+  }
 
   return &(_time_stamps[index]);
 }
 
 void GCTaskThread::print_task_time_stamps() {
-  assert(PrintGCTaskTimeStamps, "Sanity");
-  assert(_time_stamps != NULL, "Sanity (Probably set PrintGCTaskTimeStamps late)");
+  assert(log_is_enabled(Debug, gc, task, time), "Sanity");
+  assert(_time_stamps != NULL, "Sanity");
 
-  tty->print_cr("GC-Thread %u entries: %d", id(), _time_stamp_index);
+  log_debug(gc, task, time)("GC-Thread %u entries: %d", id(), _time_stamp_index);
   for(uint i=0; i<_time_stamp_index; i++) {
     GCTaskTimeStamp* time_stamp = time_stamp_at(i);
-    tty->print_cr("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]",
-                  time_stamp->name(),
-                  time_stamp->entry_time(),
-                  time_stamp->exit_time());
+    log_debug(gc, task, time)("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]",
+                              time_stamp->name(),
+                              time_stamp->entry_time(),
+                              time_stamp->exit_time());
   }
 
   // Reset after dumping the data
@@ -127,7 +133,7 @@
       // Record if this is an idle task for later use.
       bool is_idle_task = task->is_idle_task();
       // In case the update is costly
-      if (PrintGCTaskTimeStamps) {
+      if (log_is_enabled(Debug, gc, task, time)) {
         timer.update();
       }
 
@@ -143,10 +149,7 @@
       if (!is_idle_task) {
         manager()->note_completion(which());
 
-        if (PrintGCTaskTimeStamps) {
-          assert(_time_stamps != NULL,
-            "Sanity (PrintGCTaskTimeStamps set late?)");
-
+        if (log_is_enabled(Debug, gc, task, time)) {
           timer.update();
 
           GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index++);
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -38,6 +38,7 @@
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcWhen.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
@@ -307,10 +308,7 @@
         if (limit_exceeded && softrefs_clear) {
           *gc_overhead_limit_was_exceeded = true;
           size_policy()->set_gc_overhead_limit_exceeded(false);
-          if (PrintGCDetails && Verbose) {
-            gclog_or_tty->print_cr("ParallelScavengeHeap::mem_allocate: "
-              "return NULL because gc_overhead_limit_exceeded is set");
-          }
+          log_trace(gc)("ParallelScavengeHeap::mem_allocate: return NULL because gc_overhead_limit_exceeded is set");
           if (op.result() != NULL) {
             CollectedHeap::fill_with_object(op.result(), size);
           }
@@ -584,35 +582,17 @@
 }
 
 
-void ParallelScavengeHeap::verify(bool silent, VerifyOption option /* ignored */) {
+void ParallelScavengeHeap::verify(VerifyOption option /* ignored */) {
   // Why do we need the total_collections()-filter below?
   if (total_collections() > 0) {
-    if (!silent) {
-      gclog_or_tty->print("tenured ");
-    }
+    log_debug(gc, verify)("Tenured");
     old_gen()->verify();
 
-    if (!silent) {
-      gclog_or_tty->print("eden ");
-    }
+    log_debug(gc, verify)("Eden");
     young_gen()->verify();
   }
 }
 
-void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print(" "  SIZE_FORMAT
-                        "->" SIZE_FORMAT
-                        "("  SIZE_FORMAT ")",
-                        prev_used, used(), capacity());
-  } else {
-    gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                        "->" SIZE_FORMAT "K"
-                        "("  SIZE_FORMAT "K)",
-                        prev_used / K, used() / K, capacity() / K);
-  }
-}
-
 void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) {
   const PSHeapSummary& heap_summary = create_ps_heap_summary();
   gc_tracer->report_gc_heap_summary(when, heap_summary);
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,6 +35,7 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/strongRootsScope.hpp"
+#include "memory/metaspace.hpp"
 #include "utilities/ostream.hpp"
 
 class AdjoiningGenerations;
@@ -87,6 +88,10 @@
     return CollectedHeap::ParallelScavengeHeap;
   }
 
+  virtual const char* name() const {
+    return "Parallel";
+  }
+
   virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
   static PSYoungGen* young_gen() { return _young_gen; }
@@ -215,9 +220,7 @@
   virtual void gc_threads_do(ThreadClosure* tc) const;
   virtual void print_tracing_info() const;
 
-  void verify(bool silent, VerifyOption option /* ignored */);
-
-  void print_heap_change(size_t prev_used);
+  void verify(VerifyOption option /* ignored */);
 
   // Resize the young generation.  The reserved space for the
   // generation may be expanded in preparation for the resize.
@@ -241,4 +244,26 @@
   };
 };
 
+// Simple class for storing info about the heap at the start of GC, to be used
+// after GC for comparison/printing.
+class PreGCValues {
+public:
+  PreGCValues(ParallelScavengeHeap* heap) :
+      _heap_used(heap->used()),
+      _young_gen_used(heap->young_gen()->used_in_bytes()),
+      _old_gen_used(heap->old_gen()->used_in_bytes()),
+      _metadata_used(MetaspaceAux::used_bytes()) { };
+
+  size_t heap_used() const      { return _heap_used; }
+  size_t young_gen_used() const { return _young_gen_used; }
+  size_t old_gen_used() const   { return _old_gen_used; }
+  size_t metadata_used() const  { return _metadata_used; }
+
+private:
+  size_t _heap_used;
+  size_t _young_gen_used;
+  size_t _old_gen_used;
+  size_t _metadata_used;
+};
+
 #endif // SHARE_VM_GC_PARALLEL_PARALLELSCAVENGEHEAP_HPP
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,7 +31,8 @@
 #include "gc/parallel/psParallelCompact.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -251,14 +252,6 @@
 
   cm->set_region_stack_index(which_stack_index);
   cm->set_region_stack(ParCompactionManager::region_list(which_stack_index));
-  if (TraceDynamicGCThreads) {
-    gclog_or_tty->print_cr("StealRegionCompactionTask::do_it "
-                           "region_stack_index %d region_stack = " PTR_FORMAT " "
-                           " empty (%d) use all workers %d",
-    which_stack_index, p2i(ParCompactionManager::region_list(which_stack_index)),
-    cm->region_stack()->is_empty(),
-    use_all_workers);
-  }
 
   // Has to drain stacks first because there may be regions on
   // preloaded onto the stack and this thread may never have
@@ -323,14 +316,6 @@
   }
 
   cm->set_region_stack(ParCompactionManager::region_list(which_stack_index));
-  if (TraceDynamicGCThreads) {
-    gclog_or_tty->print_cr("DrainStacksCompactionTask::do_it which = %d "
-                           "which_stack_index = %d/empty(%d) "
-                           "use all workers %d",
-                           which, which_stack_index,
-                           cm->region_stack()->is_empty(),
-                           use_all_workers);
-  }
 
   cm->set_region_stack_index(which_stack_index);
 
@@ -346,13 +331,6 @@
            "region_stack and region_stack_index are inconsistent");
     ParCompactionManager::push_recycled_stack_index(cm->region_stack_index());
 
-    if (TraceDynamicGCThreads) {
-      void* old_region_stack = (void*) cm->region_stack();
-      int old_region_stack_index = cm->region_stack_index();
-      gclog_or_tty->print_cr("Pushing region stack " PTR_FORMAT "/%d",
-        p2i(old_region_stack), old_region_stack_index);
-    }
-
     cm->set_region_stack(NULL);
     cm->set_region_stack_index((uint)max_uintx);
   }
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
+#include "logging/log.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/top.hpp"
 
@@ -159,14 +160,10 @@
     _major_pause_young_estimator->update(eden_size_in_mbytes,
       major_pause_in_ms);
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: "
-        "major gc cost: %f  average: %f", collection_cost,
-        avg_major_gc_cost()->average());
-      gclog_or_tty->print_cr("  major pause: %f major period %f",
-        major_pause_in_ms,
-        _latest_major_mutator_interval_seconds * MILLIUNITS);
-    }
+    log_trace(gc, ergo)("psAdaptiveSizePolicy::major_collection_end: major gc cost: %f  average: %f",
+                        collection_cost,avg_major_gc_cost()->average());
+    log_trace(gc, ergo)("  major pause: %f major period %f",
+                        major_pause_in_ms, _latest_major_mutator_interval_seconds * MILLIUNITS);
 
     // Calculate variable used to estimate collection cost vs. gen sizes
     assert(collection_cost >= 0.0, "Expected to be non-negative");
@@ -197,19 +194,11 @@
   // A similar test is done in the scavenge's should_attempt_scavenge().  If
   // this is changed, decide if that test should also be changed.
   bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
-  if (PrintGCDetails && Verbose) {
-    if (result) {
-      gclog_or_tty->print("  full after scavenge: ");
-    } else {
-      gclog_or_tty->print("  no full after scavenge: ");
-    }
-    gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
-      " padded_average_promoted " SIZE_FORMAT
-      " free in old gen " SIZE_FORMAT,
-      (size_t) average_promoted_in_bytes(),
-      (size_t) padded_average_promoted_in_bytes(),
-      old_free_in_bytes);
-  }
+  log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT,
+                      result ? "Full" : "No full",
+                      (size_t) average_promoted_in_bytes(),
+                      (size_t) padded_average_promoted_in_bytes(),
+                      old_free_in_bytes);
   return result;
 }
 
@@ -361,26 +350,24 @@
 
   // Note we make the same tests as in the code block below;  the code
   // seems a little easier to read with the printing in another block.
-  if (PrintAdaptiveSizePolicy) {
-    if (desired_eden_size > eden_limit) {
-      gclog_or_tty->print_cr(
-            "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
-            " desired_eden_size: " SIZE_FORMAT
-            " old_eden_size: " SIZE_FORMAT
-            " eden_limit: " SIZE_FORMAT
-            " cur_eden: " SIZE_FORMAT
-            " max_eden_size: " SIZE_FORMAT
-            " avg_young_live: " SIZE_FORMAT,
-            desired_eden_size, _eden_size, eden_limit, cur_eden,
-            max_eden_size, (size_t)avg_young_live()->average());
-    }
-    if (gc_cost() > gc_cost_limit) {
-      gclog_or_tty->print_cr(
-            "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
-            " gc_cost: %f "
-            " GCTimeLimit: " UINTX_FORMAT,
-            gc_cost(), GCTimeLimit);
-    }
+  if (desired_eden_size > eden_limit) {
+    log_debug(gc, ergo)(
+          "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
+          " desired_eden_size: " SIZE_FORMAT
+          " old_eden_size: " SIZE_FORMAT
+          " eden_limit: " SIZE_FORMAT
+          " cur_eden: " SIZE_FORMAT
+          " max_eden_size: " SIZE_FORMAT
+          " avg_young_live: " SIZE_FORMAT,
+          desired_eden_size, _eden_size, eden_limit, cur_eden,
+          max_eden_size, (size_t)avg_young_live()->average());
+  }
+  if (gc_cost() > gc_cost_limit) {
+    log_debug(gc, ergo)(
+          "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
+          " gc_cost: %f "
+          " GCTimeLimit: " UINTX_FORMAT,
+          gc_cost(), GCTimeLimit);
   }
 
   // Align everything and make a final limit check
@@ -399,51 +386,26 @@
     desired_eden_size = MAX2(eden_limit, cur_eden);
   }
 
-  if (PrintAdaptiveSizePolicy) {
-    // Timing stats
-    gclog_or_tty->print(
-               "PSAdaptiveSizePolicy::compute_eden_space_size: costs"
-               " minor_time: %f"
-               " major_cost: %f"
-               " mutator_cost: %f"
-               " throughput_goal: %f",
-               minor_gc_cost(), major_gc_cost(), mutator_cost(),
-               _throughput_goal);
+  log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_eden_space_size: costs minor_time: %f major_cost: %f mutator_cost: %f throughput_goal: %f",
+             minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
+
+  log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %fpause_goal: %f",
+                      _avg_minor_pause->padded_average(),
+                      _avg_major_pause->padded_average(),
+                      _avg_minor_interval->average(),
+                      _avg_major_interval->average(),
+                      gc_pause_goal_sec());
 
-    // We give more details if Verbose is set
-    if (Verbose) {
-      gclog_or_tty->print( " minor_pause: %f"
-                  " major_pause: %f"
-                  " minor_interval: %f"
-                  " major_interval: %f"
-                  " pause_goal: %f",
-                  _avg_minor_pause->padded_average(),
-                  _avg_major_pause->padded_average(),
-                  _avg_minor_interval->average(),
-                  _avg_major_interval->average(),
-                  gc_pause_goal_sec());
-    }
+  log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
+                      live_space(), free_space());
 
-    // Footprint stats
-    gclog_or_tty->print( " live_space: " SIZE_FORMAT
-                " free_space: " SIZE_FORMAT,
-                live_space(), free_space());
-    // More detail
-    if (Verbose) {
-      gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
-                  " avg_young_live: " SIZE_FORMAT
-                  " avg_old_live: " SIZE_FORMAT,
-                  (size_t)_avg_base_footprint->average(),
-                  (size_t)avg_young_live()->average(),
-                  (size_t)avg_old_live()->average());
-    }
+  log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
+                      (size_t)_avg_base_footprint->average(),
+                      (size_t)avg_young_live()->average(),
+                      (size_t)avg_old_live()->average());
 
-    // And finally, our old and new sizes.
-    gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT
-               " desired_eden_size: " SIZE_FORMAT,
-               _eden_size, desired_eden_size);
-    gclog_or_tty->cr();
-  }
+  log_debug(gc, ergo)("Old eden_size: " SIZE_FORMAT " desired_eden_size: " SIZE_FORMAT,
+                      _eden_size, desired_eden_size);
 
   set_eden_size(desired_eden_size);
 }
@@ -564,27 +526,25 @@
 
   // Note we make the same tests as in the code block below;  the code
   // seems a little easier to read with the printing in another block.
-  if (PrintAdaptiveSizePolicy) {
-    if (desired_promo_size > promo_limit)  {
-      // "free_in_old_gen" was the original value for used for promo_limit
-      size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
-      gclog_or_tty->print_cr(
-            "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
-            " desired_promo_size: " SIZE_FORMAT
-            " promo_limit: " SIZE_FORMAT
-            " free_in_old_gen: " SIZE_FORMAT
-            " max_old_gen_size: " SIZE_FORMAT
-            " avg_old_live: " SIZE_FORMAT,
-            desired_promo_size, promo_limit, free_in_old_gen,
-            max_old_gen_size, (size_t) avg_old_live()->average());
-    }
-    if (gc_cost() > gc_cost_limit) {
-      gclog_or_tty->print_cr(
-            "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
-            " gc_cost: %f "
-            " GCTimeLimit: " UINTX_FORMAT,
-            gc_cost(), GCTimeLimit);
-    }
+  if (desired_promo_size > promo_limit)  {
+    // "free_in_old_gen" was the original value for used for promo_limit
+    size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
+    log_debug(gc, ergo)(
+          "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
+          " desired_promo_size: " SIZE_FORMAT
+          " promo_limit: " SIZE_FORMAT
+          " free_in_old_gen: " SIZE_FORMAT
+          " max_old_gen_size: " SIZE_FORMAT
+          " avg_old_live: " SIZE_FORMAT,
+          desired_promo_size, promo_limit, free_in_old_gen,
+          max_old_gen_size, (size_t) avg_old_live()->average());
+  }
+  if (gc_cost() > gc_cost_limit) {
+    log_debug(gc, ergo)(
+          "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
+          " gc_cost: %f "
+          " GCTimeLimit: " UINTX_FORMAT,
+          gc_cost(), GCTimeLimit);
   }
 
   // Align everything and make a final limit check
@@ -596,51 +556,28 @@
   // And one last limit check, now that we've aligned things.
   desired_promo_size = MIN2(desired_promo_size, promo_limit);
 
-  if (PrintAdaptiveSizePolicy) {
-    // Timing stats
-    gclog_or_tty->print(
-               "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
-               " minor_time: %f"
-               " major_cost: %f"
-               " mutator_cost: %f"
-               " throughput_goal: %f",
-               minor_gc_cost(), major_gc_cost(), mutator_cost(),
-               _throughput_goal);
+  // Timing stats
+  log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_old_gen_free_space: costs minor_time: %f major_cost: %f  mutator_cost: %f throughput_goal: %f",
+             minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
+
+  log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %f pause_goal: %f",
+                      _avg_minor_pause->padded_average(),
+                      _avg_major_pause->padded_average(),
+                      _avg_minor_interval->average(),
+                      _avg_major_interval->average(),
+                      gc_pause_goal_sec());
 
-    // We give more details if Verbose is set
-    if (Verbose) {
-      gclog_or_tty->print( " minor_pause: %f"
-                  " major_pause: %f"
-                  " minor_interval: %f"
-                  " major_interval: %f"
-                  " pause_goal: %f",
-                  _avg_minor_pause->padded_average(),
-                  _avg_major_pause->padded_average(),
-                  _avg_minor_interval->average(),
-                  _avg_major_interval->average(),
-                  gc_pause_goal_sec());
-    }
+  // Footprint stats
+  log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
+                      live_space(), free_space());
 
-    // Footprint stats
-    gclog_or_tty->print( " live_space: " SIZE_FORMAT
-                " free_space: " SIZE_FORMAT,
-                live_space(), free_space());
-    // More detail
-    if (Verbose) {
-      gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
-                  " avg_young_live: " SIZE_FORMAT
-                  " avg_old_live: " SIZE_FORMAT,
-                  (size_t)_avg_base_footprint->average(),
-                  (size_t)avg_young_live()->average(),
-                  (size_t)avg_old_live()->average());
-    }
+  log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
+                      (size_t)_avg_base_footprint->average(),
+                      (size_t)avg_young_live()->average(),
+                      (size_t)avg_old_live()->average());
 
-    // And finally, our old and new sizes.
-    gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
-               " desired_promo_size: " SIZE_FORMAT,
-               _promo_size, desired_promo_size);
-    gclog_or_tty->cr();
-  }
+  log_debug(gc, ergo)("Old promo_size: " SIZE_FORMAT " desired_promo_size: " SIZE_FORMAT,
+                      _promo_size, desired_promo_size);
 
   set_promo_size(desired_promo_size);
 }
@@ -719,14 +656,12 @@
     }
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr(
-      "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
-      "adjusting gen sizes for major pause (avg %f goal %f). "
-      "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
-      _avg_major_pause->average(), gc_pause_goal_sec(),
-      *desired_promo_size_ptr, promo_heap_delta);
-  }
+  log_trace(gc, ergo)(
+    "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
+    "adjusting gen sizes for major pause (avg %f goal %f). "
+    "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
+    _avg_major_pause->average(), gc_pause_goal_sec(),
+    *desired_promo_size_ptr, promo_heap_delta);
 }
 
 void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
@@ -740,14 +675,12 @@
   if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
     adjust_eden_for_minor_pause_time(is_full_gc, desired_eden_size_ptr);
   }
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr(
-      "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
-      "adjusting gen sizes for major pause (avg %f goal %f). "
-      "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
-      _avg_major_pause->average(), gc_pause_goal_sec(),
-      *desired_eden_size_ptr, eden_heap_delta);
-  }
+  log_trace(gc, ergo)(
+    "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
+    "adjusting gen sizes for major pause (avg %f goal %f). "
+    "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
+    _avg_major_pause->average(), gc_pause_goal_sec(),
+    *desired_eden_size_ptr, eden_heap_delta);
 }
 
 void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
@@ -761,13 +694,8 @@
     return;
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput("
-      "is_full: %d, promo: " SIZE_FORMAT "): ",
-      is_full_gc, *desired_promo_size_ptr);
-    gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
-      "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
-  }
+  log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_promo_for_throughput(is_full: %d, promo: " SIZE_FORMAT "): mutator_cost %f  major_gc_cost %f minor_gc_cost %f",
+                      is_full_gc, *desired_promo_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost());
 
   // Tenured generation
   if (is_full_gc) {
@@ -780,12 +708,8 @@
       double scale_by_ratio = major_gc_cost() / gc_cost();
       scaled_promo_heap_delta =
         (size_t) (scale_by_ratio * (double) promo_heap_delta);
-      if (PrintAdaptiveSizePolicy && Verbose) {
-        gclog_or_tty->print_cr(
-          "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
-          SIZE_FORMAT,
-          promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
-      }
+      log_trace(gc, ergo)("Scaled tenured increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
+                          promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
     } else if (major_gc_cost() >= 0.0) {
       // Scaling is not going to work.  If the major gc time is the
       // larger, give it a full increment.
@@ -839,13 +763,10 @@
         _old_gen_change_for_major_throughput++;
     }
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr(
-          "adjusting tenured gen for throughput (avg %f goal %f). "
-          "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
-          mutator_cost(), _throughput_goal,
-          *desired_promo_size_ptr, scaled_promo_heap_delta);
-    }
+    log_trace(gc, ergo)("Adjusting tenured gen for throughput (avg %f goal %f). desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
+                        mutator_cost(),
+                        _throughput_goal,
+                        *desired_promo_size_ptr, scaled_promo_heap_delta);
   }
 }
 
@@ -860,13 +781,8 @@
     return;
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput("
-      "is_full: %d, cur_eden: " SIZE_FORMAT "): ",
-      is_full_gc, *desired_eden_size_ptr);
-    gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
-      "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
-  }
+  log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_eden_for_throughput(is_full: %d, cur_eden: " SIZE_FORMAT "): mutator_cost %f  major_gc_cost %f minor_gc_cost %f",
+                      is_full_gc, *desired_eden_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost());
 
   // Young generation
   size_t scaled_eden_heap_delta = 0;
@@ -878,12 +794,8 @@
     assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
     scaled_eden_heap_delta =
       (size_t) (scale_by_ratio * (double) eden_heap_delta);
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr(
-        "Scaled eden increment: " SIZE_FORMAT " by %f down to "
-        SIZE_FORMAT,
-        eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
-    }
+    log_trace(gc, ergo)("Scaled eden increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
+                        eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
   } else if (minor_gc_cost() >= 0.0) {
     // Scaling is not going to work.  If the minor gc time is the
     // larger, give it a full increment.
@@ -936,13 +848,8 @@
       _young_gen_change_for_minor_throughput++;
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr(
-        "adjusting eden for throughput (avg %f goal %f). desired_eden_size "
-        SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
-      mutator_cost(), _throughput_goal,
-        *desired_eden_size_ptr, scaled_eden_heap_delta);
-  }
+    log_trace(gc, ergo)("Adjusting eden for throughput (avg %f goal %f). desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
+                        mutator_cost(), _throughput_goal, *desired_eden_size_ptr, scaled_eden_heap_delta);
 }
 
 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
@@ -955,15 +862,13 @@
 
   size_t reduced_size = desired_promo_size - change;
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr(
-      "AdaptiveSizePolicy::adjust_promo_for_footprint "
-      "adjusting tenured gen for footprint. "
-      "starting promo size " SIZE_FORMAT
-      " reduced promo size " SIZE_FORMAT
-      " promo delta " SIZE_FORMAT,
-      desired_promo_size, reduced_size, change );
-  }
+  log_trace(gc, ergo)(
+    "AdaptiveSizePolicy::adjust_promo_for_footprint "
+    "adjusting tenured gen for footprint. "
+    "starting promo size " SIZE_FORMAT
+    " reduced promo size " SIZE_FORMAT
+    " promo delta " SIZE_FORMAT,
+    desired_promo_size, reduced_size, change );
 
   assert(reduced_size <= desired_promo_size, "Inconsistent result");
   return reduced_size;
@@ -979,15 +884,13 @@
 
   size_t reduced_size = desired_eden_size - change;
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr(
-      "AdaptiveSizePolicy::adjust_eden_for_footprint "
-      "adjusting eden for footprint. "
-      " starting eden size " SIZE_FORMAT
-      " reduced eden size " SIZE_FORMAT
-      " eden delta " SIZE_FORMAT,
-      desired_eden_size, reduced_size, change);
-  }
+  log_trace(gc, ergo)(
+    "AdaptiveSizePolicy::adjust_eden_for_footprint "
+    "adjusting eden for footprint. "
+    " starting eden size " SIZE_FORMAT
+    " reduced eden size " SIZE_FORMAT
+    " eden delta " SIZE_FORMAT,
+    desired_eden_size, reduced_size, change);
 
   assert(reduced_size <= desired_eden_size, "Inconsistent result");
   return reduced_size;
@@ -1187,33 +1090,14 @@
   // the amount of old gen free space is less than what we expect to
   // promote).
 
-  if (PrintAdaptiveSizePolicy) {
-    // A little more detail if Verbose is on
-    if (Verbose) {
-      gclog_or_tty->print( "  avg_survived: %f"
-                  "  avg_deviation: %f",
-                  _avg_survived->average(),
-                  _avg_survived->deviation());
-    }
-
-    gclog_or_tty->print( "  avg_survived_padded_avg: %f",
-                _avg_survived->padded_average());
+  log_trace(gc, ergo)("avg_survived: %f  avg_deviation: %f", _avg_survived->average(), _avg_survived->deviation());
+  log_debug(gc, ergo)("avg_survived_padded_avg: %f", _avg_survived->padded_average());
 
-    if (Verbose) {
-      gclog_or_tty->print( "  avg_promoted_avg: %f"
-                  "  avg_promoted_dev: %f",
-                  avg_promoted()->average(),
-                  avg_promoted()->deviation());
-    }
-
-    gclog_or_tty->print_cr( "  avg_promoted_padded_avg: %f"
-                "  avg_pretenured_padded_avg: %f"
-                "  tenuring_thresh: %d"
-                "  target_size: " SIZE_FORMAT,
-                avg_promoted()->padded_average(),
-                _avg_pretenured->padded_average(),
-                tenuring_threshold, target_size);
-  }
+  log_trace(gc, ergo)("avg_promoted_avg: %f  avg_promoted_dev: %f", avg_promoted()->average(), avg_promoted()->deviation());
+  log_debug(gc, ergo)("avg_promoted_padded_avg: %f  avg_pretenured_padded_avg: %f  tenuring_thresh: %d  target_size: " SIZE_FORMAT,
+                      avg_promoted()->padded_average(),
+                      _avg_pretenured->padded_average(),
+                      tenuring_threshold, target_size);
 
   set_survivor_size(target_size);
 
@@ -1233,24 +1117,22 @@
   }
   avg_promoted()->sample(promoted);
 
-  if (PrintAdaptiveSizePolicy) {
-    gclog_or_tty->print_cr(
-                  "AdaptiveSizePolicy::update_averages:"
-                  "  survived: "  SIZE_FORMAT
-                  "  promoted: "  SIZE_FORMAT
-                  "  overflow: %s",
-                  survived, promoted, is_survivor_overflow ? "true" : "false");
-  }
+  log_trace(gc, ergo)("AdaptiveSizePolicy::update_averages:  survived: "  SIZE_FORMAT "  promoted: "  SIZE_FORMAT "  overflow: %s",
+                      survived, promoted, is_survivor_overflow ? "true" : "false");
 }
 
-bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
-  const {
+bool PSAdaptiveSizePolicy::print() const {
+
+  if (!UseAdaptiveSizePolicy) {
+    return false;
+  }
 
-  if (!UseAdaptiveSizePolicy) return false;
+  if (AdaptiveSizePolicy::print()) {
+    AdaptiveSizePolicy::print_tenuring_threshold(PSScavenge::tenuring_threshold());
+    return true;
+  }
 
-  return AdaptiveSizePolicy::print_adaptive_size_policy_on(
-                          st,
-                          PSScavenge::tenuring_threshold());
+  return false;
 }
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -395,7 +395,7 @@
                        size_t promoted);
 
   // Printing support
-  virtual bool print_adaptive_size_policy_on(outputStream* st) const;
+  virtual bool print() const;
 
   // Decay the supplemental growth additive.
   void decay_supplemental_growth(bool is_full_gc);
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,6 +32,7 @@
 #include "gc/parallel/psOldGen.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/iterator.inline.hpp"
 #include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceMirrorKlass.inline.hpp"
@@ -229,30 +230,18 @@
 static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
   T heap_oop = oopDesc::load_heap_oop(referent_addr);
-  debug_only(
-    if(TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
-    }
-  )
+  log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
   if (!oopDesc::is_null(heap_oop)) {
     oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
     if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
         PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
       // reference already enqueued, referent will be traversed later
       klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
-        }
-      )
+      log_develop_trace(gc, ref)("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
       return;
     } else {
       // treat referent as normal oop
-      debug_only(
-        if(TraceReferenceGC && PrintGCDetails) {
-          gclog_or_tty->print_cr("       Non NULL normal " PTR_FORMAT, p2i(obj));
-        }
-      )
+      log_develop_trace(gc, ref)("       Non NULL normal " PTR_FORMAT, p2i(obj));
       cm->mark_and_push(referent_addr);
     }
   }
@@ -262,12 +251,7 @@
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
     T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-    debug_only(
-      if(TraceReferenceGC && PrintGCDetails) {
-        gclog_or_tty->print_cr("   Process discovered as normal "
-                               PTR_FORMAT, p2i(discovered_addr));
-      }
-    )
+    log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     cm->mark_and_push(discovered_addr);
   }
   cm->mark_and_push(next_addr);
--- a/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psMarkSweep.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -41,11 +41,12 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/fprofiler.hpp"
@@ -137,8 +138,6 @@
   // We need to track unique mark sweep invocations as well.
   _total_invocations++;
 
-  AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
-
   heap->print_heap_before_gc();
   heap->trace_heap_before_gc(_gc_tracer);
 
@@ -148,7 +147,7 @@
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyBeforeGC:");
+    Universe::verify("Before GC");
   }
 
   // Verify object start arrays
@@ -167,8 +166,8 @@
   {
     HandleMark hm;
 
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
+    GCTraceCPUTime tcpu;
+    GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause, true);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -180,13 +179,9 @@
     CodeCache::gc_prologue();
     BiasedLocking::preserve_marks();
 
-    // Capture heap size before collection for printing.
-    size_t prev_used = heap->used();
-
     // Capture metadata size before collection for sizing.
     size_t metadata_prev_used = MetaspaceAux::used_bytes();
 
-    // For PrintGCDetails
     size_t old_gen_prev_used = old_gen->used_in_bytes();
     size_t young_gen_prev_used = young_gen->used_in_bytes();
 
@@ -266,17 +261,9 @@
 
     if (UseAdaptiveSizePolicy) {
 
-      if (PrintAdaptiveSizePolicy) {
-        gclog_or_tty->print("AdaptiveSizeStart: ");
-        gclog_or_tty->stamp();
-        gclog_or_tty->print_cr(" collection: %d ",
-                       heap->total_collections());
-        if (Verbose) {
-          gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
-            " young_gen_capacity: " SIZE_FORMAT,
-            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
-        }
-      }
+     log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());
+     log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
+                         old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
 
       // Don't check if the size_policy is ready here.  Let
       // the size_policy check that internally.
@@ -333,10 +320,7 @@
         heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
                                size_policy->calculated_survivor_size_in_bytes());
       }
-      if (PrintAdaptiveSizePolicy) {
-        gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
-                       heap->total_collections());
-      }
+      log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
     }
 
     if (UsePerfData) {
@@ -354,18 +338,9 @@
 
     if (TraceOldGenTime) accumulated_time()->stop();
 
-    if (PrintGC) {
-      if (PrintGCDetails) {
-        // Don't print a GC timestamp here.  This is after the GC so
-        // would be confusing.
-        young_gen->print_used_change(young_gen_prev_used);
-        old_gen->print_used_change(old_gen_prev_used);
-      }
-      heap->print_heap_change(prev_used);
-      if (PrintGCDetails) {
-        MetaspaceAux::print_metaspace_change(metadata_prev_used);
-      }
-    }
+    young_gen->print_used_change(young_gen_prev_used);
+    old_gen->print_used_change(old_gen_prev_used);
+    MetaspaceAux::print_metaspace_change(metadata_prev_used);
 
     // Track memory usage and detect low memory
     MemoryService::track_memory_usage();
@@ -374,7 +349,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyAfterGC:");
+    Universe::verify("After GC");
   }
 
   // Re-verify object start arrays
@@ -398,6 +373,8 @@
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+  AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
+
   _gc_timer->register_gc_end();
 
   _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
@@ -443,8 +420,7 @@
     return false; // Respect young gen minimum size.
   }
 
-  if (TraceAdaptiveGCBoundary && Verbose) {
-    gclog_or_tty->print(" absorbing " SIZE_FORMAT "K:  "
+  log_trace(heap, ergo)(" absorbing " SIZE_FORMAT "K:  "
                         "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
                         "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
                         "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
@@ -453,7 +429,6 @@
                         young_gen->from_space()->used_in_bytes() / K,
                         young_gen->to_space()->used_in_bytes() / K,
                         young_gen->capacity_in_bytes() / K, new_young_size / K);
-  }
 
   // Fill the unused part of the old gen.
   MutableSpace* const old_space = old_gen->object_space();
@@ -517,7 +492,7 @@
 
 void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", _gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
 
@@ -576,7 +551,7 @@
 
 
 void PSMarkSweep::mark_sweep_phase2() {
-  GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", _gc_timer);
 
   // Now all live objects are marked, compute the new object addresses.
 
@@ -603,7 +578,7 @@
 
 void PSMarkSweep::mark_sweep_phase3() {
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", _gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSYoungGen* young_gen = heap->young_gen();
@@ -643,7 +618,7 @@
 
 void PSMarkSweep::mark_sweep_phase4() {
   EventMark m("4 compact heap");
-  GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 4: Move objects", _gc_timer);
 
   // All pointers are now adjusted, move objects accordingly
 
--- a/hotspot/src/share/vm/gc/parallel/psOldGen.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psOldGen.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/shared/cardTableModRefBS.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 
@@ -256,10 +257,8 @@
     success = expand_to_reserved();
   }
 
-  if (PrintGC && Verbose) {
-    if (success && GC_locker::is_active_and_needs_gc()) {
-      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
-    }
+  if (success && GC_locker::is_active_and_needs_gc()) {
+    log_debug(gc)("Garbage collection disabled, expanded heap instead");
   }
 }
 
@@ -291,13 +290,11 @@
     }
   }
 
-  if (result && Verbose && PrintGC) {
+  if (result) {
     size_t new_mem_size = virtual_space()->committed_size();
     size_t old_mem_size = new_mem_size - bytes;
-    gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
-                                       SIZE_FORMAT "K to "
-                                       SIZE_FORMAT "K",
-                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
+    log_debug(gc)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                  name(), old_mem_size/K, bytes/K, new_mem_size/K);
   }
 
   return result;
@@ -326,14 +323,10 @@
     virtual_space()->shrink_by(bytes);
     post_resize();
 
-    if (Verbose && PrintGC) {
-      size_t new_mem_size = virtual_space()->committed_size();
-      size_t old_mem_size = new_mem_size + bytes;
-      gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K by "
-                                         SIZE_FORMAT "K to "
-                                         SIZE_FORMAT "K",
-                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
-    }
+    size_t new_mem_size = virtual_space()->committed_size();
+    size_t old_mem_size = new_mem_size + bytes;
+    log_debug(gc)("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                  name(), old_mem_size/K, bytes/K, new_mem_size/K);
   }
 }
 
@@ -353,14 +346,12 @@
 
   const size_t current_size = capacity_in_bytes();
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr("AdaptiveSizePolicy::old generation size: "
-      "desired free: " SIZE_FORMAT " used: " SIZE_FORMAT
-      " new size: " SIZE_FORMAT " current size " SIZE_FORMAT
-      " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
-      desired_free_space, used_in_bytes(), new_size, current_size,
-      gen_size_limit(), min_gen_size());
-  }
+  log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: "
+    "desired free: " SIZE_FORMAT " used: " SIZE_FORMAT
+    " new size: " SIZE_FORMAT " current size " SIZE_FORMAT
+    " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
+    desired_free_space, used_in_bytes(), new_size, current_size,
+    gen_size_limit(), min_gen_size());
 
   if (new_size == current_size) {
     // No change requested
@@ -376,14 +367,10 @@
     shrink(change_bytes);
   }
 
-  if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
-    gclog_or_tty->print_cr("AdaptiveSizePolicy::old generation size: "
-                  "collection: %d "
-                  "(" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
-                  heap->total_collections(),
-                  size_before, virtual_space()->committed_size());
-  }
+  log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: collection: %d (" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
+                      ParallelScavengeHeap::heap()->total_collections(),
+                      size_before,
+                      virtual_space()->committed_size());
 }
 
 // NOTE! We need to be careful about resizing. During a GC, multiple
@@ -430,13 +417,8 @@
 void PSOldGen::print() const { print_on(tty);}
 void PSOldGen::print_on(outputStream* st) const {
   st->print(" %-15s", name());
-  if (PrintGCDetails && Verbose) {
-    st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT,
-                capacity_in_bytes(), used_in_bytes());
-  } else {
-    st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
-                capacity_in_bytes()/K, used_in_bytes()/K);
-  }
+  st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
+              capacity_in_bytes()/K, used_in_bytes()/K);
   st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
                 p2i(virtual_space()->low_boundary()),
                 p2i(virtual_space()->high()),
@@ -446,13 +428,8 @@
 }
 
 void PSOldGen::print_used_change(size_t prev_used) const {
-  gclog_or_tty->print(" [%s:", name());
-  gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                      "->" SIZE_FORMAT "K"
-                      "("  SIZE_FORMAT "K)",
-                      prev_used / K, used_in_bytes() / K,
-                      capacity_in_bytes() / K);
-  gclog_or_tty->print("]");
+  log_info(gc, heap)("%s: "  SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+      name(), prev_used / K, used_in_bytes() / K, capacity_in_bytes() / K);
 }
 
 void PSOldGen::update_counters() {
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -45,11 +45,12 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/methodData.hpp"
@@ -107,7 +108,6 @@
 ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift;
 
 SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];
-bool      PSParallelCompact::_print_phases = false;
 
 ReferenceProcessor* PSParallelCompact::_ref_processor = NULL;
 
@@ -194,21 +194,26 @@
   "old ", "eden", "from", "to  "
 };
 
-void PSParallelCompact::print_region_ranges()
-{
-  tty->print_cr("space  bottom     top        end        new_top");
-  tty->print_cr("------ ---------- ---------- ---------- ----------");
+void PSParallelCompact::print_region_ranges() {
+  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+    return;
+  }
+  LogHandle(gc, compaction, phases) log;
+  ResourceMark rm;
+  Universe::print_on(log.trace_stream());
+  log.trace("space  bottom     top        end        new_top");
+  log.trace("------ ---------- ---------- ---------- ----------");
 
   for (unsigned int id = 0; id < last_space_id; ++id) {
     const MutableSpace* space = _space_info[id].space();
-    tty->print_cr("%u %s "
-                  SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
-                  SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
-                  id, space_names[id],
-                  summary_data().addr_to_region_idx(space->bottom()),
-                  summary_data().addr_to_region_idx(space->top()),
-                  summary_data().addr_to_region_idx(space->end()),
-                  summary_data().addr_to_region_idx(_space_info[id].new_top()));
+    log.trace("%u %s "
+              SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
+              SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
+              id, space_names[id],
+              summary_data().addr_to_region_idx(space->bottom()),
+              summary_data().addr_to_region_idx(space->top()),
+              summary_data().addr_to_region_idx(space->end()),
+              summary_data().addr_to_region_idx(_space_info[id].new_top()));
   }
 }
 
@@ -220,13 +225,14 @@
 
   ParallelCompactData& sd = PSParallelCompact::summary_data();
   size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0;
-  tty->print_cr(REGION_IDX_FORMAT " " PTR_FORMAT " "
-                REGION_IDX_FORMAT " " PTR_FORMAT " "
-                REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "
-                REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",
-                i, p2i(c->data_location()), dci, p2i(c->destination()),
-                c->partial_obj_size(), c->live_obj_size(),
-                c->data_size(), c->source_region(), c->destination_count());
+  log_develop_trace(gc, compaction, phases)(
+      REGION_IDX_FORMAT " " PTR_FORMAT " "
+      REGION_IDX_FORMAT " " PTR_FORMAT " "
+      REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "
+      REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",
+      i, p2i(c->data_location()), dci, p2i(c->destination()),
+      c->partial_obj_size(), c->live_obj_size(),
+      c->data_size(), c->source_region(), c->destination_count());
 
 #undef  REGION_IDX_FORMAT
 #undef  REGION_DATA_FORMAT
@@ -252,13 +258,17 @@
     ++i;
   }
 
-  tty->print_cr("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);
+  log_develop_trace(gc, compaction, phases)("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);
 }
 
 void
 print_generic_summary_data(ParallelCompactData& summary_data,
                            SpaceInfo* space_info)
 {
+  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+    return;
+  }
+
   for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) {
     const MutableSpace* space = space_info[id].space();
     print_generic_summary_data(summary_data, space->bottom(),
@@ -267,20 +277,6 @@
 }
 
 void
-print_initial_summary_region(size_t i,
-                             const ParallelCompactData::RegionData* c,
-                             bool newline = true)
-{
-  tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
-             SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
-             SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
-             i, p2i(c->destination()),
-             c->partial_obj_size(), c->live_obj_size(),
-             c->data_size(), c->source_region(), c->destination_count());
-  if (newline) tty->cr();
-}
-
-void
 print_initial_summary_data(ParallelCompactData& summary_data,
                            const MutableSpace* space) {
   if (space->top() == space->bottom()) {
@@ -299,7 +295,12 @@
   size_t full_region_count = 0;
   size_t i = summary_data.addr_to_region_idx(space->bottom());
   while (i < end_region && summary_data.region(i)->data_size() == region_size) {
-    print_initial_summary_region(i, summary_data.region(i));
+    ParallelCompactData::RegionData* c = summary_data.region(i);
+    log_develop_trace(gc, compaction, phases)(
+        SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
+        i, p2i(c->destination()),
+        c->partial_obj_size(), c->live_obj_size(),
+        c->data_size(), c->source_region(), c->destination_count());
     ++full_region_count;
     ++i;
   }
@@ -328,9 +329,15 @@
             max_live_to_right = live_to_right;
     }
 
-    print_initial_summary_region(i, c, false);
-    tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
-                  reclaimed_ratio, dead_to_right, live_to_right);
+    ParallelCompactData::RegionData* c = summary_data.region(i);
+    log_develop_trace(gc, compaction, phases)(
+        SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d"
+        "%12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
+        i, p2i(c->destination()),
+        c->partial_obj_size(), c->live_obj_size(),
+        c->data_size(), c->source_region(), c->destination_count(),
+        reclaimed_ratio, dead_to_right, live_to_right);
+
 
     live_to_right -= c->data_size();
     ++i;
@@ -338,18 +345,25 @@
 
   // Any remaining regions are empty.  Print one more if there is one.
   if (i < end_region) {
-    print_initial_summary_region(i, summary_data.region(i));
+    ParallelCompactData::RegionData* c = summary_data.region(i);
+    log_develop_trace(gc, compaction, phases)(
+        SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
+         i, p2i(c->destination()),
+         c->partial_obj_size(), c->live_obj_size(),
+         c->data_size(), c->source_region(), c->destination_count());
   }
 
-  tty->print_cr("max:  " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
-                "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
-                max_reclaimed_ratio_region, max_dead_to_right,
-                max_live_to_right, max_reclaimed_ratio);
+  log_develop_trace(gc, compaction, phases)("max:  " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
+                                            max_reclaimed_ratio_region, max_dead_to_right, max_live_to_right, max_reclaimed_ratio);
 }
 
 void
 print_initial_summary_data(ParallelCompactData& summary_data,
                            SpaceInfo* space_info) {
+  if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
+    return;
+  }
+
   unsigned int id = PSParallelCompact::old_space_id;
   const MutableSpace* space;
   do {
@@ -607,11 +621,7 @@
                                          sr->partial_obj_size()));
     const size_t end_idx = addr_to_region_idx(target_end);
 
-    if (TraceParallelOldGCSummaryPhase) {
-        gclog_or_tty->print_cr("split:  clearing source_region field in ["
-                               SIZE_FORMAT ", " SIZE_FORMAT ")",
-                               beg_idx, end_idx);
-    }
+    log_develop_trace(gc, compaction, phases)("split:  clearing source_region field in [" SIZE_FORMAT ", " SIZE_FORMAT ")", beg_idx, end_idx);
     for (size_t idx = beg_idx; idx < end_idx; ++idx) {
       _region_data[idx].set_source_region(0);
     }
@@ -631,27 +641,22 @@
   *target_next = split_destination + partial_obj_size;
   HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size;
 
-  if (TraceParallelOldGCSummaryPhase) {
+  if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
     const char * split_type = partial_obj_size == 0 ? "easy" : "hard";
-    gclog_or_tty->print_cr("%s split:  src=" PTR_FORMAT " src_c=" SIZE_FORMAT
-                           " pos=" SIZE_FORMAT,
-                           split_type, p2i(source_next), split_region,
-                           partial_obj_size);
-    gclog_or_tty->print_cr("%s split:  dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT
-                           " tn=" PTR_FORMAT,
-                           split_type, p2i(split_destination),
-                           addr_to_region_idx(split_destination),
-                           p2i(*target_next));
+    log_develop_trace(gc, compaction, phases)("%s split:  src=" PTR_FORMAT " src_c=" SIZE_FORMAT " pos=" SIZE_FORMAT,
+                                              split_type, p2i(source_next), split_region, partial_obj_size);
+    log_develop_trace(gc, compaction, phases)("%s split:  dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT " tn=" PTR_FORMAT,
+                                              split_type, p2i(split_destination),
+                                              addr_to_region_idx(split_destination),
+                                              p2i(*target_next));
 
     if (partial_obj_size != 0) {
       HeapWord* const po_beg = split_info.destination();
       HeapWord* const po_end = po_beg + split_info.partial_obj_size();
-      gclog_or_tty->print_cr("%s split:  "
-                             "po_beg=" PTR_FORMAT " " SIZE_FORMAT " "
-                             "po_end=" PTR_FORMAT " " SIZE_FORMAT,
-                             split_type,
-                             p2i(po_beg), addr_to_region_idx(po_beg),
-                             p2i(po_end), addr_to_region_idx(po_end));
+      log_develop_trace(gc, compaction, phases)("%s split:  po_beg=" PTR_FORMAT " " SIZE_FORMAT " po_end=" PTR_FORMAT " " SIZE_FORMAT,
+                                                split_type,
+                                                p2i(po_beg), addr_to_region_idx(po_beg),
+                                                p2i(po_end), addr_to_region_idx(po_end));
     }
   }
 
@@ -664,13 +669,12 @@
                                     HeapWord* target_beg, HeapWord* target_end,
                                     HeapWord** target_next)
 {
-  if (TraceParallelOldGCSummaryPhase) {
-    HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next;
-    tty->print_cr("sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT
-                  "tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT,
-                  p2i(source_beg), p2i(source_end), p2i(source_next_val),
-                  p2i(target_beg), p2i(target_end), p2i(*target_next));
-  }
+  HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next;
+  log_develop_trace(gc, compaction, phases)(
+      "sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT
+      "tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT,
+      p2i(source_beg), p2i(source_end), p2i(source_next_val),
+      p2i(target_beg), p2i(target_end), p2i(*target_next));
 
   size_t cur_region = addr_to_region_idx(source_beg);
   const size_t end_region = addr_to_region_idx(region_align_up(source_end));
@@ -901,32 +905,6 @@
   _dwl_adjustment = normal_distribution(1.0);
 }
 
-// Simple class for storing info about the heap at the start of GC, to be used
-// after GC for comparison/printing.
-class PreGCValues {
-public:
-  PreGCValues() { }
-  PreGCValues(ParallelScavengeHeap* heap) { fill(heap); }
-
-  void fill(ParallelScavengeHeap* heap) {
-    _heap_used      = heap->used();
-    _young_gen_used = heap->young_gen()->used_in_bytes();
-    _old_gen_used   = heap->old_gen()->used_in_bytes();
-    _metadata_used  = MetaspaceAux::used_bytes();
-  };
-
-  size_t heap_used() const      { return _heap_used; }
-  size_t young_gen_used() const { return _young_gen_used; }
-  size_t old_gen_used() const   { return _old_gen_used; }
-  size_t metadata_used() const  { return _metadata_used; }
-
-private:
-  size_t _heap_used;
-  size_t _young_gen_used;
-  size_t _old_gen_used;
-  size_t _metadata_used;
-};
-
 void
 PSParallelCompact::clear_data_covering_space(SpaceId id)
 {
@@ -956,19 +934,17 @@
   DEBUG_ONLY(split_info.verify_clear();)
 }
 
-void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
+void PSParallelCompact::pre_compact()
 {
   // Update the from & to space pointers in space_info, since they are swapped
   // at each young gen gc.  Do the update unconditionally (even though a
   // promotion failure does not swap spaces) because an unknown number of young
   // collections will have swapped the spaces an unknown number of times.
-  GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Pre Compact", &_gc_timer);
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   _space_info[from_space_id].set_space(heap->young_gen()->from_space());
   _space_info[to_space_id].set_space(heap->young_gen()->to_space());
 
-  pre_gc_values->fill(heap);
-
   DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
   DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
 
@@ -987,7 +963,7 @@
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyBeforeGC:");
+    Universe::verify("Before GC");
   }
 
   // Verify object start arrays
@@ -1005,7 +981,7 @@
 
 void PSParallelCompact::post_compact()
 {
-  GCTraceTime tm("post compact", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Post Compact", &_gc_timer);
 
   for (unsigned int id = old_space_id; id < last_space_id; ++id) {
     // Clear the marking bitmap, summary data and split info.
@@ -1559,7 +1535,7 @@
     }
   }
 
-  if (TraceParallelOldGCSummaryPhase) {
+  if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
     const size_t region_size = ParallelCompactData::RegionSize;
     HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
     const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
@@ -1567,12 +1543,13 @@
     HeapWord* const new_top = _space_info[id].new_top();
     const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);
     const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
-    tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
-                  "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
-                  "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
-                  id, space->capacity_in_words(), p2i(dense_prefix_end),
-                  dp_region, dp_words / region_size,
-                  cr_words / region_size, p2i(new_top));
+    log_develop_trace(gc, compaction, phases)(
+        "id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
+        "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
+        "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
+        id, space->capacity_in_words(), p2i(dense_prefix_end),
+        dp_region, dp_words / region_size,
+        cr_words / region_size, p2i(new_top));
   }
 }
 
@@ -1582,29 +1559,27 @@
                                           SpaceId src_space_id,
                                           HeapWord* src_beg, HeapWord* src_end)
 {
-  if (TraceParallelOldGCSummaryPhase) {
-    tty->print_cr("summarizing %d [%s] into %d [%s]:  "
-                  "src=" PTR_FORMAT "-" PTR_FORMAT " "
-                  SIZE_FORMAT "-" SIZE_FORMAT " "
-                  "dst=" PTR_FORMAT "-" PTR_FORMAT " "
-                  SIZE_FORMAT "-" SIZE_FORMAT,
-                  src_space_id, space_names[src_space_id],
-                  dst_space_id, space_names[dst_space_id],
-                  p2i(src_beg), p2i(src_end),
-                  _summary_data.addr_to_region_idx(src_beg),
-                  _summary_data.addr_to_region_idx(src_end),
-                  p2i(dst_beg), p2i(dst_end),
-                  _summary_data.addr_to_region_idx(dst_beg),
-                  _summary_data.addr_to_region_idx(dst_end));
-  }
+  log_develop_trace(gc, compaction, phases)(
+      "Summarizing %d [%s] into %d [%s]:  "
+      "src=" PTR_FORMAT "-" PTR_FORMAT " "
+      SIZE_FORMAT "-" SIZE_FORMAT " "
+      "dst=" PTR_FORMAT "-" PTR_FORMAT " "
+      SIZE_FORMAT "-" SIZE_FORMAT,
+      src_space_id, space_names[src_space_id],
+      dst_space_id, space_names[dst_space_id],
+      p2i(src_beg), p2i(src_end),
+      _summary_data.addr_to_region_idx(src_beg),
+      _summary_data.addr_to_region_idx(src_end),
+      p2i(dst_beg), p2i(dst_end),
+      _summary_data.addr_to_region_idx(dst_beg),
+      _summary_data.addr_to_region_idx(dst_end));
 }
 #endif  // #ifndef PRODUCT
 
 void PSParallelCompact::summary_phase(ParCompactionManager* cm,
                                       bool maximum_compaction)
 {
-  GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer);
-  // trace("2");
+  GCTraceTime(Trace, gc, phases) tm("Summary Phase", &_gc_timer);
 
 #ifdef  ASSERT
   if (TraceParallelOldGCMarkingPhase) {
@@ -1620,14 +1595,9 @@
   // Quick summarization of each space into itself, to see how much is live.
   summarize_spaces_quick();
 
-  if (TraceParallelOldGCSummaryPhase) {
-    tty->print_cr("summary_phase:  after summarizing each space to self");
-    Universe::print();
-    NOT_PRODUCT(print_region_ranges());
-    if (Verbose) {
-      NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
-    }
-  }
+  log_develop_trace(gc, compaction, phases)("summary phase:  after summarizing each space to self");
+  NOT_PRODUCT(print_region_ranges());
+  NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
 
   // The amount of live data that will end up in old space (assuming it fits).
   size_t old_space_total_live = 0;
@@ -1701,14 +1671,9 @@
     }
   }
 
-  if (TraceParallelOldGCSummaryPhase) {
-    tty->print_cr("summary_phase:  after final summarization");
-    Universe::print();
-    NOT_PRODUCT(print_region_ranges());
-    if (Verbose) {
-      NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info));
-    }
-  }
+  log_develop_trace(gc, compaction, phases)("Summary_phase:  after final summarization");
+  NOT_PRODUCT(print_region_ranges());
+  NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
 }
 
 // This method should contain all heap-specific policy for invoking a full
@@ -1783,20 +1748,16 @@
 
   heap->pre_full_gc_dump(&_gc_timer);
 
-  _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
-
   // Make sure data structures are sane, make the heap parsable, and do other
   // miscellaneous bookkeeping.
-  PreGCValues pre_gc_values;
-  pre_compact(&pre_gc_values);
+  pre_compact();
+
+  PreGCValues pre_gc_values(heap);
 
   // Get the compaction manager reserved for the VM thread.
   ParCompactionManager* const vmthread_cm =
     ParCompactionManager::manager_array(gc_task_manager()->workers());
 
-  // Place after pre_compact() where the number of invocations is incremented.
-  AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
-
   {
     ResourceMark rm;
     HandleMark hm;
@@ -1805,8 +1766,8 @@
     gc_task_manager()->set_active_gang();
     gc_task_manager()->task_idle_workers();
 
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
+    GCTraceCPUTime tcpu;
+    GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause, true);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -1853,17 +1814,9 @@
     size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);
 
     if (UseAdaptiveSizePolicy) {
-      if (PrintAdaptiveSizePolicy) {
-        gclog_or_tty->print("AdaptiveSizeStart: ");
-        gclog_or_tty->stamp();
-        gclog_or_tty->print_cr(" collection: %d ",
-                       heap->total_collections());
-        if (Verbose) {
-          gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
-            " young_gen_capacity: " SIZE_FORMAT,
-            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
-        }
-      }
+      log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());
+      log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
+                          old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
 
       // Don't check if the size_policy is ready here.  Let
       // the size_policy check that internally.
@@ -1921,10 +1874,8 @@
         heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
                                size_policy->calculated_survivor_size_in_bytes());
       }
-      if (PrintAdaptiveSizePolicy) {
-        gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
-                       heap->total_collections());
-      }
+
+      log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
     }
 
     if (UsePerfData) {
@@ -1939,20 +1890,14 @@
     // Resize the metaspace capacity after a collection
     MetaspaceGC::compute_new_size();
 
-    if (TraceOldGenTime) accumulated_time()->stop();
-
-    if (PrintGC) {
-      if (PrintGCDetails) {
-        // No GC timestamp here.  This is after GC so it would be confusing.
-        young_gen->print_used_change(pre_gc_values.young_gen_used());
-        old_gen->print_used_change(pre_gc_values.old_gen_used());
-        heap->print_heap_change(pre_gc_values.heap_used());
-        MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
-      } else {
-        heap->print_heap_change(pre_gc_values.heap_used());
-      }
+    if (TraceOldGenTime) {
+      accumulated_time()->stop();
     }
 
+    young_gen->print_used_change(pre_gc_values.young_gen_used());
+    old_gen->print_used_change(pre_gc_values.old_gen_used());
+    MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
+
     // Track memory usage and detect low memory
     MemoryService::track_memory_usage();
     heap->update_counters();
@@ -1970,7 +1915,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyAfterGC:");
+    Universe::verify("After GC");
   }
 
   // Re-verify object start arrays
@@ -1990,13 +1935,10 @@
   heap->print_heap_after_gc();
   heap->trace_heap_after_gc(&_gc_tracer);
 
-  if (PrintGCTaskTimeStamps) {
-    gclog_or_tty->print_cr("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " "
-                           JLONG_FORMAT,
-                           marking_start.ticks(), compaction_start.ticks(),
-                           collection_exit.ticks());
-    gc_task_manager()->print_task_time_stamps();
-  }
+  log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,
+                         marking_start.ticks(), compaction_start.ticks(),
+                         collection_exit.ticks());
+  gc_task_manager()->print_task_time_stamps();
 
   heap->post_full_gc_dump(&_gc_timer);
 
@@ -2004,6 +1946,8 @@
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+  AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
+
   _gc_timer.register_gc_end();
 
   _gc_tracer.report_dense_prefix(dense_prefix(old_space_id));
@@ -2050,8 +1994,7 @@
     return false; // Respect young gen minimum size.
   }
 
-  if (TraceAdaptiveGCBoundary && Verbose) {
-    gclog_or_tty->print(" absorbing " SIZE_FORMAT "K:  "
+  log_trace(heap, ergo)(" absorbing " SIZE_FORMAT "K:  "
                         "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
                         "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
                         "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
@@ -2060,7 +2003,6 @@
                         young_gen->from_space()->used_in_bytes() / K,
                         young_gen->to_space()->used_in_bytes() / K,
                         young_gen->capacity_in_bytes() / K, new_young_size / K);
-  }
 
   // Fill the unused part of the old gen.
   MutableSpace* const old_space = old_gen->object_space();
@@ -2110,7 +2052,7 @@
                                       bool maximum_heap_compaction,
                                       ParallelOldTracer *gc_tracer) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Marking Phase", &_gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   uint parallel_gc_threads = heap->gc_task_manager()->workers();
@@ -2125,7 +2067,7 @@
   ClassLoaderDataGraph::clear_claimed_marks();
 
   {
-    GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer);
+    GCTraceTime(Trace, gc, phases) tm("Par Mark", &_gc_timer);
 
     ParallelScavengeHeap::ParStrongRootsScope psrs;
 
@@ -2154,7 +2096,7 @@
 
   // Process reference objects found during marking
   {
-    GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer);
+    GCTraceTime(Trace, gc, phases) tm("Reference Processing", &_gc_timer);
 
     ReferenceProcessorStats stats;
     if (ref_processor()->processing_is_mt()) {
@@ -2171,7 +2113,7 @@
     gc_tracer->report_gc_reference_stats(stats);
   }
 
-  GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc) tm_m("Class Unloading", &_gc_timer);
 
   // This is the point where the entire marking should have completed.
   assert(cm->marking_stacks_empty(), "Marking should have completed");
@@ -2202,7 +2144,7 @@
 
 void PSParallelCompact::adjust_roots() {
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Adjust Roots", &_gc_timer);
 
   // Need new claim bits when tracing through and adjusting pointers.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -2235,10 +2177,49 @@
   PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
 }
 
+// Helper class to print 8 region numbers per line and then print the total at the end.
+class FillableRegionLogger : public StackObj {
+private:
+  LogHandle(gc, compaction) log;
+  static const int LineLength = 8;
+  size_t _regions[LineLength];
+  int _next_index;
+  bool _enabled;
+  size_t _total_regions;
+public:
+  FillableRegionLogger() : _next_index(0), _total_regions(0), _enabled(develop_log_is_enabled(Trace, gc, compaction)) { }
+  ~FillableRegionLogger() {
+    log.trace(SIZE_FORMAT " initially fillable regions", _total_regions);
+  }
+
+  void print_line() {
+    if (!_enabled || _next_index == 0) {
+      return;
+    }
+    FormatBuffer<> line("Fillable: ");
+    for (int i = 0; i < _next_index; i++) {
+      line.append(" " SIZE_FORMAT_W(7), _regions[i]);
+    }
+    log.trace("%s", line.buffer());
+    _next_index = 0;
+  }
+
+  void handle(size_t region) {
+    if (!_enabled) {
+      return;
+    }
+    _regions[_next_index++] = region;
+    if (_next_index == LineLength) {
+      print_line();
+    }
+    _total_regions++;
+  }
+};
+
 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
                                                       uint parallel_gc_threads)
 {
-  GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Drain Task Setup", &_gc_timer);
 
   // Find the threads that are active
   unsigned int which = 0;
@@ -2263,13 +2244,13 @@
 
   const ParallelCompactData& sd = PSParallelCompact::summary_data();
 
-  size_t fillable_regions = 0;   // A count for diagnostic purposes.
   // A region index which corresponds to the tasks created above.
   // "which" must be 0 <= which < task_count
 
   which = 0;
   // id + 1 is used to test termination so unsigned  can
   // be used with an old_space_id == 0.
+  FillableRegionLogger region_logger;
   for (unsigned int id = to_space_id; id + 1 > old_space_id; --id) {
     SpaceInfo* const space_info = _space_info + id;
     MutableSpace* const space = space_info->space();
@@ -2282,16 +2263,7 @@
     for (size_t cur = end_region - 1; cur + 1 > beg_region; --cur) {
       if (sd.region(cur)->claim_unsafe()) {
         ParCompactionManager::region_list_push(which, cur);
-
-        if (TraceParallelOldGCCompactionPhase && Verbose) {
-          const size_t count_mod_8 = fillable_regions & 7;
-          if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
-          gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
-          if (count_mod_8 == 7) gclog_or_tty->cr();
-        }
-
-        NOT_PRODUCT(++fillable_regions;)
-
+        region_logger.handle(cur);
         // Assign regions to tasks in round-robin fashion.
         if (++which == task_count) {
           assert(which <= parallel_gc_threads,
@@ -2300,11 +2272,7 @@
         }
       }
     }
-  }
-
-  if (TraceParallelOldGCCompactionPhase) {
-    if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr();
-    gclog_or_tty->print_cr(SIZE_FORMAT " initially fillable regions", fillable_regions);
+    region_logger.print_line();
   }
 }
 
@@ -2312,7 +2280,7 @@
 
 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
                                                     uint parallel_gc_threads) {
-  GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Dense Prefix Task Setup", &_gc_timer);
 
   ParallelCompactData& sd = PSParallelCompact::summary_data();
 
@@ -2394,7 +2362,7 @@
                                      GCTaskQueue* q,
                                      ParallelTaskTerminator* terminator_ptr,
                                      uint parallel_gc_threads) {
-  GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Steal Task Setup", &_gc_timer);
 
   // Once a thread has drained it's stack, it should try to steal regions from
   // other threads.
@@ -2408,9 +2376,15 @@
 #ifdef ASSERT
 // Write a histogram of the number of times the block table was filled for a
 // region.
-void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
+void PSParallelCompact::write_block_fill_histogram()
 {
-  if (!TraceParallelOldGCCompactionPhase) return;
+  if (!develop_log_is_enabled(Trace, gc, compaction)) {
+    return;
+  }
+
+  LogHandle(gc, compaction) log;
+  ResourceMark rm;
+  outputStream* out = log.trace_stream();
 
   typedef ParallelCompactData::RegionData rd_t;
   ParallelCompactData& sd = summary_data();
@@ -2429,7 +2403,7 @@
       for (const rd_t* cur = beg; cur < end; ++cur) {
         ++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)];
       }
-      out->print("%u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);
+      out->print("Block fill histogram: %u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);
       for (size_t i = 0; i < histo_len; ++i) {
         out->print(" " SIZE_FORMAT_W(5) " %5.1f%%",
                    histo[i], 100.0 * histo[i] / region_cnt);
@@ -2441,8 +2415,7 @@
 #endif // #ifdef ASSERT
 
 void PSParallelCompact::compact() {
-  // trace("5");
-  GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
+  GCTraceTime(Trace, gc, phases) tm("Compaction Phase", &_gc_timer);
 
   ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
   PSOldGen* old_gen = heap->old_gen();
@@ -2458,7 +2431,7 @@
   enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
 
   {
-    GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer);
+    GCTraceTime(Trace, gc, phases) tm("Par Compact", &_gc_timer);
 
     gc_task_manager()->execute_and_wait(q);
 
@@ -2472,14 +2445,14 @@
 
   {
     // Update the deferred objects, if any.  Any compaction manager can be used.
-    GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer);
+    GCTraceTime(Trace, gc, phases) tm("Deferred Updates", &_gc_timer);
     ParCompactionManager* cm = ParCompactionManager::manager_array(0);
     for (unsigned int id = old_space_id; id < last_space_id; ++id) {
       update_deferred_objects(cm, SpaceId(id));
     }
   }
 
-  DEBUG_ONLY(write_block_fill_histogram(gclog_or_tty));
+  DEBUG_ONLY(write_block_fill_histogram());
 }
 
 #ifdef  ASSERT
@@ -3108,18 +3081,13 @@
                                                   T* referent_addr,
                                                   T* next_addr,
                                                   T* discovered_addr) {
-  if(TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj));
-    gclog_or_tty->print_cr("     referent_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(referent_addr),
-                           referent_addr ? p2i(oopDesc::load_decode_heap_oop(referent_addr)) : NULL);
-    gclog_or_tty->print_cr("     next_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(next_addr),
-                           next_addr ? p2i(oopDesc::load_decode_heap_oop(next_addr)) : NULL);
-    gclog_or_tty->print_cr("     discovered_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(discovered_addr),
-                           discovered_addr ? p2i(oopDesc::load_decode_heap_oop(discovered_addr)) : NULL);
-  }
+  log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
+  log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(referent_addr), referent_addr ? p2i(oopDesc::load_decode_heap_oop(referent_addr)) : NULL);
+  log_develop_trace(gc, ref)("     next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(next_addr), next_addr ? p2i(oopDesc::load_decode_heap_oop(next_addr)) : NULL);
+  log_develop_trace(gc, ref)("     discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(discovered_addr), discovered_addr ? p2i(oopDesc::load_decode_heap_oop(discovered_addr)) : NULL);
 }
 #endif
 
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -966,7 +966,6 @@
   static ParallelCompactData  _summary_data;
   static IsAliveClosure       _is_alive_closure;
   static SpaceInfo            _space_info[last_space_id];
-  static bool                 _print_phases;
   static AdjustPointerClosure _adjust_pointer_closure;
   static AdjustKlassClosure   _adjust_klass_closure;
 
@@ -989,13 +988,10 @@
 
   static void initialize_space_info();
 
-  // Return true if details about individual phases should be printed.
-  static inline bool print_phases();
-
   // Clear the marking bitmap and summary data that cover the specified space.
   static void clear_data_covering_space(SpaceId id);
 
-  static void pre_compact(PreGCValues* pre_gc_values);
+  static void pre_compact();
   static void post_compact();
 
   // Mark live objects
@@ -1069,7 +1065,7 @@
   // Adjust addresses in roots.  Does not adjust addresses in heap.
   static void adjust_roots();
 
-  DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);)
+  DEBUG_ONLY(static void write_block_fill_histogram();)
 
   // Move objects to new locations.
   static void compact_perm(ParCompactionManager* cm);
@@ -1260,10 +1256,6 @@
   return mark_bitmap()->is_marked(obj);
 }
 
-inline bool PSParallelCompact::print_phases() {
-  return _print_phases;
-}
-
 inline double PSParallelCompact::normal_distribution(double density) {
   assert(_dwl_initialized, "uninitialized");
   const double squared_term = (density - _dwl_mean) / _dwl_std_dev;
--- a/hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psPromotionManager.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/parallel/psScavenge.inline.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/padded.inline.hpp"
@@ -99,7 +100,7 @@
 bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) {
   bool promotion_failure_occurred = false;
 
-  TASKQUEUE_STATS_ONLY(if (PrintTaskqueue) print_taskqueue_stats());
+  TASKQUEUE_STATS_ONLY(print_taskqueue_stats());
   for (uint i = 0; i < ParallelGCThreads + 1; i++) {
     PSPromotionManager* manager = manager_array(i);
     assert(manager->claimed_stack_depth()->is_empty(), "should be empty");
@@ -128,7 +129,13 @@
 };
 
 void
-PSPromotionManager::print_taskqueue_stats(outputStream* const out) {
+PSPromotionManager::print_taskqueue_stats() {
+  if (!develop_log_is_enabled(Trace, gc, task, stats)) {
+    return;
+  }
+  LogHandle(gc, task, stats) log;
+  ResourceMark rm;
+  outputStream* out = log.trace_stream();
   out->print_cr("== GC Tasks Stats, GC %3d",
                 ParallelScavengeHeap::heap()->total_collections());
 
@@ -368,12 +375,7 @@
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
     T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-    debug_only(
-      if(TraceReferenceGC && PrintGCDetails) {
-        gclog_or_tty->print_cr("   Process discovered as normal "
-                               PTR_FORMAT, p2i(discovered_addr));
-      }
-    )
+    log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     if (PSScavenge::should_scavenge(discovered_addr)) {
       pm->claim_or_forward_depth(discovered_addr);
     }
@@ -430,13 +432,7 @@
     obj = obj->forwardee();
   }
 
-  if (TraceScavenge) {
-    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " (%d)}",
-                           "promotion-failure",
-                           obj->klass()->internal_name(),
-                           p2i(obj), obj->size());
-
-  }
+  log_develop_trace(gc, scavenge)("{promotion-failure %s " PTR_FORMAT " (%d)}", obj->klass()->internal_name(), p2i(obj), obj->size());
 
   return obj;
 }
--- a/hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psPromotionManager.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -65,7 +65,7 @@
   size_t                              _array_chunks_processed;
 
   void print_local_stats(outputStream* const out, uint i) const;
-  static void print_taskqueue_stats(outputStream* const out = gclog_or_tty);
+  static void print_taskqueue_stats();
 
   void reset_stats();
 #endif // TASKQUEUE_STATS
--- a/hotspot/src/share/vm/gc/parallel/psPromotionManager.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psPromotionManager.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,6 +31,7 @@
 #include "gc/parallel/psPromotionManager.hpp"
 #include "gc/parallel/psScavenge.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 
 inline PSPromotionManager* PSPromotionManager::manager_array(uint index) {
@@ -262,11 +263,9 @@
 
   // This code must come after the CAS test, or it will print incorrect
   // information.
-  if (TraceScavenge) {
-    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-       should_scavenge(&new_obj) ? "copying" : "tenuring",
-       new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
-  }
+  log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
+                                  should_scavenge(&new_obj) ? "copying" : "tenuring",
+                                  new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
 
   return new_obj;
 }
@@ -285,10 +284,10 @@
 
   // This code must come after the CAS test, or it will print incorrect
   // information.
-  if (TraceScavenge && o->is_forwarded()) {
-    gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
-       "forwarding",
-       new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
+  if (develop_log_is_enabled(Trace, gc, scavenge) && o->is_forwarded()) {
+    log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
+                      "forwarding",
+                      new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
   }
 
   oopDesc::encode_store_heap_oop_not_null(p, new_obj);
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -40,12 +40,13 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/spaceDecorator.hpp"
 #include "memory/resourceArea.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/fprofiler.hpp"
@@ -290,8 +291,6 @@
 
   heap->increment_total_collections();
 
-  AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
-
   if (AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) {
     // Gather the feedback data for eden occupancy.
     young_gen->eden_space()->accumulate_statistics();
@@ -303,23 +302,21 @@
   assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
   assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
 
-  size_t prev_used = heap->used();
-
   // Fill in TLABs
   heap->accumulate_statistics_all_tlabs();
   heap->ensure_parsability(true);  // retire TLABs
 
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyBeforeGC:");
+    Universe::verify("Before GC");
   }
 
   {
     ResourceMark rm;
     HandleMark hm;
 
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
+    GCTraceCPUTime tcpu;
+    GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
 
@@ -352,12 +349,7 @@
     reference_processor()->enable_discovery();
     reference_processor()->setup_policy(false);
 
-    // We track how much was promoted to the next generation for
-    // the AdaptiveSizePolicy.
-    size_t old_gen_used_before = old_gen->used_in_bytes();
-
-    // For PrintGCDetails
-    size_t young_gen_used_before = young_gen->used_in_bytes();
+    PreGCValues pre_gc_values(heap);
 
     // Reset our survivor overflow.
     set_survivor_overflow(false);
@@ -383,7 +375,7 @@
     // We'll use the promotion manager again later.
     PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
     {
-      GCTraceTime tm("Scavenge", false, false, &_gc_timer);
+      GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer);
       ParallelScavengeHeap::ParStrongRootsScope psrs;
 
       GCTaskQueue* q = GCTaskQueue::create();
@@ -425,7 +417,7 @@
 
     // Process reference objects discovered during scavenge
     {
-      GCTraceTime tm("References", false, false, &_gc_timer);
+      GCTraceTime(Debug, gc, phases) tm("References", &_gc_timer);
 
       reference_processor()->setup_policy(false); // not always_clear
       reference_processor()->set_active_mt_degree(active_workers);
@@ -454,7 +446,7 @@
     }
 
     {
-      GCTraceTime tm("StringTable", false, false, &_gc_timer);
+      GCTraceTime(Debug, gc, phases) tm("StringTable", &_gc_timer);
       // Unlink any dead interned Strings and process the remaining live ones.
       PSScavengeRootsClosure root_closure(promotion_manager);
       StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
@@ -464,9 +456,7 @@
     promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer);
     if (promotion_failure_occurred) {
       clean_up_failed_promotion();
-      if (PrintGC) {
-        gclog_or_tty->print("--");
-      }
+      log_info(gc)("Promotion failed");
     }
 
     _gc_tracer.report_tenuring_threshold(tenuring_threshold());
@@ -483,7 +473,7 @@
       young_gen->swap_spaces();
 
       size_t survived = young_gen->from_space()->used_in_bytes();
-      size_t promoted = old_gen->used_in_bytes() - old_gen_used_before;
+      size_t promoted = old_gen->used_in_bytes() - pre_gc_values.old_gen_used();
       size_policy->update_averages(_survivor_overflow, survived, promoted);
 
       // A successful scavenge should restart the GC time limit count which is
@@ -492,19 +482,9 @@
       if (UseAdaptiveSizePolicy) {
         // Calculate the new survivor size and tenuring threshold
 
-        if (PrintAdaptiveSizePolicy) {
-          gclog_or_tty->print("AdaptiveSizeStart: ");
-          gclog_or_tty->stamp();
-          gclog_or_tty->print_cr(" collection: %d ",
-                         heap->total_collections());
-
-          if (Verbose) {
-            gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
-              " young_gen_capacity: " SIZE_FORMAT,
-              old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
-          }
-        }
-
+        log_debug(gc, ergo)("AdaptiveSizeStart:  collection: %d ", heap->total_collections());
+        log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
+                            old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
 
         if (UsePerfData) {
           PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
@@ -538,13 +518,9 @@
                                                            _tenuring_threshold,
                                                            survivor_limit);
 
-       if (PrintTenuringDistribution) {
-         gclog_or_tty->cr();
-         gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u"
-                                " (max threshold " UINTX_FORMAT ")",
-                                size_policy->calculated_survivor_size_in_bytes(),
-                                _tenuring_threshold, MaxTenuringThreshold);
-       }
+       log_debug(gc, age)("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max threshold " UINTX_FORMAT ")",
+                          size_policy->calculated_survivor_size_in_bytes(),
+                          _tenuring_threshold, MaxTenuringThreshold);
 
         if (UsePerfData) {
           PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
@@ -602,10 +578,7 @@
         heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
                         size_policy->calculated_survivor_size_in_bytes());
 
-        if (PrintAdaptiveSizePolicy) {
-          gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
-                         heap->total_collections());
-        }
+        log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
       }
 
       // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can
@@ -628,7 +601,7 @@
     NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
 
     {
-      GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer);
+      GCTraceTime(Debug, gc, phases) tm("Prune Scavenge Root Methods", &_gc_timer);
 
       CodeCache::prune_scavenge_root_nmethods();
     }
@@ -649,14 +622,9 @@
 
     if (TraceYoungGenTime) accumulated_time()->stop();
 
-    if (PrintGC) {
-      if (PrintGCDetails) {
-        // Don't print a GC timestamp here.  This is after the GC so
-        // would be confusing.
-        young_gen->print_used_change(young_gen_used_before);
-      }
-      heap->print_heap_change(prev_used);
-    }
+    young_gen->print_used_change(pre_gc_values.young_gen_used());
+    old_gen->print_used_change(pre_gc_values.old_gen_used());
+    MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
 
     // Track memory usage and detect low memory
     MemoryService::track_memory_usage();
@@ -667,7 +635,7 @@
 
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyAfterGC:");
+    Universe::verify("After GC");
   }
 
   heap->print_heap_after_gc();
@@ -675,17 +643,16 @@
 
   scavenge_exit.update();
 
-  if (PrintGCTaskTimeStamps) {
-    tty->print_cr("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,
-                  scavenge_entry.ticks(), scavenge_midpoint.ticks(),
-                  scavenge_exit.ticks());
-    gc_task_manager()->print_task_time_stamps();
-  }
+  log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,
+                            scavenge_entry.ticks(), scavenge_midpoint.ticks(),
+                            scavenge_exit.ticks());
+  gc_task_manager()->print_task_time_stamps();
 
 #ifdef TRACESPINNING
   ParallelTaskTerminator::print_termination_counts();
 #endif
 
+  AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
 
   _gc_timer.register_gc_end();
 
@@ -708,9 +675,7 @@
     PSPromotionFailedClosure unforward_closure;
     young_gen->object_iterate(&unforward_closure);
 
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks", _preserved_oop_stack.size());
-    }
+    log_trace(gc, ergo)("Restoring " SIZE_FORMAT " marks", _preserved_oop_stack.size());
 
     // Restore any saved marks.
     while (!_preserved_oop_stack.is_empty()) {
@@ -772,19 +737,12 @@
   size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
   bool result = promotion_estimate < old_gen->free_in_bytes();
 
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print(result ? "  do scavenge: " : "  skip scavenge: ");
-    gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
-      " padded_average_promoted " SIZE_FORMAT
-      " free in old gen " SIZE_FORMAT,
-      (size_t) policy->average_promoted_in_bytes(),
-      (size_t) policy->padded_average_promoted_in_bytes(),
-      old_gen->free_in_bytes());
-    if (young_gen->used_in_bytes() <
-        (size_t) policy->padded_average_promoted_in_bytes()) {
-      gclog_or_tty->print_cr(" padded_promoted_average is greater"
-        " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
-    }
+  log_trace(ergo)("%s scavenge: average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT,
+                result ? "Do" : "Skip", (size_t) policy->average_promoted_in_bytes(),
+                (size_t) policy->padded_average_promoted_in_bytes(),
+                old_gen->free_in_bytes());
+  if (young_gen->used_in_bytes() < (size_t) policy->padded_average_promoted_in_bytes()) {
+    log_trace(ergo)(" padded_promoted_average is greater than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
   }
 
   if (result) {
--- a/hotspot/src/share/vm/gc/parallel/psScavenge.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psScavenge.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "gc/parallel/parallelScavengeHeap.hpp"
 #include "gc/parallel/psPromotionManager.inline.hpp"
 #include "gc/parallel/psScavenge.hpp"
+#include "logging/log.hpp"
 #include "memory/iterator.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -138,13 +139,11 @@
     // If the klass has not been dirtied we know that there's
     // no references into  the young gen and we can skip it.
 
-    if (TraceScavenge) {
-      ResourceMark rm;
-      gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
-                             p2i(klass),
-                             klass->external_name(),
-                             klass->has_modified_oops() ? "true" : "false");
-    }
+    NOT_PRODUCT(ResourceMark rm);
+    log_develop_trace(gc, scavenge)("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
+                                    p2i(klass),
+                                    klass->external_name(),
+                                    klass->has_modified_oops() ? "true" : "false");
 
     if (klass->has_modified_oops()) {
       // Clean the klass since we're going to scavenge all the metadata.
--- a/hotspot/src/share/vm/gc/parallel/psVirtualspace.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psVirtualspace.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -213,20 +213,6 @@
   }
 }
 
-void PSVirtualSpace::print() const {
-  gclog_or_tty->print_cr("virtual space [" PTR_FORMAT "]:  alignment="
-                         SIZE_FORMAT "K grows %s%s",
-                         p2i(this), alignment() / K, grows_up() ? "up" : "down",
-                         special() ? " (pinned in memory)" : "");
-  gclog_or_tty->print_cr("    reserved=" SIZE_FORMAT "K"
-                         " [" PTR_FORMAT "," PTR_FORMAT "]"
-                         " committed=" SIZE_FORMAT "K"
-                         " [" PTR_FORMAT "," PTR_FORMAT "]",
-                         reserved_size() / K,
-                         p2i(reserved_low_addr()), p2i(reserved_high_addr()),
-                         committed_size() / K,
-                         p2i(committed_low_addr()), p2i(committed_high_addr()));
-}
 #endif // #ifndef PRODUCT
 
 void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {
--- a/hotspot/src/share/vm/gc/parallel/psVirtualspace.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psVirtualspace.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -96,7 +96,6 @@
           bool is_aligned(size_t val) const;
           bool is_aligned(char* val) const;
           void verify() const;
-          void print() const;
   virtual bool grows_up() const   { return true; }
           bool grows_down() const { return !grows_up(); }
 
--- a/hotspot/src/share/vm/gc/parallel/psYoungGen.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/parallel/psYoungGen.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,6 +30,7 @@
 #include "gc/parallel/psYoungGen.hpp"
 #include "gc/shared/gcUtil.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 
@@ -268,14 +269,12 @@
 
     space_invariants();
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("Young generation size: "
-        "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
-        " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
-        " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
-        eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
-        _max_gen_size, min_gen_size());
-    }
+    log_trace(gc, ergo)("Young generation size: "
+                        "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
+                        " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
+                        " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
+                        eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
+                        _max_gen_size, min_gen_size());
   }
 }
 
@@ -330,26 +329,17 @@
       size_changed = true;
     }
   } else {
-    if (Verbose && PrintGC) {
-      if (orig_size == gen_size_limit()) {
-        gclog_or_tty->print_cr("PSYoung generation size at maximum: "
-          SIZE_FORMAT "K", orig_size/K);
-      } else if (orig_size == min_gen_size()) {
-        gclog_or_tty->print_cr("PSYoung generation size at minium: "
-          SIZE_FORMAT "K", orig_size/K);
-      }
+    if (orig_size == gen_size_limit()) {
+      log_trace(gc)("PSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K);
+    } else if (orig_size == min_gen_size()) {
+      log_trace(gc)("PSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K);
     }
   }
 
   if (size_changed) {
     post_resize();
-
-    if (Verbose && PrintGC) {
-      size_t current_size  = virtual_space()->committed_size();
-      gclog_or_tty->print_cr("PSYoung generation size changed: "
-                             SIZE_FORMAT "K->" SIZE_FORMAT "K",
-                             orig_size/K, current_size/K);
-    }
+    log_trace(gc)("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
+                  orig_size/K, virtual_space()->committed_size()/K);
   }
 
   guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
@@ -412,28 +402,25 @@
     s2->mangle_region(delta2_right);
   }
 
-  if (TraceZapUnusedHeapArea) {
-    // s1
-    gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
-      "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
-      p2i(s1->bottom()), p2i(s1->end()),
-      p2i(s1MR.start()), p2i(s1MR.end()));
-    gclog_or_tty->print_cr("    Mangle before: [" PTR_FORMAT ", "
-      PTR_FORMAT ")  Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
-      p2i(delta1_left.start()), p2i(delta1_left.end()),
-      p2i(delta1_right.start()), p2i(delta1_right.end()));
+  // s1
+  log_develop_trace(gc)("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
+    "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
+    p2i(s1->bottom()), p2i(s1->end()),
+    p2i(s1MR.start()), p2i(s1MR.end()));
+  log_develop_trace(gc)("    Mangle before: [" PTR_FORMAT ", "
+    PTR_FORMAT ")  Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
+    p2i(delta1_left.start()), p2i(delta1_left.end()),
+    p2i(delta1_right.start()), p2i(delta1_right.end()));
 
-    // s2
-    gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
-      "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
-      p2i(s2->bottom()), p2i(s2->end()),
-      p2i(s2MR.start()), p2i(s2MR.end()));
-    gclog_or_tty->print_cr("    Mangle before: [" PTR_FORMAT ", "
-      PTR_FORMAT ")  Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
-      p2i(delta2_left.start()), p2i(delta2_left.end()),
-      p2i(delta2_right.start()), p2i(delta2_right.end()));
-  }
-
+  // s2
+  log_develop_trace(gc)("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
+    "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
+    p2i(s2->bottom()), p2i(s2->end()),
+    p2i(s2MR.start()), p2i(s2MR.end()));
+  log_develop_trace(gc)("    Mangle before: [" PTR_FORMAT ", "
+    PTR_FORMAT ")  Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
+    p2i(delta2_left.start()), p2i(delta2_left.end()),
+    p2i(delta2_right.start()), p2i(delta2_right.end()));
 }
 #endif // NOT PRODUCT
 
@@ -448,41 +435,32 @@
     return;
   }
 
-  if (PrintAdaptiveSizePolicy && Verbose) {
-    gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: "
-                  SIZE_FORMAT
-                  ", requested_survivor_size: " SIZE_FORMAT ")",
-                  requested_eden_size, requested_survivor_size);
-    gclog_or_tty->print_cr("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(eden_space()->bottom()),
-                  p2i(eden_space()->end()),
-                  pointer_delta(eden_space()->end(),
-                                eden_space()->bottom(),
-                                sizeof(char)));
-    gclog_or_tty->print_cr("    from: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(from_space()->bottom()),
-                  p2i(from_space()->end()),
-                  pointer_delta(from_space()->end(),
-                                from_space()->bottom(),
-                                sizeof(char)));
-    gclog_or_tty->print_cr("      to: [" PTR_FORMAT ".." PTR_FORMAT ") "
-                  SIZE_FORMAT,
-                  p2i(to_space()->bottom()),
-                  p2i(to_space()->end()),
-                  pointer_delta(  to_space()->end(),
-                                  to_space()->bottom(),
-                                  sizeof(char)));
-  }
+  log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: " SIZE_FORMAT ", requested_survivor_size: " SIZE_FORMAT ")",
+                      requested_eden_size, requested_survivor_size);
+  log_trace(gc, ergo)("    eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
+                      p2i(eden_space()->bottom()),
+                      p2i(eden_space()->end()),
+                      pointer_delta(eden_space()->end(),
+                                    eden_space()->bottom(),
+                                    sizeof(char)));
+  log_trace(gc, ergo)("    from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
+                      p2i(from_space()->bottom()),
+                      p2i(from_space()->end()),
+                      pointer_delta(from_space()->end(),
+                                    from_space()->bottom(),
+                                    sizeof(char)));
+  log_trace(gc, ergo)("      to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
+                      p2i(to_space()->bottom()),
+                      p2i(to_space()->end()),
+                      pointer_delta(  to_space()->end(),
+                                      to_space()->bottom(),
+                                      sizeof(char)));
 
   // There's nothing to do if the new sizes are the same as the current
   if (requested_survivor_size == to_space()->capacity_in_bytes() &&
       requested_survivor_size == from_space()->capacity_in_bytes() &&
       requested_eden_size == eden_space()->capacity_in_bytes()) {
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    capacities are the right sizes, returning");
-    }
+    log_trace(gc, ergo)("    capacities are the right sizes, returning");
     return;
   }
 
@@ -503,9 +481,7 @@
   if (eden_from_to_order) {
     // Eden, from, to
     eden_from_to_order = true;
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("  Eden, from, to:");
-    }
+    log_trace(gc, ergo)("  Eden, from, to:");
 
     // Set eden
     // "requested_eden_size" is a goal for the size of eden
@@ -566,28 +542,21 @@
 
     guarantee(to_start != to_end, "to space is zero sized");
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(eden_start),
-                    p2i(eden_end),
-                    pointer_delta(eden_end, eden_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [from_start .. from_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(from_start),
-                    p2i(from_end),
-                    pointer_delta(from_end, from_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(to_start),
-                    p2i(to_end),
-                    pointer_delta(  to_end,   to_start, sizeof(char)));
-    }
+    log_trace(gc, ergo)("    [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(eden_start),
+                        p2i(eden_end),
+                        pointer_delta(eden_end, eden_start, sizeof(char)));
+    log_trace(gc, ergo)("    [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(from_start),
+                        p2i(from_end),
+                        pointer_delta(from_end, from_start, sizeof(char)));
+    log_trace(gc, ergo)("    [  to_start ..   to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(to_start),
+                        p2i(to_end),
+                        pointer_delta(  to_end,   to_start, sizeof(char)));
   } else {
     // Eden, to, from
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("  Eden, to, from:");
-    }
+    log_trace(gc, ergo)("  Eden, to, from:");
 
     // To space gets priority over eden resizing. Note that we position
     // to space as if we were able to resize from space, even though from
@@ -623,23 +592,18 @@
     eden_end = MAX2(eden_end, eden_start + alignment);
     to_start = MAX2(to_start, eden_end);
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print_cr("    [eden_start .. eden_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(eden_start),
-                    p2i(eden_end),
-                    pointer_delta(eden_end, eden_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [  to_start ..   to_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(to_start),
-                    p2i(to_end),
-                    pointer_delta(  to_end,   to_start, sizeof(char)));
-      gclog_or_tty->print_cr("    [from_start .. from_end): "
-                    "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
-                    p2i(from_start),
-                    p2i(from_end),
-                    pointer_delta(from_end, from_start, sizeof(char)));
-    }
+    log_trace(gc, ergo)("    [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(eden_start),
+                        p2i(eden_end),
+                        pointer_delta(eden_end, eden_start, sizeof(char)));
+    log_trace(gc, ergo)("    [  to_start ..   to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(to_start),
+                        p2i(to_end),
+                        pointer_delta(  to_end,   to_start, sizeof(char)));
+    log_trace(gc, ergo)("    [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
+                        p2i(from_start),
+                        p2i(from_end),
+                        pointer_delta(from_end, from_start, sizeof(char)));
   }
 
 
@@ -658,7 +622,7 @@
   // Let's make sure the call to initialize doesn't reset "top"!
   HeapWord* old_from_top = from_space()->top();
 
-  // For PrintAdaptiveSizePolicy block  below
+  // For logging block  below
   size_t old_from = from_space()->capacity_in_bytes();
   size_t old_to   = to_space()->capacity_in_bytes();
 
@@ -704,18 +668,11 @@
 
   assert(from_space()->top() == old_from_top, "from top changed!");
 
-  if (PrintAdaptiveSizePolicy) {
-    ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
-    gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: "
-                  "collection: %d "
-                  "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
-                  "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
-                  heap->total_collections(),
-                  old_from, old_to,
-                  from_space()->capacity_in_bytes(),
-                  to_space()->capacity_in_bytes());
-    gclog_or_tty->cr();
-  }
+  log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: collection: %d (" SIZE_FORMAT ", " SIZE_FORMAT ") -> (" SIZE_FORMAT ", " SIZE_FORMAT ") ",
+                      ParallelScavengeHeap::heap()->total_collections(),
+                      old_from, old_to,
+                      from_space()->capacity_in_bytes(),
+                      to_space()->capacity_in_bytes());
 }
 
 void PSYoungGen::swap_spaces() {
@@ -794,13 +751,8 @@
 void PSYoungGen::print() const { print_on(tty); }
 void PSYoungGen::print_on(outputStream* st) const {
   st->print(" %-15s", "PSYoungGen");
-  if (PrintGCDetails && Verbose) {
-    st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT,
-               capacity_in_bytes(), used_in_bytes());
-  } else {
-    st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
-               capacity_in_bytes()/K, used_in_bytes()/K);
-  }
+  st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
+             capacity_in_bytes()/K, used_in_bytes()/K);
   virtual_space()->print_space_boundaries_on(st);
   st->print("  eden"); eden_space()->print_on(st);
   st->print("  from"); from_space()->print_on(st);
@@ -809,13 +761,8 @@
 
 // Note that a space is not printed before the [NAME:
 void PSYoungGen::print_used_change(size_t prev_used) const {
-  gclog_or_tty->print("[%s:", name());
-  gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                      "->" SIZE_FORMAT "K"
-                      "("  SIZE_FORMAT "K)",
-                      prev_used / K, used_in_bytes() / K,
-                      capacity_in_bytes() / K);
-  gclog_or_tty->print("]");
+  log_info(gc, heap)("%s: "  SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+      name(), prev_used / K, used_in_bytes() / K, capacity_in_bytes() / K);
 }
 
 size_t PSYoungGen::available_for_expansion() {
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,7 +31,7 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
@@ -39,6 +39,7 @@
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
 #include "gc/shared/strongRootsScope.hpp"
+#include "logging/log.hpp"
 #include "memory/iterator.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/oop.inline.hpp"
@@ -134,13 +135,11 @@
 void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); }
 
 void KlassScanClosure::do_klass(Klass* klass) {
-  if (TraceScavenge) {
-    ResourceMark rm;
-    gclog_or_tty->print_cr("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
-                           p2i(klass),
-                           klass->external_name(),
-                           klass->has_modified_oops() ? "true" : "false");
-  }
+  NOT_PRODUCT(ResourceMark rm);
+  log_develop_trace(gc, scavenge)("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
+                                  p2i(klass),
+                                  klass->external_name(),
+                                  klass->has_modified_oops() ? "true" : "false");
 
   // If the klass has not been dirtied we know that there's
   // no references into  the young gen and we can skip it.
@@ -359,10 +358,7 @@
   // but the second succeeds and expands the heap to its maximum
   // value.
   if (GC_locker::is_active()) {
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("Garbage collection disabled, "
-        "expanded heap instead");
-    }
+    log_debug(gc)("Garbage collection disabled, expanded heap instead");
   }
 
   return success;
@@ -429,22 +425,15 @@
     MemRegion cmr((HeapWord*)_virtual_space.low(),
                   (HeapWord*)_virtual_space.high());
     gch->barrier_set()->resize_covered_region(cmr);
-    if (Verbose && PrintGC) {
-      size_t new_size_after  = _virtual_space.committed_size();
-      size_t eden_size_after = eden()->capacity();
-      size_t survivor_size_after = from()->capacity();
-      gclog_or_tty->print("New generation size " SIZE_FORMAT "K->"
-        SIZE_FORMAT "K [eden="
-        SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
-        new_size_before/K, new_size_after/K,
-        eden_size_after/K, survivor_size_after/K);
-      if (WizardMode) {
-        gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]",
+
+    log_debug(gc, heap, ergo)(
+        "New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
+        new_size_before/K, _virtual_space.committed_size()/K,
+        eden()->capacity()/K, from()->capacity()/K);
+    log_trace(gc, heap, ergo)(
+        "  [allowed " SIZE_FORMAT "K extra for %d threads]",
           thread_increase_size/K, threads_count);
       }
-      gclog_or_tty->cr();
-    }
-  }
 }
 
 void DefNewGeneration::younger_refs_iterate(OopsInGenClosure* cl, uint n_threads) {
@@ -507,34 +496,27 @@
 // The last collection bailed out, we are running out of heap space,
 // so we try to allocate the from-space, too.
 HeapWord* DefNewGeneration::allocate_from_space(size_t size) {
+  bool should_try_alloc = should_allocate_from_space() || GC_locker::is_active_and_needs_gc();
+
+  // If the Heap_lock is not locked by this thread, this will be called
+  // again later with the Heap_lock held.
+  bool do_alloc = should_try_alloc && (Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()));
+
   HeapWord* result = NULL;
-  if (Verbose && PrintGCDetails) {
-    gclog_or_tty->print("DefNewGeneration::allocate_from_space(" SIZE_FORMAT "):"
-                        "  will_fail: %s"
-                        "  heap_lock: %s"
-                        "  free: " SIZE_FORMAT,
+  if (do_alloc) {
+    result = from()->allocate(size);
+  }
+
+  log_trace(gc, alloc)("DefNewGeneration::allocate_from_space(" SIZE_FORMAT "):  will_fail: %s  heap_lock: %s  free: " SIZE_FORMAT "%s%s returns %s",
                         size,
                         GenCollectedHeap::heap()->incremental_collection_will_fail(false /* don't consult_young */) ?
                           "true" : "false",
                         Heap_lock->is_locked() ? "locked" : "unlocked",
-                        from()->free());
-  }
-  if (should_allocate_from_space() || GC_locker::is_active_and_needs_gc()) {
-    if (Heap_lock->owned_by_self() ||
-        (SafepointSynchronize::is_at_safepoint() &&
-         Thread::current()->is_VM_thread())) {
-      // If the Heap_lock is not locked by this thread, this will be called
-      // again later with the Heap_lock held.
-      result = from()->allocate(size);
-    } else if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("  Heap_lock is not owned by self");
-    }
-  } else if (PrintGC && Verbose) {
-    gclog_or_tty->print_cr("  should_allocate_from_space: NOT");
-  }
-  if (PrintGC && Verbose) {
-    gclog_or_tty->print_cr("  returns %s", result == NULL ? "NULL" : "object");
-  }
+                        from()->free(),
+                        should_try_alloc ? "" : "  should_allocate_from_space: NOT",
+                        do_alloc ? "  Heap_lock is not owned by self" : "",
+                        result == NULL ? "NULL" : "object");
+
   return result;
 }
 
@@ -570,9 +552,7 @@
   // from this generation, pass on collection; let the next generation
   // do it.
   if (!collection_attempt_is_safe()) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print(" :: Collection attempt not safe :: ");
-    }
+    log_trace(gc)(":: Collection attempt not safe ::");
     gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one
     return;
   }
@@ -580,9 +560,7 @@
 
   init_assuming_no_promotion_failure();
 
-  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
-  // Capture heap used before collection (for printing).
-  size_t gch_prev_used = gch->used();
+  GCTraceTime(Trace, gc) tm("DefNew", NULL, gch->gc_cause());
 
   gch->trace_heap_before_gc(&gc_tracer);
 
@@ -677,9 +655,7 @@
     _promo_failure_scan_stack.clear(true); // Clear cached segments.
 
     remove_forwarding_pointers();
-    if (PrintGCDetails) {
-      gclog_or_tty->print(" (promotion failed) ");
-    }
+    log_debug(gc)("Promotion failed");
     // Add to-space to the list of space to compact
     // when a promotion failure has occurred.  In that
     // case there can be live objects in to-space
@@ -696,9 +672,6 @@
     // Reset the PromotionFailureALot counters.
     NOT_PRODUCT(gch->reset_promotion_should_fail();)
   }
-  if (PrintGC && !PrintGCDetails) {
-    gch->print_heap_change(gch_prev_used);
-  }
   // set new iteration safe limit for the survivor spaces
   from()->set_concurrent_iteration_safe_limit(from()->top());
   to()->set_concurrent_iteration_safe_limit(to()->top());
@@ -760,10 +733,8 @@
 }
 
 void DefNewGeneration::handle_promotion_failure(oop old) {
-  if (PrintPromotionFailure && !_promotion_failed) {
-    gclog_or_tty->print(" (promotion failure size = %d) ",
-                        old->size());
-  }
+  log_debug(gc, promotion)("Promotion failure size = %d) ", old->size());
+
   _promotion_failed = true;
   _promotion_failed_info.register_copy_failure(old->size());
   preserve_mark_if_necessary(old, old->mark());
@@ -895,9 +866,7 @@
 
 bool DefNewGeneration::collection_attempt_is_safe() {
   if (!to()->is_empty()) {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print(" :: to is not empty :: ");
-    }
+    log_trace(gc)(":: to is not empty ::");
     return false;
   }
   if (_old_gen == NULL) {
@@ -919,17 +888,13 @@
   if (full) {
     DEBUG_ONLY(seen_incremental_collection_failed = false;)
     if (!collection_attempt_is_safe() && !_eden_space->is_empty()) {
-      if (Verbose && PrintGCDetails) {
-        gclog_or_tty->print("DefNewEpilogue: cause(%s), full, not safe, set_failed, set_alloc_from, clear_seen",
+      log_trace(gc)("DefNewEpilogue: cause(%s), full, not safe, set_failed, set_alloc_from, clear_seen",
                             GCCause::to_string(gch->gc_cause()));
-      }
       gch->set_incremental_collection_failed(); // Slight lie: a full gc left us in that state
       set_should_allocate_from_space(); // we seem to be running out of space
     } else {
-      if (Verbose && PrintGCDetails) {
-        gclog_or_tty->print("DefNewEpilogue: cause(%s), full, safe, clear_failed, clear_alloc_from, clear_seen",
+      log_trace(gc)("DefNewEpilogue: cause(%s), full, safe, clear_failed, clear_alloc_from, clear_seen",
                             GCCause::to_string(gch->gc_cause()));
-      }
       gch->clear_incremental_collection_failed(); // We just did a full collection
       clear_should_allocate_from_space(); // if set
     }
@@ -943,16 +908,12 @@
     // a full collection in between.
     if (!seen_incremental_collection_failed &&
         gch->incremental_collection_failed()) {
-      if (Verbose && PrintGCDetails) {
-        gclog_or_tty->print("DefNewEpilogue: cause(%s), not full, not_seen_failed, failed, set_seen_failed",
+      log_trace(gc)("DefNewEpilogue: cause(%s), not full, not_seen_failed, failed, set_seen_failed",
                             GCCause::to_string(gch->gc_cause()));
-      }
       seen_incremental_collection_failed = true;
     } else if (seen_incremental_collection_failed) {
-      if (Verbose && PrintGCDetails) {
-        gclog_or_tty->print("DefNewEpilogue: cause(%s), not full, seen_failed, will_clear_seen_failed",
+      log_trace(gc)("DefNewEpilogue: cause(%s), not full, seen_failed, will_clear_seen_failed",
                             GCCause::to_string(gch->gc_cause()));
-      }
       assert(gch->gc_cause() == GCCause::_scavenge_alot ||
              (GCCause::is_user_requested_gc(gch->gc_cause()) && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
              !gch->incremental_collection_failed(),
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -339,7 +339,6 @@
   virtual const char* name() const;
   virtual const char* short_name() const { return "DefNew"; }
 
-  // PrintHeapAtGC support.
   void print_on(outputStream* st) const;
 
   void verify();
--- a/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,7 +35,7 @@
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/generation.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
@@ -71,8 +71,6 @@
   set_ref_processor(rp);
   rp->setup_policy(clear_all_softrefs);
 
-  GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
-
   gch->trace_heap_before_gc(_gc_tracer);
 
   // When collecting the permanent generation Method*s may be moving,
@@ -82,9 +80,6 @@
   // Increment the invocation count
   _total_invocations++;
 
-  // Capture heap size before collection for printing.
-  size_t gch_prev_used = gch->used();
-
   // Capture used regions for each generation that will be
   // subject to collection, so that card table adjustments can
   // be made intelligently (see clear / invalidate further below).
@@ -134,10 +129,6 @@
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
 
-  if (PrintGC && !PrintGCDetails) {
-    gch->print_heap_change(gch_prev_used);
-  }
-
   // refs processing: clean slate
   set_ref_processor(NULL);
 
@@ -189,7 +180,7 @@
 
 void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", _gc_timer);
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
@@ -262,7 +253,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", _gc_timer);
 
   gch->prepare_for_compaction();
 }
@@ -278,7 +269,7 @@
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
   // Adjust the pointers to reflect the new locations
-  GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", _gc_timer);
 
   // Need new claim bits for the pointer adjustment tracing.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -330,7 +321,7 @@
   // to use a higher index (saved from phase2) when verifying perm_gen.
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer);
+  GCTraceTime(Trace, gc) tm("Phase 4: Move objects", _gc_timer);
 
   GenCompactClosure blk;
   gch->generation_iterate(&blk, true);
--- a/hotspot/src/share/vm/gc/serial/markSweep.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/markSweep.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -250,10 +250,7 @@
 void MarkSweep::restore_marks() {
   assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
          "inconsistent preserved oop stacks");
-  if (PrintGC && Verbose) {
-    gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks",
-                           _preserved_count + _preserved_oop_stack.size());
-  }
+  log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_oop_stack.size());
 
   // restore the marks we saved earlier
   for (size_t i = 0; i < _preserved_count; i++) {
@@ -305,20 +302,13 @@
                                                   T* referent_addr,
                                                   T* next_addr,
                                                   T* discovered_addr) {
-  if(TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj));
-    gclog_or_tty->print_cr("     referent_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(referent_addr),
-                           p2i(referent_addr ?
-                               (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
-    gclog_or_tty->print_cr("     next_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(next_addr),
-                           p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
-    gclog_or_tty->print_cr("     discovered_addr/* " PTR_FORMAT " / "
-                           PTR_FORMAT, p2i(discovered_addr),
-                           p2i(discovered_addr ?
-                               (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
-  }
+  log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
+  log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
+  log_develop_trace(gc, ref)("     next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
+  log_develop_trace(gc, ref)("     discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                             p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
 }
 #endif
 
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,6 +32,7 @@
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
 #include "gc/shared/space.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
@@ -81,42 +82,28 @@
   // why it returns what it returns (without re-evaluating the conditionals
   // in case they aren't idempotent), so I'm doing it this way.
   // DeMorgan says it's okay.
-  bool result = false;
-  if (!result && full) {
-    result = true;
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
-                    " full");
-    }
+  if (full) {
+    log_trace(gc)("TenuredGeneration::should_collect: because full");
+    return true;
   }
-  if (!result && should_allocate(size, is_tlab)) {
-    result = true;
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
-                    " should_allocate(" SIZE_FORMAT ")",
-                    size);
-    }
+  if (should_allocate(size, is_tlab)) {
+    log_trace(gc)("TenuredGeneration::should_collect: because should_allocate(" SIZE_FORMAT ")", size);
+    return true;
   }
   // If we don't have very much free space.
   // XXX: 10000 should be a percentage of the capacity!!!
-  if (!result && free() < 10000) {
-    result = true;
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
-                    " free(): " SIZE_FORMAT,
-                    free());
-    }
+  if (free() < 10000) {
+    log_trace(gc)("TenuredGeneration::should_collect: because free(): " SIZE_FORMAT, free());
+    return true;
   }
   // If we had to expand to accommodate promotions from the young generation
-  if (!result && _capacity_at_prologue < capacity()) {
-    result = true;
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
-                    "_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT,
-                    _capacity_at_prologue, capacity());
-    }
+  if (_capacity_at_prologue < capacity()) {
+    log_trace(gc)("TenuredGeneration::should_collect: because_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT,
+        _capacity_at_prologue, capacity());
+    return true;
   }
-  return result;
+
+  return false;
 }
 
 void TenuredGeneration::compute_new_size() {
@@ -165,13 +152,10 @@
   size_t available = max_contiguous_available();
   size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();
   bool   res = (available >= av_promo) || (available >= max_promotion_in_bytes);
-  if (PrintGC && Verbose) {
-    gclog_or_tty->print_cr(
-      "Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "),"
-      "max_promo(" SIZE_FORMAT ")",
-      res? "":" not", available, res? ">=":"<",
-      av_promo, max_promotion_in_bytes);
-  }
+
+  log_trace(gc)("Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "), max_promo(" SIZE_FORMAT ")",
+    res? "":" not", available, res? ">=":"<", av_promo, max_promotion_in_bytes);
+
   return res;
 }
 
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "logging/log.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/ostream.hpp"
 elapsedTimer AdaptiveSizePolicy::_minor_timer;
@@ -166,14 +167,12 @@
       "Jiggled active workers too much");
   }
 
-  if (TraceDynamicGCThreads) {
-     gclog_or_tty->print_cr("GCTaskManager::calc_default_active_workers() : "
-       "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
-       "prev_active_workers: " UINTX_FORMAT "\n"
-       " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
-       active_workers, new_active_workers, prev_active_workers,
-       active_workers_by_JT, active_workers_by_heap_size);
-  }
+   log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
+     "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
+     "prev_active_workers: " UINTX_FORMAT "\n"
+     " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
+     active_workers, new_active_workers, prev_active_workers,
+     active_workers_by_JT, active_workers_by_heap_size);
   assert(new_active_workers > 0, "Always need at least 1");
   return new_active_workers;
 }
@@ -275,14 +274,10 @@
     update_minor_pause_young_estimator(minor_pause_in_ms);
     update_minor_pause_old_estimator(minor_pause_in_ms);
 
-    if (PrintAdaptiveSizePolicy && Verbose) {
-      gclog_or_tty->print("AdaptiveSizePolicy::minor_collection_end: "
-                          "minor gc cost: %f  average: %f", collection_cost,
-                          _avg_minor_gc_cost->average());
-      gclog_or_tty->print_cr("  minor pause: %f minor period %f",
-                             minor_pause_in_ms,
-                             _latest_minor_mutator_interval_seconds * MILLIUNITS);
-    }
+    log_trace(gc, ergo)("AdaptiveSizePolicy::minor_collection_end: minor gc cost: %f  average: %f",
+                        collection_cost, _avg_minor_gc_cost->average());
+    log_trace(gc, ergo)("  minor pause: %f minor period %f",
+                        minor_pause_in_ms, _latest_minor_mutator_interval_seconds * MILLIUNITS);
 
     // Calculate variable used to estimate collection cost vs. gen sizes
     assert(collection_cost >= 0.0, "Expected to be non-negative");
@@ -388,13 +383,10 @@
 
       // Decay using the time-since-last-major-gc
       decayed_major_gc_cost = decaying_major_gc_cost();
-      if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("\ndecaying_gc_cost: major interval average:"
-          " %f  time since last major gc: %f",
-          avg_major_interval, time_since_last_major_gc);
-        gclog_or_tty->print_cr("  major gc cost: %f  decayed major gc cost: %f",
-          major_gc_cost(), decayed_major_gc_cost);
-      }
+      log_trace(gc, ergo)("decaying_gc_cost: major interval average: %f  time since last major gc: %f",
+                    avg_major_interval, time_since_last_major_gc);
+      log_trace(gc, ergo)("  major gc cost: %f  decayed major gc cost: %f",
+                    major_gc_cost(), decayed_major_gc_cost);
     }
   }
   double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost());
@@ -461,21 +453,17 @@
   promo_limit = MAX2(promo_limit, _promo_size);
 
 
-  if (PrintAdaptiveSizePolicy && (Verbose ||
-      (free_in_old_gen < (size_t) mem_free_old_limit &&
-       free_in_eden < (size_t) mem_free_eden_limit))) {
-    gclog_or_tty->print_cr(
-          "PSAdaptiveSizePolicy::check_gc_overhead_limit:"
-          " promo_limit: " SIZE_FORMAT
-          " max_eden_size: " SIZE_FORMAT
-          " total_free_limit: " SIZE_FORMAT
-          " max_old_gen_size: " SIZE_FORMAT
-          " max_eden_size: " SIZE_FORMAT
-          " mem_free_limit: " SIZE_FORMAT,
-          promo_limit, max_eden_size, total_free_limit,
-          max_old_gen_size, max_eden_size,
-          (size_t) mem_free_limit);
-  }
+  log_trace(gc, ergo)(
+        "PSAdaptiveSizePolicy::check_gc_overhead_limit:"
+        " promo_limit: " SIZE_FORMAT
+        " max_eden_size: " SIZE_FORMAT
+        " total_free_limit: " SIZE_FORMAT
+        " max_old_gen_size: " SIZE_FORMAT
+        " max_eden_size: " SIZE_FORMAT
+        " mem_free_limit: " SIZE_FORMAT,
+        promo_limit, max_eden_size, total_free_limit,
+        max_old_gen_size, max_eden_size,
+        (size_t) mem_free_limit);
 
   bool print_gc_overhead_limit_would_be_exceeded = false;
   if (is_full_gc) {
@@ -521,10 +509,7 @@
           bool near_limit = gc_overhead_limit_near();
           if (near_limit) {
             collector_policy->set_should_clear_all_soft_refs(true);
-            if (PrintGCDetails && Verbose) {
-              gclog_or_tty->print_cr("  Nearing GC overhead limit, "
-                "will be clearing all SoftReference");
-            }
+            log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
           }
         }
       }
@@ -540,26 +525,25 @@
     }
   }
 
-  if (UseGCOverheadLimit && PrintGCDetails && Verbose) {
+  if (UseGCOverheadLimit) {
     if (gc_overhead_limit_exceeded()) {
-      gclog_or_tty->print_cr("      GC is exceeding overhead limit "
-        "of " UINTX_FORMAT "%%", GCTimeLimit);
+      log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit);
       reset_gc_overhead_limit_count();
     } else if (print_gc_overhead_limit_would_be_exceeded) {
       assert(gc_overhead_limit_count() > 0, "Should not be printing");
-      gclog_or_tty->print_cr("      GC would exceed overhead limit "
-        "of " UINTX_FORMAT "%% %d consecutive time(s)",
-        GCTimeLimit, gc_overhead_limit_count());
+      log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)",
+                          GCTimeLimit, gc_overhead_limit_count());
     }
   }
 }
 // Printing
 
-bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const {
+bool AdaptiveSizePolicy::print() const {
+  assert(UseAdaptiveSizePolicy, "UseAdaptiveSizePolicy need to be enabled.");
 
-  //  Should only be used with adaptive size policy turned on.
-  // Otherwise, there may be variables that are undefined.
-  if (!UseAdaptiveSizePolicy) return false;
+  if (!log_is_enabled(Debug, gc, ergo)) {
+    return false;
+  }
 
   // Print goal for which action is needed.
   char* action = NULL;
@@ -627,41 +611,24 @@
     tenured_gen_action = shrink_msg;
   }
 
-  st->print_cr("    UseAdaptiveSizePolicy actions to meet %s", action);
-  st->print_cr("                       GC overhead (%%)");
-  st->print_cr("    Young generation:     %7.2f\t  %s",
-    100.0 * avg_minor_gc_cost()->average(),
-    young_gen_action);
-  st->print_cr("    Tenured generation:   %7.2f\t  %s",
-    100.0 * avg_major_gc_cost()->average(),
-    tenured_gen_action);
+  log_debug(gc, ergo)("UseAdaptiveSizePolicy actions to meet %s", action);
+  log_debug(gc, ergo)("                       GC overhead (%%)");
+  log_debug(gc, ergo)("    Young generation:     %7.2f\t  %s",
+                      100.0 * avg_minor_gc_cost()->average(), young_gen_action);
+  log_debug(gc, ergo)("    Tenured generation:   %7.2f\t  %s",
+                      100.0 * avg_major_gc_cost()->average(), tenured_gen_action);
   return true;
 }
 
-bool AdaptiveSizePolicy::print_adaptive_size_policy_on(
-                                            outputStream* st,
-                                            uint tenuring_threshold_arg) const {
-  if (!AdaptiveSizePolicy::print_adaptive_size_policy_on(st)) {
-    return false;
-  }
-
+void AdaptiveSizePolicy::print_tenuring_threshold( uint new_tenuring_threshold_arg) const {
   // Tenuring threshold
-  bool tenuring_threshold_changed = true;
   if (decrement_tenuring_threshold_for_survivor_limit()) {
-    st->print("    Tenuring threshold:    (attempted to decrease to avoid"
-              " survivor space overflow) = ");
+    log_debug(gc, ergo)("Tenuring threshold: (attempted to decrease to avoid survivor space overflow) = %u", new_tenuring_threshold_arg);
   } else if (decrement_tenuring_threshold_for_gc_cost()) {
-    st->print("    Tenuring threshold:    (attempted to decrease to balance"
-              " GC costs) = ");
+    log_debug(gc, ergo)("Tenuring threshold: (attempted to decrease to balance GC costs) = %u", new_tenuring_threshold_arg);
   } else if (increment_tenuring_threshold_for_gc_cost()) {
-    st->print("    Tenuring threshold:    (attempted to increase to balance"
-              " GC costs) = ");
+    log_debug(gc, ergo)("Tenuring threshold: (attempted to increase to balance GC costs) = %u", new_tenuring_threshold_arg);
   } else {
-    tenuring_threshold_changed = false;
     assert(!tenuring_threshold_change(), "(no change was attempted)");
   }
-  if (tenuring_threshold_changed) {
-    st->print_cr("%u", tenuring_threshold_arg);
-  }
-  return true;
 }
--- a/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/adaptiveSizePolicy.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/universe.hpp"
 
@@ -500,9 +501,8 @@
   }
 
   // Printing support
-  virtual bool print_adaptive_size_policy_on(outputStream* st) const;
-  bool print_adaptive_size_policy_on(outputStream* st,
-                                     uint tenuring_threshold) const;
+  virtual bool print() const;
+  void print_tenuring_threshold(uint new_tenuring_threshold) const;
 };
 
 // Class that can be used to print information about the
@@ -510,46 +510,26 @@
 // AdaptiveSizePolicyOutputInterval.  Only print information
 // if an adaptive size policy is in use.
 class AdaptiveSizePolicyOutput : StackObj {
-  AdaptiveSizePolicy* _size_policy;
-  bool _do_print;
-  bool print_test(uint count) {
-    // A count of zero is a special value that indicates that the
-    // interval test should be ignored.  An interval is of zero is
-    // a special value that indicates that the interval test should
-    // always fail (never do the print based on the interval test).
-    return PrintGCDetails &&
+  static bool enabled() {
+    return UseParallelGC &&
            UseAdaptiveSizePolicy &&
-           UseParallelGC &&
-           (AdaptiveSizePolicyOutputInterval > 0) &&
-           ((count == 0) ||
-             ((count % AdaptiveSizePolicyOutputInterval) == 0));
+           log_is_enabled(Debug, gc, ergo);
   }
  public:
-  // The special value of a zero count can be used to ignore
-  // the count test.
-  AdaptiveSizePolicyOutput(uint count) {
-    if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
-      CollectedHeap* heap = Universe::heap();
-      _size_policy = heap->size_policy();
-      _do_print = print_test(count);
-    } else {
-      _size_policy = NULL;
-      _do_print = false;
+  static void print() {
+    if (enabled()) {
+      Universe::heap()->size_policy()->print();
     }
   }
-  AdaptiveSizePolicyOutput(AdaptiveSizePolicy* size_policy,
-                           uint count) :
-    _size_policy(size_policy) {
-    if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
-      _do_print = print_test(count);
-    } else {
-      _do_print = false;
-    }
-  }
-  ~AdaptiveSizePolicyOutput() {
-    if (_do_print) {
-      assert(UseAdaptiveSizePolicy, "Should not be in use");
-      _size_policy->print_adaptive_size_policy_on(gclog_or_tty);
+
+  static void print(AdaptiveSizePolicy* size_policy, uint count) {
+    bool do_print =
+        enabled() &&
+        (AdaptiveSizePolicyOutputInterval > 0) &&
+        (count % AdaptiveSizePolicyOutputInterval) == 0;
+
+    if (do_print) {
+      size_policy->print();
     }
   }
 };
--- a/hotspot/src/share/vm/gc/shared/ageTable.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/ageTable.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "memory/resourceArea.hpp"
+#include "logging/log.hpp"
 #include "utilities/copy.hpp"
 
 /* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University.
@@ -94,24 +95,18 @@
     result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
   }
 
-  if (PrintTenuringDistribution || UsePerfData) {
 
-    if (PrintTenuringDistribution) {
-      gclog_or_tty->cr();
-      gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold "
-        UINTX_FORMAT " (max threshold " UINTX_FORMAT ")",
-        desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold);
-    }
+  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) {
     size_t total = 0;
     uint age = 1;
     while (age < table_size) {
       total += sizes[age];
       if (sizes[age] > 0) {
-        if (PrintTenuringDistribution) {
-          gclog_or_tty->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total",
-                                        age,    sizes[age]*oopSize,          total*oopSize);
-        }
+        log_trace(gc, age)("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total",
+                            age, sizes[age]*oopSize, total*oopSize);
       }
       if (UsePerfData) {
         _perf_sizes[age]->set_value(sizes[age]*oopSize);
--- a/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/blockOffsetTable.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/shared/space.inline.hpp"
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
 #include "services/memTracker.hpp"
@@ -53,19 +54,11 @@
   }
   _offset_array = (u_char*)_vs.low_boundary();
   resize(init_word_size);
-  if (TraceBlockOffsetTable) {
-    gclog_or_tty->print_cr("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
-    gclog_or_tty->print_cr("  "
-                  "  rs.base(): " INTPTR_FORMAT
-                  "  rs.size(): " INTPTR_FORMAT
-                  "  rs end(): " INTPTR_FORMAT,
-                  p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
-    gclog_or_tty->print_cr("  "
-                  "  _vs.low_boundary(): " INTPTR_FORMAT
-                  "  _vs.high_boundary(): " INTPTR_FORMAT,
-                  p2i(_vs.low_boundary()),
-                  p2i(_vs.high_boundary()));
-  }
+  log_trace(gc, bot)("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
+  log_trace(gc, bot)("   rs.base(): " INTPTR_FORMAT " rs.size(): " INTPTR_FORMAT " rs end(): " INTPTR_FORMAT,
+                     p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
+  log_trace(gc, bot)("   _vs.low_boundary(): " INTPTR_FORMAT "  _vs.high_boundary(): " INTPTR_FORMAT,
+                     p2i(_vs.low_boundary()), p2i(_vs.high_boundary()));
 }
 
 void BlockOffsetSharedArray::resize(size_t new_word_size) {
--- a/hotspot/src/share/vm/gc/shared/cardGeneration.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/cardGeneration.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -33,6 +33,7 @@
 #include "gc/shared/space.inline.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
+#include "logging/log.hpp"
 #include "runtime/java.hpp"
 
 CardGeneration::CardGeneration(ReservedSpace rs,
@@ -96,13 +97,10 @@
     // update the space and generation capacity counters
     update_counters();
 
-    if (Verbose && PrintGC) {
-      size_t new_mem_size = _virtual_space.committed_size();
-      size_t old_mem_size = new_mem_size - bytes;
-      gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
-                      SIZE_FORMAT "K to " SIZE_FORMAT "K",
-                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
-    }
+    size_t new_mem_size = _virtual_space.committed_size();
+    size_t old_mem_size = new_mem_size - bytes;
+    log_trace(gc, heap)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                    name(), old_mem_size/K, bytes/K, new_mem_size/K);
   }
   return result;
 }
@@ -133,10 +131,8 @@
   if (!success) {
     success = grow_to_reserved();
   }
-  if (PrintGC && Verbose) {
-    if (success && GC_locker::is_active_and_needs_gc()) {
-      gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
-    }
+  if (success && GC_locker::is_active_and_needs_gc()) {
+    log_trace(gc, heap)("Garbage collection disabled, expanded heap instead");
   }
 
   return success;
@@ -172,12 +168,10 @@
   // Shrink the card table
   GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
 
-  if (Verbose && PrintGC) {
-    size_t new_mem_size = _virtual_space.committed_size();
-    size_t old_mem_size = new_mem_size + size;
-    gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
-                  name(), old_mem_size/K, new_mem_size/K);
-  }
+  size_t new_mem_size = _virtual_space.committed_size();
+  size_t old_mem_size = new_mem_size + size;
+  log_trace(gc, heap)("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                      name(), old_mem_size/K, new_mem_size/K);
 }
 
 // No young generation references, clear this generation's cards.
@@ -211,26 +205,17 @@
   minimum_desired_capacity = MAX2(minimum_desired_capacity, initial_size());
   assert(used_after_gc <= minimum_desired_capacity, "sanity check");
 
-  if (PrintGC && Verbose) {
     const size_t free_after_gc = free();
     const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
-    gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: ");
-    gclog_or_tty->print_cr("  "
-                  "  minimum_free_percentage: %6.2f"
-                  "  maximum_used_percentage: %6.2f",
+    log_trace(gc, heap)("TenuredGeneration::compute_new_size:");
+    log_trace(gc, heap)("    minimum_free_percentage: %6.2f  maximum_used_percentage: %6.2f",
                   minimum_free_percentage,
                   maximum_used_percentage);
-    gclog_or_tty->print_cr("  "
-                  "   free_after_gc   : %6.1fK"
-                  "   used_after_gc   : %6.1fK"
-                  "   capacity_after_gc   : %6.1fK",
+    log_trace(gc, heap)("     free_after_gc   : %6.1fK   used_after_gc   : %6.1fK   capacity_after_gc   : %6.1fK",
                   free_after_gc / (double) K,
                   used_after_gc / (double) K,
                   capacity_after_gc / (double) K);
-    gclog_or_tty->print_cr("  "
-                  "   free_percentage: %6.2f",
-                  free_percentage);
-  }
+    log_trace(gc, heap)("     free_percentage: %6.2f", free_percentage);
 
   if (capacity_after_gc < minimum_desired_capacity) {
     // If we have less free space than we want then expand
@@ -239,15 +224,10 @@
     if (expand_bytes >= _min_heap_delta_bytes) {
       expand(expand_bytes, 0); // safe if expansion fails
     }
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("    expanding:"
-                    "  minimum_desired_capacity: %6.1fK"
-                    "  expand_bytes: %6.1fK"
-                    "  _min_heap_delta_bytes: %6.1fK",
-                    minimum_desired_capacity / (double) K,
-                    expand_bytes / (double) K,
-                    _min_heap_delta_bytes / (double) K);
-    }
+    log_trace(gc, heap)("    expanding:  minimum_desired_capacity: %6.1fK  expand_bytes: %6.1fK  _min_heap_delta_bytes: %6.1fK",
+                  minimum_desired_capacity / (double) K,
+                  expand_bytes / (double) K,
+                  _min_heap_delta_bytes / (double) K);
     return;
   }
 
@@ -262,20 +242,12 @@
     const double max_tmp = used_after_gc / minimum_used_percentage;
     size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
     maximum_desired_capacity = MAX2(maximum_desired_capacity, initial_size());
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("  "
-                             "  maximum_free_percentage: %6.2f"
-                             "  minimum_used_percentage: %6.2f",
-                             maximum_free_percentage,
-                             minimum_used_percentage);
-      gclog_or_tty->print_cr("  "
-                             "  _capacity_at_prologue: %6.1fK"
-                             "  minimum_desired_capacity: %6.1fK"
-                             "  maximum_desired_capacity: %6.1fK",
+    log_trace(gc, heap)("    maximum_free_percentage: %6.2f  minimum_used_percentage: %6.2f",
+                             maximum_free_percentage, minimum_used_percentage);
+    log_trace(gc, heap)("    _capacity_at_prologue: %6.1fK  minimum_desired_capacity: %6.1fK  maximum_desired_capacity: %6.1fK",
                              _capacity_at_prologue / (double) K,
                              minimum_desired_capacity / (double) K,
                              maximum_desired_capacity / (double) K);
-    }
     assert(minimum_desired_capacity <= maximum_desired_capacity,
            "sanity check");
 
@@ -295,23 +267,13 @@
       } else {
         _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
       }
-      if (PrintGC && Verbose) {
-        gclog_or_tty->print_cr("  "
-                               "  shrinking:"
-                               "  initSize: %.1fK"
-                               "  maximum_desired_capacity: %.1fK",
-                               initial_size() / (double) K,
-                               maximum_desired_capacity / (double) K);
-        gclog_or_tty->print_cr("  "
-                               "  shrink_bytes: %.1fK"
-                               "  current_shrink_factor: " SIZE_FORMAT
-                               "  new shrink factor: " SIZE_FORMAT
-                               "  _min_heap_delta_bytes: %.1fK",
+      log_trace(gc, heap)("    shrinking:  initSize: %.1fK  maximum_desired_capacity: %.1fK",
+                               initial_size() / (double) K, maximum_desired_capacity / (double) K);
+      log_trace(gc, heap)("    shrink_bytes: %.1fK  current_shrink_factor: " SIZE_FORMAT "  new shrink factor: " SIZE_FORMAT "  _min_heap_delta_bytes: %.1fK",
                                shrink_bytes / (double) K,
                                current_shrink_factor,
                                _shrink_factor,
                                _min_heap_delta_bytes / (double) K);
-      }
     }
   }
 
@@ -324,18 +286,11 @@
     // We have two shrinking computations, take the largest
     shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion);
     assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
-    if (PrintGC && Verbose) {
-      gclog_or_tty->print_cr("  "
-                             "  aggressive shrinking:"
-                             "  _capacity_at_prologue: %.1fK"
-                             "  capacity_after_gc: %.1fK"
-                             "  expansion_for_promotion: %.1fK"
-                             "  shrink_bytes: %.1fK",
-                             capacity_after_gc / (double) K,
-                             _capacity_at_prologue / (double) K,
-                             expansion_for_promotion / (double) K,
-                             shrink_bytes / (double) K);
-    }
+    log_trace(gc, heap)("    aggressive shrinking:  _capacity_at_prologue: %.1fK  capacity_after_gc: %.1fK  expansion_for_promotion: %.1fK  shrink_bytes: %.1fK",
+                        capacity_after_gc / (double) K,
+                        _capacity_at_prologue / (double) K,
+                        expansion_for_promotion / (double) K,
+                        shrink_bytes / (double) K);
   }
   // Don't shrink unless it's significant
   if (shrink_bytes >= _min_heap_delta_bytes) {
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,6 +28,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "memory/virtualspace.hpp"
+#include "logging/log.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/macros.hpp"
 
@@ -115,17 +116,10 @@
                             !ExecMem, "card table last card");
   *guard_card = last_card;
 
-  if (TraceCardTableModRefBS) {
-    gclog_or_tty->print_cr("CardTableModRefBS::CardTableModRefBS: ");
-    gclog_or_tty->print_cr("  "
-                  "  &_byte_map[0]: " INTPTR_FORMAT
-                  "  &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
-                  p2i(&_byte_map[0]),
-                  p2i(&_byte_map[_last_valid_index]));
-    gclog_or_tty->print_cr("  "
-                  "  byte_map_base: " INTPTR_FORMAT,
-                  p2i(byte_map_base));
-  }
+  log_trace(gc, barrier)("CardTableModRefBS::CardTableModRefBS: ");
+  log_trace(gc, barrier)("    &_byte_map[0]: " INTPTR_FORMAT "  &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
+                  p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
+  log_trace(gc, barrier)("    byte_map_base: " INTPTR_FORMAT, p2i(byte_map_base));
 }
 
 CardTableModRefBS::~CardTableModRefBS() {
@@ -350,29 +344,17 @@
   }
   // In any case, the covered size changes.
   _covered[ind].set_word_size(new_region.word_size());
-  if (TraceCardTableModRefBS) {
-    gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: ");
-    gclog_or_tty->print_cr("  "
-                  "  _covered[%d].start(): " INTPTR_FORMAT
-                  "  _covered[%d].last(): " INTPTR_FORMAT,
-                  ind, p2i(_covered[ind].start()),
-                  ind, p2i(_covered[ind].last()));
-    gclog_or_tty->print_cr("  "
-                  "  _committed[%d].start(): " INTPTR_FORMAT
-                  "  _committed[%d].last(): " INTPTR_FORMAT,
-                  ind, p2i(_committed[ind].start()),
-                  ind, p2i(_committed[ind].last()));
-    gclog_or_tty->print_cr("  "
-                  "  byte_for(start): " INTPTR_FORMAT
-                  "  byte_for(last): " INTPTR_FORMAT,
-                  p2i(byte_for(_covered[ind].start())),
-                  p2i(byte_for(_covered[ind].last())));
-    gclog_or_tty->print_cr("  "
-                  "  addr_for(start): " INTPTR_FORMAT
-                  "  addr_for(last): " INTPTR_FORMAT,
-                  p2i(addr_for((jbyte*) _committed[ind].start())),
-                  p2i(addr_for((jbyte*) _committed[ind].last())));
-  }
+
+  log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
+  log_trace(gc, barrier)("    _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
+                         ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
+  log_trace(gc, barrier)("    _committed[%d].start(): " INTPTR_FORMAT "  _committed[%d].last(): " INTPTR_FORMAT,
+                         ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
+  log_trace(gc, barrier)("    byte_for(start): " INTPTR_FORMAT "  byte_for(last): " INTPTR_FORMAT,
+                         p2i(byte_for(_covered[ind].start())),  p2i(byte_for(_covered[ind].last())));
+  log_trace(gc, barrier)("    addr_for(start): " INTPTR_FORMAT "  addr_for(last): " INTPTR_FORMAT,
+                         p2i(addr_for((jbyte*) _committed[ind].start())),  p2i(addr_for((jbyte*) _committed[ind].last())));
+
   // Touch the last card of the covered region to show that it
   // is committed (or SEGV).
   debug_only((void) (*byte_for(_covered[ind].last()));)
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -30,9 +30,10 @@
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/vmGCOperations.hpp"
+#include "logging/log.hpp"
 #include "memory/metaspace.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/oop.inline.hpp"
@@ -53,7 +54,7 @@
   st->print_raw(m);
 }
 
-void GCHeapLog::log_heap(bool before) {
+void GCHeapLog::log_heap(CollectedHeap* heap, bool before) {
   if (!should_log()) {
     return;
   }
@@ -65,11 +66,14 @@
   _records[index].timestamp = timestamp;
   _records[index].data.is_before = before;
   stringStream st(_records[index].data.buffer(), _records[index].data.size());
-  if (before) {
-    Universe::print_heap_before_gc(&st, true);
-  } else {
-    Universe::print_heap_after_gc(&st, true);
-  }
+
+  st.print_cr("{Heap %s GC invocations=%u (full %u):",
+                 before ? "before" : "after",
+                 heap->total_collections(),
+                 heap->total_full_collections());
+
+  heap->print_on(&st);
+  st.print_cr("}");
 }
 
 VirtualSpaceSummary CollectedHeap::create_heap_space_summary() {
@@ -108,20 +112,16 @@
 }
 
 void CollectedHeap::print_heap_before_gc() {
-  if (PrintHeapAtGC) {
-    Universe::print_heap_before_gc();
-  }
+  Universe::print_heap_before_gc();
   if (_gc_heap_log != NULL) {
-    _gc_heap_log->log_heap_before();
+    _gc_heap_log->log_heap_before(this);
   }
 }
 
 void CollectedHeap::print_heap_after_gc() {
-  if (PrintHeapAtGC) {
-    Universe::print_heap_after_gc();
-  }
+  Universe::print_heap_after_gc();
   if (_gc_heap_log != NULL) {
-    _gc_heap_log->log_heap_after();
+    _gc_heap_log->log_heap_after(this);
   }
 }
 
@@ -571,34 +571,30 @@
   }
 }
 
-void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
-  if (HeapDumpBeforeFullGC) {
+void CollectedHeap::full_gc_dump(GCTimer* timer, const char* when) {
+  if (HeapDumpBeforeFullGC || HeapDumpAfterFullGC) {
     GCIdMarkAndRestore gc_id_mark;
-    GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer);
-    // We are doing a full collection and a heap dump before
-    // full collection has been requested.
+    FormatBuffer<> title("Heap Dump (%s full gc)", when);
+    GCTraceTime(Info, gc) tm(title.buffer(), timer);
     HeapDumper::dump_heap();
   }
-  if (PrintClassHistogramBeforeFullGC) {
+  LogHandle(gc, classhisto) log;
+  if (log.is_trace()) {
+    ResourceMark rm;
     GCIdMarkAndRestore gc_id_mark;
-    GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer);
-    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
+    FormatBuffer<> title("Class Histogram (%s full gc)", when);
+    GCTraceTime(Trace, gc, classhisto) tm(title.buffer(), timer);
+    VM_GC_HeapInspection inspector(log.trace_stream(), false /* ! full gc */);
     inspector.doit();
   }
 }
 
+void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
+  full_gc_dump(timer, "before");
+}
+
 void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
-  if (HeapDumpAfterFullGC) {
-    GCIdMarkAndRestore gc_id_mark;
-    GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
-    HeapDumper::dump_heap();
-  }
-  if (PrintClassHistogramAfterFullGC) {
-    GCIdMarkAndRestore gc_id_mark;
-    GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
-    VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
-    inspector.doit();
-  }
+  full_gc_dump(timer, "after");
 }
 
 void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) {
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -58,18 +58,20 @@
   GCMessage() {}
 };
 
+class CollectedHeap;
+
 class GCHeapLog : public EventLogBase<GCMessage> {
  private:
-  void log_heap(bool before);
+  void log_heap(CollectedHeap* heap, bool before);
 
  public:
   GCHeapLog() : EventLogBase<GCMessage>("GC Heap History") {}
 
-  void log_heap_before() {
-    log_heap(true);
+  void log_heap_before(CollectedHeap* heap) {
+    log_heap(heap, true);
   }
-  void log_heap_after() {
-    log_heap(false);
+  void log_heap_after(CollectedHeap* heap) {
+    log_heap(heap, false);
   }
 };
 
@@ -195,6 +197,8 @@
 
   virtual Name kind() const = 0;
 
+  virtual const char* name() const = 0;
+
   /**
    * Returns JNI error code JNI_ENOMEM if memory could not be allocated,
    * and JNI_OK on success.
@@ -519,6 +523,9 @@
   virtual void prepare_for_verify() = 0;
 
   // Generate any dumps preceding or following a full gc
+ private:
+  void full_gc_dump(GCTimer* timer, const char* when);
+ public:
   void pre_full_gc_dump(GCTimer* timer);
   void post_full_gc_dump(GCTimer* timer);
 
@@ -569,7 +576,7 @@
   void trace_heap_after_gc(const GCTracer* gc_tracer);
 
   // Heap verification
-  virtual void verify(bool silent, VerifyOption option) = 0;
+  virtual void verify(VerifyOption option) = 0;
 
   // Non product verification and debugging.
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/collectorPolicy.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,6 +32,7 @@
 #include "gc/shared/generationSpec.hpp"
 #include "gc/shared/space.hpp"
 #include "gc/shared/vmGCOperations.hpp"
+#include "logging/log.hpp"
 #include "memory/universe.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals_extension.hpp"
@@ -137,11 +138,8 @@
 }
 
 void CollectorPolicy::initialize_size_info() {
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT "  Initial heap "
-      SIZE_FORMAT "  Maximum heap " SIZE_FORMAT,
-      _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
-  }
+  log_debug(gc, heap)("Minimum heap " SIZE_FORMAT "  Initial heap " SIZE_FORMAT "  Maximum heap " SIZE_FORMAT,
+                      _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
 
   DEBUG_ONLY(CollectorPolicy::assert_size_info();)
 }
@@ -488,11 +486,8 @@
     }
   }
 
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print_cr("1: Minimum young " SIZE_FORMAT "  Initial young "
-      SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
-      _min_young_size, _initial_young_size, _max_young_size);
-  }
+  log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT "  Initial young " SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
+                      _min_young_size, _initial_young_size, _max_young_size);
 
   // At this point the minimum, initial and maximum sizes
   // of the overall heap and of the young generation have been determined.
@@ -558,11 +553,8 @@
       _initial_young_size = desired_young_size;
     }
 
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("2: Minimum young " SIZE_FORMAT "  Initial young "
-        SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
-        _min_young_size, _initial_young_size, _max_young_size);
-    }
+    log_trace(gc, heap)("2: Minimum young " SIZE_FORMAT "  Initial young " SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
+                    _min_young_size, _initial_young_size, _max_young_size);
   }
 
   // Write back to flags if necessary.
@@ -578,11 +570,8 @@
     FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
   }
 
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print_cr("Minimum old " SIZE_FORMAT "  Initial old "
-      SIZE_FORMAT "  Maximum old " SIZE_FORMAT,
-      _min_old_size, _initial_old_size, _max_old_size);
-  }
+  log_trace(gc, heap)("Minimum old " SIZE_FORMAT "  Initial old " SIZE_FORMAT "  Maximum old " SIZE_FORMAT,
+                  _min_old_size, _initial_old_size, _max_old_size);
 
   DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
 }
@@ -620,10 +609,7 @@
     uint gc_count_before;  // Read inside the Heap_lock locked region.
     {
       MutexLocker ml(Heap_lock);
-      if (PrintGC && Verbose) {
-        gclog_or_tty->print_cr("GenCollectorPolicy::mem_allocate_work:"
-                               " attempting locked slow path allocation");
-      }
+      log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
       // Note that only large objects get a shot at being
       // allocated in later generations.
       bool first_only = ! should_try_older_generation_allocation(size);
@@ -757,9 +743,7 @@
                        is_tlab,                   // is_tlab
                        GenCollectedHeap::OldGen); // max_generation
   } else {
-    if (Verbose && PrintGCDetails) {
-      gclog_or_tty->print(" :: Trying full because partial may fail :: ");
-    }
+    log_trace(gc)(" :: Trying full because partial may fail :: ");
     // Try a full collection; see delta for bug id 6266275
     // for the original code and why this has been simplified
     // with from-space allocation criteria modified and
--- a/hotspot/src/share/vm/gc/shared/gcCause.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcCause.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -125,36 +125,4 @@
   static const char* to_string(GCCause::Cause cause);
 };
 
-// Helper class for doing logging that includes the GC Cause
-// as a string.
-class GCCauseString : StackObj {
- private:
-   static const int _length = 128;
-   char _buffer[_length];
-   int _position;
-
- public:
-   GCCauseString(const char* prefix, GCCause::Cause cause) {
-     if (PrintGCCause) {
-      _position = jio_snprintf(_buffer, _length, "%s (%s) ", prefix, GCCause::to_string(cause));
-     } else {
-      _position = jio_snprintf(_buffer, _length, "%s ", prefix);
-     }
-     assert(_position >= 0 && _position <= _length,
-            "Need to increase the buffer size in GCCauseString? %d", _position);
-   }
-
-   GCCauseString& append(const char* str) {
-     int res = jio_snprintf(_buffer + _position, _length - _position, "%s", str);
-     _position += res;
-     assert(res >= 0 && _position <= _length,
-            "Need to increase the buffer size in GCCauseString? %d", res);
-     return *this;
-   }
-
-   operator const char*() {
-     return _buffer;
-   }
-};
-
 #endif // SHARE_VM_GC_SHARED_GCCAUSE_HPP
--- a/hotspot/src/share/vm/gc/shared/gcId.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcId.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,6 +26,7 @@
 #include "gc/shared/gcId.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadLocalStorage.hpp"
 
 uint GCId::_next_id = 0;
 
@@ -47,6 +48,18 @@
   return currentNamedthread()->gc_id();
 }
 
+size_t GCId::print_prefix(char* buf, size_t len) {
+  if (ThreadLocalStorage::is_initialized() && ThreadLocalStorage::thread()->is_Named_thread()) {
+    uint gc_id = current_raw();
+    if (gc_id != undefined()) {
+      int ret = jio_snprintf(buf, len, "GC(%u) ", gc_id);
+      assert(ret > 0, "Failed to print prefix. Log buffer too small?");
+      return (size_t)ret;
+    }
+  }
+  return 0;
+}
+
 GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
   currentNamedthread()->set_gc_id(_gc_id);
 }
--- a/hotspot/src/share/vm/gc/shared/gcId.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcId.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -40,6 +40,7 @@
   // Same as current() but can return undefined() if no GC id is currently active
   static const uint current_raw();
   static const uint undefined() { return UNDEFINED; }
+  static size_t print_prefix(char* buf, size_t len);
 };
 
 class GCIdMark : public StackObj {
--- a/hotspot/src/share/vm/gc/shared/gcLocker.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcLocker.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,6 +26,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "logging/log.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
@@ -73,17 +74,20 @@
 }
 #endif
 
+void GC_locker::log_debug_jni(const char* msg) {
+  LogHandle(gc, jni) log;
+  if (log.is_debug()) {
+    ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
+    log.debug("%s Thread \"%s\" %d locked.", msg, Thread::current()->name(), _jni_lock_count);
+  }
+}
+
 bool GC_locker::check_active_before_gc() {
   assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint");
   if (is_active() && !_needs_gc) {
     verify_critical_count();
     _needs_gc = true;
-    if (PrintJNIGCStalls && PrintGCDetails) {
-      ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
-      gclog_or_tty->print_cr("%.3f: Setting _needs_gc. Thread \"%s\" %d locked.",
-                             gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
-    }
-
+    log_debug_jni("Setting _needs_gc.");
   }
   return is_active();
 }
@@ -93,11 +97,7 @@
   MutexLocker   ml(JNICritical_lock);
 
   if (needs_gc()) {
-    if (PrintJNIGCStalls && PrintGCDetails) {
-      ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
-      gclog_or_tty->print_cr("%.3f: Allocation failed. Thread \"%s\" is stalled by JNI critical section, %d locked.",
-                             gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
-    }
+    log_debug_jni("Allocation failed. Thread stalled by JNI critical section.");
   }
 
   // Wait for _needs_gc  to be cleared
@@ -134,11 +134,7 @@
     {
       // Must give up the lock while at a safepoint
       MutexUnlocker munlock(JNICritical_lock);
-      if (PrintJNIGCStalls && PrintGCDetails) {
-        ResourceMark rm; // JavaThread::name() allocates to convert to UTF8
-        gclog_or_tty->print_cr("%.3f: Thread \"%s\" is performing GC after exiting critical section, %d locked",
-            gclog_or_tty->time_stamp().seconds(), Thread::current()->name(), _jni_lock_count);
-      }
+      log_debug_jni("Performing GC after exiting critical section.");
       Universe::heap()->collect(GCCause::_gc_locker);
     }
     _doing_gc = false;
--- a/hotspot/src/share/vm/gc/shared/gcLocker.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcLocker.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -64,6 +64,7 @@
     return _jni_lock_count > 0;
   }
 
+  static void log_debug_jni(const char* msg);
  public:
   // Accessors
   static bool is_active() {
--- a/hotspot/src/share/vm/gc/shared/gcTraceTime.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -23,57 +23,38 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
-#include "runtime/globals.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
+#include "logging/log.hpp"
 #include "runtime/os.hpp"
-#include "runtime/safepoint.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/timer.hpp"
-#include "utilities/ostream.hpp"
-#include "utilities/ticks.inline.hpp"
-
 
-GCTraceTimeImpl::GCTraceTimeImpl(const char* title, bool doit, bool print_cr, GCTimer* timer) :
-    _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() {
-  if (_doit || _timer != NULL) {
-    _start_counter.stamp();
-  }
-
-  if (_timer != NULL) {
-    assert(SafepointSynchronize::is_at_safepoint(), "Tracing currently only supported at safepoints");
-    assert(Thread::current()->is_VM_thread(), "Tracing currently only supported from the VM thread");
-
-    _timer->register_gc_phase_start(title, _start_counter);
-  }
-
-  if (_doit) {
-    gclog_or_tty->gclog_stamp();
-    gclog_or_tty->print("[%s", title);
-    gclog_or_tty->flush();
+GCTraceCPUTime::GCTraceCPUTime() :
+  _active(log_is_enabled(Info, gc, cpu)),
+  _starting_user_time(0.0),
+  _starting_system_time(0.0),
+  _starting_real_time(0.0)
+{
+  if (_active) {
+    bool valid = os::getTimesSecs(&_starting_real_time,
+                               &_starting_user_time,
+                               &_starting_system_time);
+    if (!valid) {
+      log_warning(gc, cpu)("TraceCPUTime: os::getTimesSecs() returned invalid result");
+      _active = false;
+    }
   }
 }
 
-GCTraceTimeImpl::~GCTraceTimeImpl() {
-  Ticks stop_counter;
-
-  if (_doit || _timer != NULL) {
-    stop_counter.stamp();
-  }
-
-  if (_timer != NULL) {
-    _timer->register_gc_phase_end(stop_counter);
-  }
-
-  if (_doit) {
-    const Tickspan duration = stop_counter - _start_counter;
-    double duration_in_seconds = TicksToTimeHelper::seconds(duration);
-    if (_print_cr) {
-      gclog_or_tty->print_cr(", %3.7f secs]", duration_in_seconds);
+GCTraceCPUTime::~GCTraceCPUTime() {
+  if (_active) {
+    double real_time, user_time, system_time;
+    bool valid = os::getTimesSecs(&real_time, &user_time, &system_time);
+    if (valid) {
+      log_info(gc, cpu)("User=%3.2fs Sys=%3.2fs Real=%3.2fs",
+                        user_time - _starting_user_time,
+                        system_time - _starting_system_time,
+                        real_time - _starting_real_time);
     } else {
-      gclog_or_tty->print(", %3.7f secs]", duration_in_seconds);
+      log_warning(gc, cpu)("TraceCPUTime: os::getTimesSecs() returned invalid result");
     }
-    gclog_or_tty->flush();
   }
 }
--- a/hotspot/src/share/vm/gc/shared/gcTraceTime.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -25,31 +25,55 @@
 #ifndef SHARE_VM_GC_SHARED_GCTRACETIME_HPP
 #define SHARE_VM_GC_SHARED_GCTRACETIME_HPP
 
-#include "gc/shared/gcTrace.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
-#include "prims/jni_md.h"
 #include "utilities/ticks.hpp"
 
+class GCTraceCPUTime : public StackObj {
+  bool _active;                 // true if times will be measured and printed
+  double _starting_user_time;   // user time at start of measurement
+  double _starting_system_time; // system time at start of measurement
+  double _starting_real_time;   // real time at start of measurement
+ public:
+  GCTraceCPUTime();
+  ~GCTraceCPUTime();
+};
+
 class GCTimer;
 
-class GCTraceTimeImpl VALUE_OBJ_CLASS_SPEC {
+template <LogLevelType Level, LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
+    LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
+class GCTraceTimeImpl : public StackObj {
+ private:
+  bool _enabled;
+  Ticks _start_ticks;
   const char* _title;
-  bool _doit;
-  bool _print_cr;
+  GCCause::Cause _gc_cause;
   GCTimer* _timer;
-  Ticks _start_counter;
+  size_t _heap_usage_before;
+
+  void log_start(jlong start_counter);
+  void log_stop(jlong start_counter, jlong stop_counter);
+  void time_stamp(Ticks& ticks);
 
  public:
-  GCTraceTimeImpl(const char* title, bool doit, bool print_cr, GCTimer* timer);
+  GCTraceTimeImpl(const char* title, GCTimer* timer = NULL, GCCause::Cause gc_cause = GCCause::_no_gc, bool log_heap_usage = false);
   ~GCTraceTimeImpl();
 };
 
-class GCTraceTime : public StackObj {
-  GCTraceTimeImpl _gc_trace_time_impl;
-
+// Similar to GCTraceTimeImpl but is intended for concurrent phase logging,
+// which is a bit simpler and should always print the start line, i.e. not add the "start" tag.
+template <LogLevelType Level, LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
+    LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
+class GCTraceConcTimeImpl : public StackObj {
+ private:
+  bool _enabled;
+  jlong _start_time;
+  const char* _title;
  public:
-  GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
-    _gc_trace_time_impl(title, doit, print_cr, timer) {};
+  GCTraceConcTimeImpl(const char* title);
+  ~GCTraceConcTimeImpl();
+  jlong start_time() { return _start_time; }
 };
 
 #endif // SHARE_VM_GC_SHARED_GCTRACETIME_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_GCTRACETIME_INLINE_HPP
+#define SHARE_VM_GC_SHARED_GCTRACETIME_INLINE_HPP
+
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/gcTimer.hpp"
+#include "gc/shared/gcTrace.hpp"
+#include "gc/shared/gcTraceTime.hpp"
+#include "logging/log.hpp"
+#include "memory/universe.hpp"
+#include "prims/jni_md.h"
+#include "utilities/ticks.hpp"
+#include "runtime/timer.hpp"
+
+#define LOG_STOP_TIME_FORMAT "(%.3fs, %.3fs) %.3fms"
+#define LOG_STOP_HEAP_FORMAT SIZE_FORMAT "M->" SIZE_FORMAT "M("  SIZE_FORMAT "M)"
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+void GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::log_start(jlong start_counter) {
+  if (Log<PREFIX_LOG_TAG(start), T0, T1, T2, T3>::is_level(Level)) {
+    FormatBuffer<> start_msg("%s", _title);
+    if (_gc_cause != GCCause::_no_gc) {
+      start_msg.append(" (%s)", GCCause::to_string(_gc_cause));
+    }
+    start_msg.append(" (%.3fs)", TimeHelper::counter_to_seconds(start_counter));
+    // Make sure to put the "start" tag last in the tag set
+    STATIC_ASSERT(T0 != LogTag::__NO_TAG); // Need some tag to log on.
+    STATIC_ASSERT(T4 == LogTag::__NO_TAG); // Need to leave at least the last tag for the "start" tag in log_start()
+    if (T1 == LogTag::__NO_TAG) {
+      Log<T0, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
+    } else if (T2 == LogTag::__NO_TAG) {
+      Log<T0, T1, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
+    } else if (T3 == LogTag::__NO_TAG) {
+      Log<T0, T1, T2, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
+    } else {
+      Log<T0, T1, T2, T3, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
+    }
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+void GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::log_stop(jlong start_counter, jlong stop_counter) {
+  double duration_in_ms = TimeHelper::counter_to_millis(stop_counter - start_counter);
+  double start_time_in_secs = TimeHelper::counter_to_seconds(start_counter);
+  double stop_time_in_secs = TimeHelper::counter_to_seconds(stop_counter);
+  FormatBuffer<> stop_msg("%s", _title);
+  if (_gc_cause != GCCause::_no_gc) {
+    stop_msg.append(" (%s)", GCCause::to_string(_gc_cause));
+  }
+  if (_heap_usage_before == SIZE_MAX) {
+    Log<T0, T1, T2, T3, T4>::template write<Level>("%s " LOG_STOP_TIME_FORMAT,
+        stop_msg.buffer(), start_time_in_secs, stop_time_in_secs, duration_in_ms);
+  } else {
+    CollectedHeap* heap = Universe::heap();
+    size_t used_before_m = _heap_usage_before / M;
+    size_t used_m = heap->used() / M;
+    size_t capacity_m = heap->capacity() / M;
+    Log<T0, T1, T2, T3, T4>::template write<Level>("%s " LOG_STOP_HEAP_FORMAT " " LOG_STOP_TIME_FORMAT,
+        stop_msg.buffer(), used_before_m, used_m, capacity_m, start_time_in_secs, stop_time_in_secs, duration_in_ms);
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+void GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::time_stamp(Ticks& ticks) {
+  if (_enabled || _timer != NULL) {
+    ticks.stamp();
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::GCTraceTimeImpl(const char* title, GCTimer* timer, GCCause::Cause gc_cause, bool log_heap_usage) :
+  _enabled(Log<T0, T1, T2, T3, T4, GuardTag>::is_level(Level)),
+  _start_ticks(),
+  _heap_usage_before(SIZE_MAX),
+  _title(title),
+  _gc_cause(gc_cause),
+  _timer(timer) {
+
+  time_stamp(_start_ticks);
+  if (_enabled) {
+    if (log_heap_usage) {
+      _heap_usage_before = Universe::heap()->used();
+    }
+    log_start(_start_ticks.value());
+  }
+  if (_timer != NULL) {
+    _timer->register_gc_phase_start(_title, _start_ticks);
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::~GCTraceTimeImpl() {
+  Ticks stop_ticks;
+  time_stamp(stop_ticks);
+  if (_enabled) {
+    log_stop(_start_ticks.value(), stop_ticks.value());
+  }
+  if (_timer != NULL) {
+    _timer->register_gc_phase_end(stop_ticks);
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+GCTraceConcTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::GCTraceConcTimeImpl(const char* title) :
+  _enabled(Log<T0, T1, T2, T3, T4, GuardTag>::is_level(Level)), _start_time(os::elapsed_counter()), _title(title) {
+  if (_enabled) {
+    Log<T0, T1, T2, T3, T4>::template write<Level>("%s (%.3fs)", _title, TimeHelper::counter_to_seconds(_start_time));
+  }
+}
+
+template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
+GCTraceConcTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::~GCTraceConcTimeImpl() {
+  if (_enabled) {
+    jlong stop_time = os::elapsed_counter();
+    Log<T0, T1, T2, T3, T4>::template write<Level>("%s " LOG_STOP_TIME_FORMAT,
+                                                   _title,
+                                                   TimeHelper::counter_to_seconds(_start_time),
+                                                   TimeHelper::counter_to_seconds(stop_time),
+                                                   TimeHelper::counter_to_millis(stop_time - _start_time));
+  }
+}
+
+#define GCTraceTime(Level, ...) GCTraceTimeImpl<LogLevel::Level, LOG_TAGS(__VA_ARGS__)>
+#define GCTraceConcTime(Level, ...) GCTraceConcTimeImpl<LogLevel::Level, LOG_TAGS(__VA_ARGS__)>
+
+#endif // SHARE_VM_GC_SHARED_GCTRACETIME_INLINE_HPP
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -33,7 +33,7 @@
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcTrace.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
@@ -314,13 +314,11 @@
 void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t size,
                                           bool is_tlab, bool run_verification, bool clear_soft_refs,
                                           bool restore_marks_for_biased_locking) {
-  // Timer for individual generations. Last argument is false: no CR
-  // FIXME: We should try to start the timing earlier to cover more of the GC pause
-  GCTraceTime t1(gen->short_name(), PrintGCDetails, false, NULL);
+  FormatBuffer<> title("Collect gen: %s", gen->short_name());
+  GCTraceTime(Debug, gc) t1(title);
   TraceCollectorStats tcs(gen->counters());
   TraceMemoryManagerStats tmms(gen->kind(),gc_cause());
 
-  size_t prev_used = gen->used();
   gen->stat_record()->invocations++;
   gen->stat_record()->accumulated_time.start();
 
@@ -329,24 +327,11 @@
   // change top of some spaces.
   record_gen_tops_before_GC();
 
-  if (PrintGC && Verbose) {
-    // I didn't want to change the logging when removing the level concept,
-    // but I guess this logging could say young/old or something instead of 0/1.
-    uint level;
-    if (heap()->is_young_gen(gen)) {
-      level = 0;
-    } else {
-      level = 1;
-    }
-    gclog_or_tty->print("level=%u invoke=%d size=" SIZE_FORMAT,
-                        level,
-                        gen->stat_record()->invocations,
-                        size * HeapWordSize);
-  }
+  log_trace(gc)("%s invoke=%d size=" SIZE_FORMAT, heap()->is_young_gen(gen) ? "Young" : "Old", gen->stat_record()->invocations, size * HeapWordSize);
 
   if (run_verification && VerifyBeforeGC) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyBeforeGC:");
+    Universe::verify("Before GC");
   }
   COMPILER2_PRESENT(DerivedPointerTable::clear());
 
@@ -404,12 +389,7 @@
 
   if (run_verification && VerifyAfterGC) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(" VerifyAfterGC:");
-  }
-
-  if (PrintGCDetails) {
-    gclog_or_tty->print(":");
-    gen->print_heap_change(prev_used);
+    Universe::verify("After GC");
   }
 }
 
@@ -448,21 +428,31 @@
     FlagSetting fl(_is_gc_active, true);
 
     bool complete = full && (max_generation == OldGen);
-    const char* gc_cause_prefix = complete ? "Full GC" : "GC";
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL);
+    bool old_collects_young = complete && !ScavengeBeforeFullGC;
+    bool do_young_collection = !old_collects_young && _young_gen->should_collect(full, size, is_tlab);
+
+    FormatBuffer<> gc_string("%s", "Pause ");
+    if (do_young_collection) {
+      gc_string.append("Young");
+    } else {
+      gc_string.append("Full");
+    }
+
+    GCTraceCPUTime tcpu;
+    GCTraceTime(Info, gc) t(gc_string, NULL, gc_cause(), true);
 
     gc_prologue(complete);
     increment_total_collections(complete);
 
-    size_t gch_prev_used = used();
+    size_t young_prev_used = _young_gen->used();
+    size_t old_prev_used = _old_gen->used();
+
     bool run_verification = total_collections() >= VerifyGCStartAt;
 
     bool prepared_for_verification = false;
     bool collected_old = false;
-    bool old_collects_young = complete && !ScavengeBeforeFullGC;
 
-    if (!old_collects_young && _young_gen->should_collect(full, size, is_tlab)) {
+    if (do_young_collection) {
       if (run_verification && VerifyGCLevel <= 0 && VerifyBeforeGC) {
         prepare_for_verify();
         prepared_for_verification = true;
@@ -487,7 +477,6 @@
     bool must_restore_marks_for_biased_locking = false;
 
     if (max_generation == OldGen && _old_gen->should_collect(full, size, is_tlab)) {
-      GCIdMarkAndRestore gc_id_mark;
       if (!complete) {
         // The full_collections increment was missed above.
         increment_total_full_collections();
@@ -501,13 +490,16 @@
       }
 
       assert(_old_gen->performs_in_place_marking(), "All old generations do in place marking");
-      collect_generation(_old_gen,
-                         full,
-                         size,
-                         is_tlab,
-                         run_verification && VerifyGCLevel <= 1,
-                         do_clear_all_soft_refs,
-                         true);
+
+      if (do_young_collection) {
+        // We did a young GC. Need a new GC id for the old GC.
+        GCIdMarkAndRestore gc_id_mark;
+        GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true);
+        collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true);
+      } else {
+        // No young GC done. Use the same GC id as was set up earlier in this method.
+        collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true);
+      }
 
       must_restore_marks_for_biased_locking = true;
       collected_old = true;
@@ -523,14 +515,8 @@
       post_full_gc_dump(NULL);   // do any post full gc dumps
     }
 
-    if (PrintGCDetails) {
-      print_heap_change(gch_prev_used);
-
-      // Print metaspace info for full GC with PrintGCDetails flag.
-      if (complete) {
-        MetaspaceAux::print_metaspace_change(metadata_prev_used);
-      }
-    }
+    print_heap_change(young_prev_used, old_prev_used);
+    MetaspaceAux::print_metaspace_change(metadata_prev_used);
 
     // Adjust generation sizes.
     if (collected_old) {
@@ -874,10 +860,7 @@
   // been attempted and failed, because the old gen was too full
   if (local_last_generation == YoungGen && gc_cause() == GCCause::_gc_locker &&
       incremental_collection_will_fail(false /* don't consult_young */)) {
-    if (PrintGCDetails) {
-      gclog_or_tty->print_cr("GC locker: Trying a full collection "
-                             "because scavenge failed");
-    }
+    log_debug(gc, jni)("GC locker: Trying a full collection because scavenge failed");
     // This time allow the old gen to be collected as well
     do_collection(true,                // full
                   clear_all_soft_refs, // clear_all_soft_refs
@@ -1106,22 +1089,14 @@
   _young_gen->prepare_for_compaction(&cp);
 }
 
-void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) {
-  if (!silent) {
-    gclog_or_tty->print("%s", _old_gen->name());
-    gclog_or_tty->print(" ");
-  }
+void GenCollectedHeap::verify(VerifyOption option /* ignored */) {
+  log_debug(gc, verify)("%s", _old_gen->name());
   _old_gen->verify();
 
-  if (!silent) {
-    gclog_or_tty->print("%s", _young_gen->name());
-    gclog_or_tty->print(" ");
-  }
+  log_debug(gc, verify)("%s", _old_gen->name());
   _young_gen->verify();
 
-  if (!silent) {
-    gclog_or_tty->print("remset ");
-  }
+  log_debug(gc, verify)("RemSet");
   rem_set()->verify();
 }
 
@@ -1171,18 +1146,11 @@
   }
 }
 
-void GenCollectedHeap::print_heap_change(size_t prev_used) const {
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print(" "  SIZE_FORMAT
-                        "->" SIZE_FORMAT
-                        "("  SIZE_FORMAT ")",
-                        prev_used, used(), capacity());
-  } else {
-    gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                        "->" SIZE_FORMAT "K"
-                        "("  SIZE_FORMAT "K)",
-                        prev_used / K, used() / K, capacity() / K);
-  }
+void GenCollectedHeap::print_heap_change(size_t young_prev_used, size_t old_prev_used) const {
+  log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                     _young_gen->short_name(), young_prev_used / K, _young_gen->used() /K, _young_gen->capacity() /K);
+  log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                     _old_gen->short_name(), old_prev_used / K, _old_gen->used() /K, _old_gen->capacity() /K);
 }
 
 class GenGCPrologueClosure: public GenCollectedHeap::GenClosure {
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -142,6 +142,14 @@
     return CollectedHeap::GenCollectedHeap;
   }
 
+  virtual const char* name() const {
+    if (UseConcMarkSweepGC) {
+      return "Concurrent Mark Sweep";
+    } else {
+      return "Serial";
+    }
+  }
+
   Generation* young_gen() const { return _young_gen; }
   Generation* old_gen()   const { return _old_gen; }
 
@@ -329,7 +337,7 @@
   void prepare_for_verify();
 
   // Override.
-  void verify(bool silent, VerifyOption option);
+  void verify(VerifyOption option);
 
   // Override.
   virtual void print_on(outputStream* st) const;
@@ -338,8 +346,7 @@
   virtual void print_tracing_info() const;
   virtual void print_on_error(outputStream* st) const;
 
-  // PrintGC, PrintGCDetails support
-  void print_heap_change(size_t prev_used) const;
+  void print_heap_change(size_t young_prev_used, size_t old_prev_used) const;
 
   // The functions below are helper functions that a subclass of
   // "CollectedHeap" can use in the implementation of its virtual
--- a/hotspot/src/share/vm/gc/shared/generation.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/generation.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -36,6 +36,7 @@
 #include "gc/shared/generation.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
@@ -70,20 +71,6 @@
   return reserved().byte_size();
 }
 
-void Generation::print_heap_change(size_t prev_used) const {
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print(" "  SIZE_FORMAT
-                        "->" SIZE_FORMAT
-                        "("  SIZE_FORMAT ")",
-                        prev_used, used(), capacity());
-  } else {
-    gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                        "->" SIZE_FORMAT "K"
-                        "("  SIZE_FORMAT "K)",
-                        prev_used / K, used() / K, capacity() / K);
-  }
-}
-
 // By default we get a single threaded default reference processor;
 // generations needing multi-threaded refs processing or discovery override this method.
 void Generation::ref_processor_init() {
@@ -171,12 +158,8 @@
 bool Generation::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
   size_t available = max_contiguous_available();
   bool   res = (available >= max_promotion_in_bytes);
-  if (PrintGC && Verbose) {
-    gclog_or_tty->print_cr(
-      "Generation: promo attempt is%s safe: available(" SIZE_FORMAT ") %s max_promo(" SIZE_FORMAT ")",
-      res? "":" not", available, res? ">=":"<",
-      max_promotion_in_bytes);
-  }
+  log_trace(gc)("Generation: promo attempt is%s safe: available(" SIZE_FORMAT ") %s max_promo(" SIZE_FORMAT ")",
+                res? "":" not", available, res? ">=":"<", max_promotion_in_bytes);
   return res;
 }
 
--- a/hotspot/src/share/vm/gc/shared/generation.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/generation.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -536,11 +536,8 @@
   // the block is an object.
   virtual bool block_is_obj(const HeapWord* addr) const;
 
-
-  // PrintGC, PrintGCDetails support
   void print_heap_change(size_t prev_used) const;
 
-  // PrintHeapAtGC support
   virtual void print() const;
   virtual void print_on(outputStream* st) const;
 
--- a/hotspot/src/share/vm/gc/shared/plab.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/plab.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -26,6 +26,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/plab.inline.hpp"
 #include "gc/shared/threadLocalAllocBuffer.hpp"
+#include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/oop.inline.hpp"
 
@@ -149,18 +150,8 @@
   new_plab_sz = MIN2(max_size(), new_plab_sz);
   new_plab_sz = align_object_size(new_plab_sz);
   // Latch the result
-  if (PrintPLAB) {
-    gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_net_plab_sz = " SIZE_FORMAT ") ", recent_plab_sz, new_plab_sz);
-  }
+  log_trace(gc, plab)("plab_size = " SIZE_FORMAT " desired_net_plab_sz = " SIZE_FORMAT ") ", recent_plab_sz, new_plab_sz);
   _desired_net_plab_sz = new_plab_sz;
 
   reset();
 }
-
-#ifndef PRODUCT
-void PLAB::print() {
-  gclog_or_tty->print_cr("PLAB: _bottom: " PTR_FORMAT "  _top: " PTR_FORMAT
-    "  _end: " PTR_FORMAT "  _hard_end: " PTR_FORMAT ")",
-    p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
-}
-#endif // !PRODUCT
--- a/hotspot/src/share/vm/gc/shared/plab.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/plab.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -141,8 +141,6 @@
   // Fills in the unallocated portion of the buffer with a garbage object and updates
   // statistics. To be called during GC.
   virtual void retire();
-
-  void print() PRODUCT_RETURN;
 };
 
 // PLAB book-keeping.
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -28,9 +28,10 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/gcTimer.hpp"
-#include "gc/shared/gcTraceTime.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessor.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
@@ -186,21 +187,6 @@
   return total;
 }
 
-static void log_ref_count(size_t count, bool doit) {
-  if (doit) {
-    gclog_or_tty->print(", " SIZE_FORMAT " refs", count);
-  }
-}
-
-class GCRefTraceTime : public StackObj {
-  GCTraceTimeImpl _gc_trace_time;
- public:
-  GCRefTraceTime(const char* title, bool doit, GCTimer* timer, size_t count) :
-    _gc_trace_time(title, doit, false, timer) {
-    log_ref_count(count, doit);
-  }
-};
-
 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
   BoolObjectClosure*           is_alive,
   OopClosure*                  keep_alive,
@@ -222,8 +208,6 @@
 
   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 
-  bool trace_time = PrintGCDetails && PrintReferenceGC;
-
   // Include cleaners in phantom statistics.  We expect Cleaner
   // references to be temporary, and don't want to deal with
   // possible incompatibilities arising from making it more visible.
@@ -235,7 +219,7 @@
 
   // Soft references
   {
-    GCRefTraceTime tt("SoftReference", trace_time, gc_timer, stats.soft_count());
+    GCTraceTime(Debug, gc, ref) tt("SoftReference", gc_timer);
     process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
                                is_alive, keep_alive, complete_gc, task_executor);
   }
@@ -244,21 +228,21 @@
 
   // Weak references
   {
-    GCRefTraceTime tt("WeakReference", trace_time, gc_timer, stats.weak_count());
+    GCTraceTime(Debug, gc, ref) tt("WeakReference", gc_timer);
     process_discovered_reflist(_discoveredWeakRefs, NULL, true,
                                is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Final references
   {
-    GCRefTraceTime tt("FinalReference", trace_time, gc_timer, stats.final_count());
+  GCTraceTime(Debug, gc, ref) tt("FinalReference", gc_timer);
     process_discovered_reflist(_discoveredFinalRefs, NULL, false,
                                is_alive, keep_alive, complete_gc, task_executor);
   }
 
   // Phantom references
   {
-    GCRefTraceTime tt("PhantomReference", trace_time, gc_timer, stats.phantom_count());
+    GCTraceTime(Debug, gc, ref) tt("PhantomReference", gc_timer);
     process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
                                is_alive, keep_alive, complete_gc, task_executor);
 
@@ -275,20 +259,23 @@
   // thus use JNI weak references to circumvent the phantom references and
   // resurrect a "post-mortem" object.
   {
-    GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
-    NOT_PRODUCT(log_ref_count(count_jni_refs(), trace_time);)
+    GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", gc_timer);
     if (task_executor != NULL) {
       task_executor->set_single_threaded_mode();
     }
     process_phaseJNI(is_alive, keep_alive, complete_gc);
   }
 
+  log_debug(gc, ref)("Ref Counts: Soft: " SIZE_FORMAT " Weak: " SIZE_FORMAT " Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT,
+                     stats.soft_count(), stats.weak_count(), stats.final_count(), stats.phantom_count());
+  log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
+
   return stats;
 }
 
 #ifndef PRODUCT
 // Calculate the number of jni handles.
-uint ReferenceProcessor::count_jni_refs() {
+size_t ReferenceProcessor::count_jni_refs() {
   class AlwaysAliveClosure: public BoolObjectClosure {
   public:
     virtual bool do_object_b(oop obj) { return true; }
@@ -296,12 +283,12 @@
 
   class CountHandleClosure: public OopClosure {
   private:
-    int _count;
+    size_t _count;
   public:
     CountHandleClosure(): _count(0) {}
     void do_oop(oop* unused)       { _count++; }
     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
-    int count() { return _count; }
+    size_t count() { return _count; }
   };
   CountHandleClosure global_handle_count;
   AlwaysAliveClosure always_alive;
@@ -362,10 +349,7 @@
   // all linked Reference objects. Note that it is important to not dirty any
   // cards during reference processing since this will cause card table
   // verification to fail for G1.
-  if (TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
-                           INTPTR_FORMAT, p2i(refs_list.head()));
-  }
+  log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(refs_list.head()));
 
   oop obj = NULL;
   oop next_d = refs_list.head();
@@ -376,10 +360,7 @@
     assert(obj->is_instance(), "should be an instance object");
     assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
     next_d = java_lang_ref_Reference::discovered(obj);
-    if (TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
-                             p2i(obj), p2i(next_d));
-    }
+    log_develop_trace(gc, ref)("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
     assert(java_lang_ref_Reference::next(obj) == NULL,
            "Reference not active; should not be discovered");
     // Self-loop next, so as to make Ref not active.
@@ -517,10 +498,8 @@
     bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
     if (referent_is_dead &&
         !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
-      if (TraceReferenceGC) {
-        gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
-                               p2i(iter.obj()), iter.obj()->klass()->internal_name());
-      }
+      log_develop_trace(gc, ref)("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
+                                 p2i(iter.obj()), iter.obj()->klass()->internal_name());
       // Remove Reference object from list
       iter.remove();
       // keep the referent around
@@ -532,14 +511,9 @@
   }
   // Close the reachable set
   complete_gc->do_void();
-  NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC) {
-      gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT
-        " discovered Refs by policy, from list " INTPTR_FORMAT,
-        iter.removed(), iter.processed(), p2i(refs_list.head()));
+  log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT,
+                             iter.removed(), iter.processed(), p2i(refs_list.head()));
     }
-  )
-}
 
 // Traverse the list and remove any Refs that are not active, or
 // whose referents are either alive or NULL.
@@ -554,10 +528,8 @@
     DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
     assert(next == NULL, "Should not discover inactive Reference");
     if (iter.is_referent_alive()) {
-      if (TraceReferenceGC) {
-        gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
-                               p2i(iter.obj()), iter.obj()->klass()->internal_name());
-      }
+      log_develop_trace(gc, ref)("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
+                                 p2i(iter.obj()), iter.obj()->klass()->internal_name());
       // The referent is reachable after all.
       // Remove Reference object from list.
       iter.remove();
@@ -571,8 +543,8 @@
     }
   }
   NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
-      gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
+    if (iter.processed() > 0) {
+      log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
         " Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), p2i(refs_list.head()));
     }
@@ -610,8 +582,8 @@
   // Now close the newly reachable set
   complete_gc->do_void();
   NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
-      gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
+    if (iter.processed() > 0) {
+      log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
         " Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), p2i(refs_list.head()));
     }
@@ -638,11 +610,8 @@
       // keep the referent around
       iter.make_referent_alive();
     }
-    if (TraceReferenceGC) {
-      gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
-                             clear_referent ? "cleared " : "",
-                             p2i(iter.obj()), iter.obj()->klass()->internal_name());
-    }
+    log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
+                               clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name());
     assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
     iter.next();
   }
@@ -666,8 +635,8 @@
 void ReferenceProcessor::abandon_partial_discovery() {
   // loop over the lists
   for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
-    if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
-      gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
+    if ((i % _max_num_q) == 0) {
+      log_develop_trace(gc, ref)("Abandoning %s discovered list", list_name(i));
     }
     clear_discovered_references(_discovered_refs[i]);
   }
@@ -736,6 +705,20 @@
   bool _clear_referent;
 };
 
+#ifndef PRODUCT
+void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], size_t total_refs) {
+  if (!log_is_enabled(Trace, gc, ref)) {
+    return;
+  }
+
+  stringStream st;
+  for (uint i = 0; i < _max_num_q; ++i) {
+    st.print(SIZE_FORMAT " ", ref_lists[i].length());
+  }
+  log_develop_trace(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs);
+}
+#endif
+
 // Balances reference queues.
 // Move entries from all queues[0, 1, ..., _max_num_q-1] to
 // queues[0, 1, ..., _num_q-1] because only the first _num_q
@@ -744,19 +727,12 @@
 {
   // calculate total length
   size_t total_refs = 0;
-  if (TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("\nBalance ref_lists ");
-  }
+  log_develop_trace(gc, ref)("Balance ref_lists ");
 
   for (uint i = 0; i < _max_num_q; ++i) {
     total_refs += ref_lists[i].length();
-    if (TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print(SIZE_FORMAT " ", ref_lists[i].length());
     }
-  }
-  if (TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr(" = " SIZE_FORMAT, total_refs);
-  }
+  log_reflist_counts(ref_lists, total_refs);
   size_t avg_refs = total_refs / _num_q + 1;
   uint to_idx = 0;
   for (uint from_idx = 0; from_idx < _max_num_q; from_idx++) {
@@ -820,14 +796,8 @@
   size_t balanced_total_refs = 0;
   for (uint i = 0; i < _max_num_q; ++i) {
     balanced_total_refs += ref_lists[i].length();
-    if (TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print(SIZE_FORMAT " ", ref_lists[i].length());
     }
-  }
-  if (TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr(" = " SIZE_FORMAT, balanced_total_refs);
-    gclog_or_tty->flush();
-  }
+  log_reflist_counts(ref_lists, balanced_total_refs);
   assert(total_refs == balanced_total_refs, "Balancing was incomplete");
 #endif
 }
@@ -950,9 +920,7 @@
     default:
       ShouldNotReachHere();
   }
-  if (TraceReferenceGC && PrintGCDetails) {
-    gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, id, p2i(list));
-  }
+  log_develop_trace(gc, ref)("Thread %d gets list " INTPTR_FORMAT, id, p2i(list));
   return list;
 }
 
@@ -976,19 +944,15 @@
     refs_list.set_head(obj);
     refs_list.inc_length(1);
 
-    if (TraceReferenceGC) {
-      gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
-                             p2i(obj), obj->klass()->internal_name());
-    }
+    log_develop_trace(gc, ref)("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
+                               p2i(obj), obj->klass()->internal_name());
   } else {
     // If retest was non NULL, another thread beat us to it:
     // The reference has already been discovered...
-    if (TraceReferenceGC) {
-      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
-                             p2i(obj), obj->klass()->internal_name());
+    log_develop_trace(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)",
+                               p2i(obj), obj->klass()->internal_name());
     }
   }
-}
 
 #ifndef PRODUCT
 // Non-atomic (i.e. concurrent) discovery might allow us
@@ -1078,10 +1042,8 @@
   assert(discovered->is_oop_or_null(), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   if (discovered != NULL) {
     // The reference has already been discovered...
-    if (TraceReferenceGC) {
-      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
-                             p2i(obj), obj->klass()->internal_name());
-    }
+    log_develop_trace(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)",
+                               p2i(obj), obj->klass()->internal_name());
     if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
       // assumes that an object is not processed twice;
       // if it's been already discovered it must be on another
@@ -1136,10 +1098,7 @@
     list->set_head(obj);
     list->inc_length(1);
 
-    if (TraceReferenceGC) {
-      gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
-                                p2i(obj), obj->klass()->internal_name());
-    }
+    log_develop_trace(gc, ref)("Discovered reference (" INTPTR_FORMAT ": %s)", p2i(obj), obj->klass()->internal_name());
   }
   assert(obj->is_oop(), "Discovered a bad reference");
   verify_referent(obj);
@@ -1159,8 +1118,7 @@
 
   // Soft references
   {
-    GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer);
+    GCTraceTime(Debug, gc, ref) tm("Preclean SoftReferences", gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1172,8 +1130,7 @@
 
   // Weak references
   {
-    GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer);
+    GCTraceTime(Debug, gc, ref) tm("Preclean WeakReferences", gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1185,8 +1142,7 @@
 
   // Final references
   {
-    GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer);
+    GCTraceTime(Debug, gc, ref) tm("Preclean FinalReferences", gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1198,8 +1154,7 @@
 
   // Phantom references
   {
-    GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
-              false, gc_timer);
+    GCTraceTime(Debug, gc, ref) tm("Preclean PhantomReferences", gc_timer);
     for (uint i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
@@ -1244,10 +1199,8 @@
         next != NULL) {
       // The referent has been cleared, or is alive, or the Reference is not
       // active; we need to trace and mark its cohort.
-      if (TraceReferenceGC) {
-        gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
-                               p2i(iter.obj()), iter.obj()->klass()->internal_name());
-      }
+      log_develop_trace(gc, ref)("Precleaning Reference (" INTPTR_FORMAT ": %s)",
+                                 p2i(iter.obj()), iter.obj()->klass()->internal_name());
       // Remove Reference object from list
       iter.remove();
       // Keep alive its cohort.
@@ -1268,9 +1221,8 @@
   complete_gc->do_void();
 
   NOT_PRODUCT(
-    if (PrintGCDetails && PrintReferenceGC && (iter.processed() > 0)) {
-      gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT
-        " Refs in discovered list " INTPTR_FORMAT,
+    if (iter.processed() > 0) {
+      log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT " Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), p2i(refs_list.head()));
     }
   )
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -364,7 +364,9 @@
   void clear_discovered_references(DiscoveredList& refs_list);
 
   // Calculate the number of jni handles.
-  unsigned int count_jni_refs();
+  size_t count_jni_refs();
+
+  void log_reflist_counts(DiscoveredList ref_lists[], size_t total_count) PRODUCT_RETURN;
 
   // Balances reference queues.
   void balance_queues(DiscoveredList ref_lists[]);
--- a/hotspot/src/share/vm/gc/shared/space.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/space.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -220,7 +220,6 @@
   // moving as a part of compaction.
   virtual void adjust_pointers() = 0;
 
-  // PrintHeapAtGC support
   virtual void print() const;
   virtual void print_on(outputStream* st) const;
   virtual void print_short() const;
@@ -659,7 +658,6 @@
   // Overrides for more efficient compaction support.
   void prepare_for_compaction(CompactPoint* cp);
 
-  // PrintHeapAtGC support.
   virtual void print_on(outputStream* st) const;
 
   // Checked dynamic downcasts.
--- a/hotspot/src/share/vm/gc/shared/spaceDecorator.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/spaceDecorator.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
+#include "logging/log.hpp"
 #include "utilities/copy.hpp"
 
 // Catch-all file for utility classes
@@ -83,13 +84,9 @@
 void SpaceMangler::mangle_region(MemRegion mr) {
   assert(ZapUnusedHeapArea, "Mangling should not be in use");
 #ifdef ASSERT
-  if(TraceZapUnusedHeapArea) {
-    gclog_or_tty->print("Mangling [" PTR_FORMAT " to " PTR_FORMAT ")", p2i(mr.start()), p2i(mr.end()));
-  }
+  log_develop_trace(gc)("Mangling [" PTR_FORMAT " to " PTR_FORMAT ")", p2i(mr.start()), p2i(mr.end()));
   Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord);
-  if(TraceZapUnusedHeapArea) {
-    gclog_or_tty->print_cr(" done");
-  }
+  log_develop_trace(gc)("Mangling done.");
 #endif
 }
 
--- a/hotspot/src/share/vm/gc/shared/taskqueue.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/taskqueue.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/taskqueue.hpp"
 #include "oops/oop.inline.hpp"
+#include "logging/log.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/thread.inline.hpp"
@@ -212,11 +213,8 @@
 #endif
         }
       } else {
-        if (PrintGCDetails && Verbose) {
-         gclog_or_tty->print_cr("ParallelTaskTerminator::offer_termination() "
-           "thread " PTR_FORMAT " sleeps after %u yields",
-           p2i(Thread::current()), yield_count);
-        }
+        log_develop_trace(gc, task)("ParallelTaskTerminator::offer_termination() thread " PTR_FORMAT " sleeps after %u yields",
+                                    p2i(Thread::current()), yield_count);
         yield_count = 0;
         // A sleep will cause this processor to seek work on another processor's
         // runqueue, if it has nothing else to run (as opposed to the yield
@@ -240,7 +238,7 @@
 
 #ifdef TRACESPINNING
 void ParallelTaskTerminator::print_termination_counts() {
-  gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %u"
+  log_trace(gc, task)("ParallelTaskTerminator Total yields: %u"
     " Total spins: %u Total peeks: %u",
     total_yields(),
     total_spins(),
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/threadLocalAllocBuffer.inline.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -54,9 +55,7 @@
   // Publish new stats if some allocation occurred.
   if (global_stats()->allocation() != 0) {
     global_stats()->publish();
-    if (PrintTLAB) {
-      global_stats()->print();
-    }
+    global_stats()->print();
   }
 }
 
@@ -70,9 +69,7 @@
   size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc;
   _allocated_before_last_gc = total_allocated;
 
-  if (PrintTLAB && (_number_of_refills > 0 || Verbose)) {
-    print_stats("gc");
-  }
+  print_stats("gc");
 
   if (_number_of_refills > 0) {
     // Update allocation history if a reasonable amount of eden was allocated.
@@ -149,12 +146,11 @@
 
   size_t aligned_new_size = align_object_size(new_size);
 
-  if (PrintTLAB && Verbose) {
-    gclog_or_tty->print("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
-                        " refills %d  alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT "\n",
-                        p2i(myThread()), myThread()->osthread()->thread_id(),
-                        _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
-  }
+  log_trace(gc, tlab)("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
+                      " refills %d  alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT,
+                      p2i(myThread()), myThread()->osthread()->thread_id(),
+                      _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
+
   set_desired_size(aligned_new_size);
   set_refill_waste_limit(initial_refill_waste_limit());
 }
@@ -171,9 +167,7 @@
                                   HeapWord* top,
                                   size_t    new_size) {
   _number_of_refills++;
-  if (PrintTLAB && Verbose) {
-    print_stats("fill");
-  }
+  print_stats("fill");
   assert(top <= start + new_size - alignment_reserve(), "size too small");
   initialize(start, top, start + new_size - alignment_reserve());
 
@@ -226,10 +220,8 @@
   guarantee(Thread::current()->is_Java_thread(), "tlab initialization thread not Java thread");
   Thread::current()->tlab().initialize();
 
-  if (PrintTLAB && Verbose) {
-    gclog_or_tty->print("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT "\n",
-                        min_size(), Thread::current()->tlab().initial_desired_size(), max_size());
-  }
+  log_develop_trace(gc, tlab)("TLAB min: " SIZE_FORMAT " initial: " SIZE_FORMAT " max: " SIZE_FORMAT,
+                               min_size(), Thread::current()->tlab().initial_desired_size(), max_size());
 }
 
 size_t ThreadLocalAllocBuffer::initial_desired_size() {
@@ -250,26 +242,31 @@
 }
 
 void ThreadLocalAllocBuffer::print_stats(const char* tag) {
+  LogHandle(gc, tlab) log;
+  if (!log.is_trace()) {
+    return;
+  }
+
   Thread* thrd = myThread();
   size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste;
   size_t alloc = _number_of_refills * _desired_size;
   double waste_percent = alloc == 0 ? 0.0 :
                       100.0 * waste / alloc;
   size_t tlab_used  = Universe::heap()->tlab_used(thrd);
-  gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
-                      " desired_size: " SIZE_FORMAT "KB"
-                      " slow allocs: %d  refill waste: " SIZE_FORMAT "B"
-                      " alloc:%8.5f %8.0fKB refills: %d waste %4.1f%% gc: %dB"
-                      " slow: %dB fast: %dB\n",
-                      tag, p2i(thrd), thrd->osthread()->thread_id(),
-                      _desired_size / (K / HeapWordSize),
-                      _slow_allocations, _refill_waste_limit * HeapWordSize,
-                      _allocation_fraction.average(),
-                      _allocation_fraction.average() * tlab_used / K,
-                      _number_of_refills, waste_percent,
-                      _gc_waste * HeapWordSize,
-                      _slow_refill_waste * HeapWordSize,
-                      _fast_refill_waste * HeapWordSize);
+  log.trace("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
+            " desired_size: " SIZE_FORMAT "KB"
+            " slow allocs: %d  refill waste: " SIZE_FORMAT "B"
+            " alloc:%8.5f %8.0fKB refills: %d waste %4.1f%% gc: %dB"
+            " slow: %dB fast: %dB",
+            tag, p2i(thrd), thrd->osthread()->thread_id(),
+            _desired_size / (K / HeapWordSize),
+            _slow_allocations, _refill_waste_limit * HeapWordSize,
+            _allocation_fraction.average(),
+            _allocation_fraction.average() * tlab_used / K,
+            _number_of_refills, waste_percent,
+            _gc_waste * HeapWordSize,
+            _slow_refill_waste * HeapWordSize,
+            _fast_refill_waste * HeapWordSize);
 }
 
 void ThreadLocalAllocBuffer::verify() {
@@ -388,22 +385,27 @@
 }
 
 void GlobalTLABStats::print() {
+  LogHandle(gc, tlab) log;
+  if (!log.is_debug()) {
+    return;
+  }
+
   size_t waste = _total_gc_waste + _total_slow_refill_waste + _total_fast_refill_waste;
   double waste_percent = _total_allocation == 0 ? 0.0 :
                          100.0 * waste / _total_allocation;
-  gclog_or_tty->print("TLAB totals: thrds: %d  refills: %d max: %d"
-                      " slow allocs: %d max %d waste: %4.1f%%"
-                      " gc: " SIZE_FORMAT "B max: " SIZE_FORMAT "B"
-                      " slow: " SIZE_FORMAT "B max: " SIZE_FORMAT "B"
-                      " fast: " SIZE_FORMAT "B max: " SIZE_FORMAT "B\n",
-                      _allocating_threads,
-                      _total_refills, _max_refills,
-                      _total_slow_allocations, _max_slow_allocations,
-                      waste_percent,
-                      _total_gc_waste * HeapWordSize,
-                      _max_gc_waste * HeapWordSize,
-                      _total_slow_refill_waste * HeapWordSize,
-                      _max_slow_refill_waste * HeapWordSize,
-                      _total_fast_refill_waste * HeapWordSize,
-                      _max_fast_refill_waste * HeapWordSize);
+  log.debug("TLAB totals: thrds: %d  refills: %d max: %d"
+            " slow allocs: %d max %d waste: %4.1f%%"
+            " gc: " SIZE_FORMAT "B max: " SIZE_FORMAT "B"
+            " slow: " SIZE_FORMAT "B max: " SIZE_FORMAT "B"
+            " fast: " SIZE_FORMAT "B max: " SIZE_FORMAT "B",
+            _allocating_threads,
+            _total_refills, _max_refills,
+            _total_slow_allocations, _max_slow_allocations,
+            waste_percent,
+            _total_gc_waste * HeapWordSize,
+            _max_gc_waste * HeapWordSize,
+            _total_slow_refill_waste * HeapWordSize,
+            _max_slow_refill_waste * HeapWordSize,
+            _total_fast_refill_waste * HeapWordSize,
+            _max_fast_refill_waste * HeapWordSize);
 }
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/threadLocalAllocBuffer.hpp"
+#include "logging/log.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/copy.hpp"
 
@@ -66,18 +67,12 @@
   const size_t obj_plus_filler_size = aligned_obj_size + alignment_reserve();
   if (new_tlab_size < obj_plus_filler_size) {
     // If there isn't enough room for the allocation, return failure.
-    if (PrintTLAB && Verbose) {
-      gclog_or_tty->print_cr("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ")"
-                    " returns failure",
-                    obj_size);
-    }
+    log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ") returns failure",
+                        obj_size);
     return 0;
   }
-  if (PrintTLAB && Verbose) {
-    gclog_or_tty->print_cr("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ")"
-                  " returns " SIZE_FORMAT,
-                  obj_size, new_tlab_size);
-  }
+  log_trace(gc, tlab)("ThreadLocalAllocBuffer::compute_size(" SIZE_FORMAT ") returns " SIZE_FORMAT,
+                      obj_size, new_tlab_size);
   return new_tlab_size;
 }
 
@@ -91,15 +86,12 @@
 
   _slow_allocations++;
 
-  if (PrintTLAB && Verbose) {
-    Thread* thrd = myThread();
-    gclog_or_tty->print("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
-                        " obj: " SIZE_FORMAT
-                        " free: " SIZE_FORMAT
-                        " waste: " SIZE_FORMAT "\n",
-                        "slow", p2i(thrd), thrd->osthread()->thread_id(),
-                        obj_size, free(), refill_waste_limit());
-  }
+  log_develop_trace(gc, tlab)("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
+                              " obj: " SIZE_FORMAT
+                              " free: " SIZE_FORMAT
+                              " waste: " SIZE_FORMAT,
+                              "slow", p2i(myThread()), myThread()->osthread()->thread_id(),
+                              obj_size, free(), refill_waste_limit());
 }
 
 #endif // SHARE_VM_GC_SHARED_THREADLOCALALLOCBUFFER_INLINE_HPP
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/oopFactory.hpp"
+#include "logging/log.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "runtime/handles.inline.hpp"
@@ -216,16 +217,6 @@
   return false;
 }
 
-static void log_metaspace_alloc_failure_for_concurrent_GC() {
-  if (Verbose && PrintGCDetails) {
-    if (UseConcMarkSweepGC) {
-      gclog_or_tty->print_cr("\nCMS full GC for Metaspace");
-    } else if (UseG1GC) {
-      gclog_or_tty->print_cr("\nG1 full GC for Metaspace");
-    }
-  }
-}
-
 void VM_CollectForMetadataAllocation::doit() {
   SvcGCMarker sgcm(SvcGCMarker::FULL);
 
@@ -249,7 +240,7 @@
       return;
     }
 
-    log_metaspace_alloc_failure_for_concurrent_GC();
+    log_debug(gc)("%s full GC for Metaspace", UseConcMarkSweepGC ? "CMS" : "G1");
   }
 
   // Don't clear the soft refs yet.
@@ -282,10 +273,7 @@
     return;
   }
 
-  if (Verbose && PrintGCDetails) {
-    gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size "
-                           SIZE_FORMAT, _size);
-  }
+  log_debug(gc)("After Metaspace GC failed to allocate size " SIZE_FORMAT, _size);
 
   if (GC_locker::is_active_and_needs_gc()) {
     set_gc_locked();
--- a/hotspot/src/share/vm/gc/shared/workgroup.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -500,122 +500,42 @@
   return false;
 }
 
-bool FreeIdSet::_stat_init = false;
-FreeIdSet* FreeIdSet::_sets[NSets];
-bool FreeIdSet::_safepoint;
-
-FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
-  _sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
+FreeIdSet::FreeIdSet(uint size, Monitor* mon) :
+  _size(size), _mon(mon), _hd(0), _waiters(0), _claimed(0)
 {
-  _ids = NEW_C_HEAP_ARRAY(int, sz, mtInternal);
-  for (int i = 0; i < sz; i++) _ids[i] = i+1;
-  _ids[sz-1] = end_of_list; // end of list.
-  if (_stat_init) {
-    for (int j = 0; j < NSets; j++) _sets[j] = NULL;
-    _stat_init = true;
+  guarantee(size != 0, "must be");
+  _ids = NEW_C_HEAP_ARRAY(uint, size, mtGC);
+  for (uint i = 0; i < size - 1; i++) {
+    _ids[i] = i+1;
   }
-  // Add to sets.  (This should happen while the system is still single-threaded.)
-  for (int j = 0; j < NSets; j++) {
-    if (_sets[j] == NULL) {
-      _sets[j] = this;
-      _index = j;
-      break;
-    }
-  }
-  guarantee(_index != -1, "Too many FreeIdSets in use!");
+  _ids[size-1] = end_of_list; // end of list.
 }
 
 FreeIdSet::~FreeIdSet() {
-  _sets[_index] = NULL;
-  FREE_C_HEAP_ARRAY(int, _ids);
+  FREE_C_HEAP_ARRAY(uint, _ids);
 }
 
-void FreeIdSet::set_safepoint(bool b) {
-  _safepoint = b;
-  if (b) {
-    for (int j = 0; j < NSets; j++) {
-      if (_sets[j] != NULL && _sets[j]->_waiters > 0) {
-        Monitor* mon = _sets[j]->_mon;
-        mon->lock_without_safepoint_check();
-        mon->notify_all();
-        mon->unlock();
-      }
-    }
-  }
-}
-
-#define FID_STATS 0
-
-int FreeIdSet::claim_par_id() {
-#if FID_STATS
-  thread_t tslf = thr_self();
-  tty->print("claim_par_id[%d]: sz = %d, claimed = %d\n", tslf, _sz, _claimed);
-#endif
+uint FreeIdSet::claim_par_id() {
   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
-  while (!_safepoint && _hd == end_of_list) {
+  while (_hd == end_of_list) {
     _waiters++;
-#if FID_STATS
-    if (_waiters > 5) {
-      tty->print("claim_par_id waiting[%d]: %d waiters, %d claimed.\n",
-                 tslf, _waiters, _claimed);
-    }
-#endif
     _mon->wait(Mutex::_no_safepoint_check_flag);
     _waiters--;
   }
-  if (_hd == end_of_list) {
-#if FID_STATS
-    tty->print("claim_par_id[%d]: returning EOL.\n", tslf);
-#endif
-    return -1;
-  } else {
-    int res = _hd;
-    _hd = _ids[res];
-    _ids[res] = claimed;  // For debugging.
-    _claimed++;
-#if FID_STATS
-    tty->print("claim_par_id[%d]: returning %d, claimed = %d.\n",
-               tslf, res, _claimed);
-#endif
-    return res;
-  }
+  uint res = _hd;
+  _hd = _ids[res];
+  _ids[res] = claimed;  // For debugging.
+  _claimed++;
+  return res;
 }
 
-bool FreeIdSet::claim_perm_id(int i) {
-  assert(0 <= i && i < _sz, "Out of range.");
-  MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
-  int prev = end_of_list;
-  int cur = _hd;
-  while (cur != end_of_list) {
-    if (cur == i) {
-      if (prev == end_of_list) {
-        _hd = _ids[cur];
-      } else {
-        _ids[prev] = _ids[cur];
-      }
-      _ids[cur] = claimed;
-      _claimed++;
-      return true;
-    } else {
-      prev = cur;
-      cur = _ids[cur];
-    }
-  }
-  return false;
-
-}
-
-void FreeIdSet::release_par_id(int id) {
+void FreeIdSet::release_par_id(uint id) {
   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
   assert(_ids[id] == claimed, "Precondition.");
   _ids[id] = _hd;
   _hd = id;
   _claimed--;
-#if FID_STATS
-  tty->print("[%d] release_par_id(%d), waiters =%d,  claimed = %d.\n",
-             thr_self(), id, _waiters, _claimed);
-#endif
-  if (_waiters > 0)
-    // Notify all would be safer, but this is OK, right?
+  if (_waiters > 0) {
     _mon->notify_all();
+  }
 }
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -379,42 +379,29 @@
 };
 
 // Represents a set of free small integer ids.
-class FreeIdSet : public CHeapObj<mtInternal> {
+class FreeIdSet : public CHeapObj<mtGC> {
   enum {
-    end_of_list = -1,
-    claimed = -2
+    end_of_list = UINT_MAX,
+    claimed = UINT_MAX - 1
   };
 
-  int _sz;
+  uint _size;
   Monitor* _mon;
 
-  int* _ids;
-  int _hd;
-  int _waiters;
-  int _claimed;
-
-  static bool _safepoint;
-  typedef FreeIdSet* FreeIdSetPtr;
-  static const int NSets = 10;
-  static FreeIdSetPtr _sets[NSets];
-  static bool _stat_init;
-  int _index;
+  uint* _ids;
+  uint _hd;
+  uint _waiters;
+  uint _claimed;
 
 public:
-  FreeIdSet(int sz, Monitor* mon);
+  FreeIdSet(uint size, Monitor* mon);
   ~FreeIdSet();
 
-  static void set_safepoint(bool b);
-
-  // Attempt to claim the given id permanently.  Returns "true" iff
-  // successful.
-  bool claim_perm_id(int i);
+  // Returns an unclaimed parallel id (waiting for one to be released if
+  // necessary).
+  uint claim_par_id();
 
-  // Returns an unclaimed parallel id (waiting for one to be released if
-  // necessary).  Returns "-1" if a GC wakes up a wait for an id.
-  int claim_par_id();
-
-  void release_par_id(int id);
+  void release_par_id(uint id);
 };
 
 #endif // SHARE_VM_GC_SHARED_WORKGROUP_HPP
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -314,6 +314,27 @@
   THROW_HANDLE(exception);
 IRT_END
 
+IRT_ENTRY(address, InterpreterRuntime::check_ReservedStackAccess_annotated_methods(JavaThread* thread))
+  frame fr = thread->last_frame();
+  assert(fr.is_java_frame(), "Must be a Java frame");
+  frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+  if (activation.sp() != NULL) {
+    thread->disable_stack_reserved_zone();
+    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+  }
+  return (address)activation.sp();
+IRT_END
+
+ IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
+  Handle exception = get_preinitialized_exception(
+                                 SystemDictionary::StackOverflowError_klass(),
+                                 CHECK);
+  java_lang_Throwable::set_message(exception(),
+          Universe::delayed_stack_overflow_error_message());
+  // Increment counter for hs_err file reporting
+  Atomic::inc(&Exceptions::_stack_overflow_errors);
+  THROW_HANDLE(exception);
+IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message))
   // lookup exception klass
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -91,10 +91,13 @@
   // Quicken instance-of and check-cast bytecodes
   static void    quicken_io_cc(JavaThread* thread);
 
+  static address check_ReservedStackAccess_annotated_methods(JavaThread* thread);
+
   // Exceptions thrown by the interpreter
   static void    throw_AbstractMethodError(JavaThread* thread);
   static void    throw_IncompatibleClassChangeError(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
+  static void    throw_delayed_StackOverflowError(JavaThread* thread);
   static void    throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index);
   static void    throw_ClassCastException(JavaThread* thread, oopDesc* obj);
   static void    create_exception(JavaThread* thread, char* name, char* message);
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -248,7 +248,7 @@
   // Check the stack guard pages and reenable them if necessary and there is
   // enough space on the stack to do so.  Use fast exceptions only if the guard
   // pages are enabled.
-  bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+  bool guard_pages_enabled = thread->stack_guards_enabled();
   if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
 
   if (JvmtiExport::can_post_on_exceptions()) {
--- a/hotspot/src/share/vm/logging/logPrefix.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -38,7 +38,38 @@
 // List of prefixes for specific tags and/or tagsets.
 // Syntax: LOG_PREFIX(<name of prefixer function>, LOG_TAGS(<chosen log tags>))
 // Where the prefixer function matches the following signature: size_t (*)(char*, size_t)
-#define LOG_PREFIX_LIST // Currently unused/empty
+#define LOG_PREFIX_LIST \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, age)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, alloc)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, barrier)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, compaction)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, compaction, phases)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, cpu)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, cset)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, heap)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, ihop)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, freelist)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ihop)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, liveness)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, metaspace)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, start)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, plab)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, region)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, remset)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, sweep)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, start)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, stats)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, time)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, tlab))
+
 
 // The empty prefix, used when there's no prefix defined.
 template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag = LogTag::__NO_TAG>
--- a/hotspot/src/share/vm/logging/logTag.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/logging/logTag.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -31,11 +31,52 @@
 // (The tags 'all', 'disable' and 'help' are special tags that can
 // not be used in log calls, and should not be listed below.)
 #define LOG_TAG_LIST \
+  LOG_TAG(alloc) \
+  LOG_TAG(age) \
+  LOG_TAG(barrier) \
+  LOG_TAG(bot) \
+  LOG_TAG(census) \
+  LOG_TAG(classhisto) \
   LOG_TAG(classinit) \
+  LOG_TAG(comp) \
+  LOG_TAG(compaction) \
+  LOG_TAG(cpu) \
+  LOG_TAG(cset) \
   LOG_TAG(defaultmethods) \
+  LOG_TAG(ergo) \
+  LOG_TAG(exit) \
+  LOG_TAG(freelist) \
   LOG_TAG(gc) \
+  LOG_TAG(heap) \
+  LOG_TAG(humongous) \
+  LOG_TAG(ihop) \
+  LOG_TAG(jni) \
+  LOG_TAG(liveness) \
   LOG_TAG(logging) \
+  LOG_TAG(marking) \
+  LOG_TAG(metaspace) \
+  LOG_TAG(phases) \
+  LOG_TAG(plab) \
+  LOG_TAG(promotion) \
+  LOG_TAG(ref) \
+  LOG_TAG(refine) \
+  LOG_TAG(region) \
+  LOG_TAG(remset) \
+  LOG_TAG(rt) \
   LOG_TAG(safepoint) \
+  LOG_TAG(scavenge) \
+  LOG_TAG(scrub) \
+  LOG_TAG(start) \
+  LOG_TAG(state) \
+  LOG_TAG(stats) \
+  LOG_TAG(stringdedup) \
+  LOG_TAG(survivor) \
+  LOG_TAG(svc) \
+  LOG_TAG(sweep) \
+  LOG_TAG(task) \
+  LOG_TAG(tlab) \
+  LOG_TAG(time) \
+  LOG_TAG(verify) \
   LOG_TAG(vmoperation)
 
 #define PREFIX_LOG_TAG(T) (LogTag::_##T)
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "memory/freeBlockDictionary.hpp"
 #include "memory/freeList.hpp"
 #include "memory/metachunk.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/globals.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
@@ -1189,27 +1190,29 @@
   // Does walking the tree 3 times hurt?
   set_tree_surplus(splitSurplusPercent);
   set_tree_hints();
-  if (PrintGC && Verbose) {
-    report_statistics();
+  LogHandle(gc, freelist, stats) log;
+  if (log.is_trace()) {
+    ResourceMark rm;
+    report_statistics(log.trace_stream());
   }
   clear_tree_census();
 }
 
 // Print summary statistics
 template <class Chunk_t, class FreeList_t>
-void BinaryTreeDictionary<Chunk_t, FreeList_t>::report_statistics() const {
+void BinaryTreeDictionary<Chunk_t, FreeList_t>::report_statistics(outputStream* st) const {
   FreeBlockDictionary<Chunk_t>::verify_par_locked();
-  gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n"
-         "------------------------------------\n");
+  st->print_cr("Statistics for BinaryTreeDictionary:");
+  st->print_cr("------------------------------------");
   size_t total_size = total_chunk_size(debug_only(NULL));
-  size_t    free_blocks = num_free_blocks();
-  gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size);
-  gclog_or_tty->print("Max   Chunk Size: " SIZE_FORMAT "\n", max_chunk_size());
-  gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks);
+  size_t free_blocks = num_free_blocks();
+  st->print_cr("Total Free Space: " SIZE_FORMAT, total_size);
+  st->print_cr("Max   Chunk Size: " SIZE_FORMAT, max_chunk_size());
+  st->print_cr("Number of Blocks: " SIZE_FORMAT, free_blocks);
   if (free_blocks > 0) {
-    gclog_or_tty->print("Av.  Block  Size: " SIZE_FORMAT "\n", total_size/free_blocks);
+    st->print_cr("Av.  Block  Size: " SIZE_FORMAT, total_size/free_blocks);
   }
-  gclog_or_tty->print("Tree      Height: " SIZE_FORMAT "\n", tree_height());
+  st->print_cr("Tree      Height: " SIZE_FORMAT, tree_height());
 }
 
 // Print census information - counts, births, deaths, etc.
@@ -1229,22 +1232,27 @@
   FreeList_t* total() { return &_total; }
   size_t total_free() { return _total_free; }
   void do_list(FreeList<Chunk_t>* fl) {
+    LogHandle(gc, freelist, census) log;
+    outputStream* out = log.debug_stream();
     if (++_print_line >= 40) {
-      FreeList_t::print_labels_on(gclog_or_tty, "size");
+      ResourceMark rm;
+      FreeList_t::print_labels_on(out, "size");
       _print_line = 0;
     }
-    fl->print_on(gclog_or_tty);
-    _total_free +=            fl->count()            * fl->size()        ;
-    total()->set_count(      total()->count()       + fl->count()      );
+    fl->print_on(out);
+    _total_free += fl->count() * fl->size();
+    total()->set_count(total()->count() + fl->count());
   }
 
 #if INCLUDE_ALL_GCS
   void do_list(AdaptiveFreeList<Chunk_t>* fl) {
+    LogHandle(gc, freelist, census) log;
+    outputStream* out = log.debug_stream();
     if (++_print_line >= 40) {
-      FreeList_t::print_labels_on(gclog_or_tty, "size");
+      FreeList_t::print_labels_on(out, "size");
       _print_line = 0;
     }
-    fl->print_on(gclog_or_tty);
+    fl->print_on(out);
     _total_free +=           fl->count()             * fl->size()        ;
     total()->set_count(      total()->count()        + fl->count()      );
     total()->set_bfr_surp(   total()->bfr_surp()     + fl->bfr_surp()    );
@@ -1261,38 +1269,36 @@
 };
 
 template <class Chunk_t, class FreeList_t>
-void BinaryTreeDictionary<Chunk_t, FreeList_t>::print_dict_census(void) const {
+void BinaryTreeDictionary<Chunk_t, FreeList_t>::print_dict_census(outputStream* st) const {
 
-  gclog_or_tty->print("\nBinaryTree\n");
-  FreeList_t::print_labels_on(gclog_or_tty, "size");
+  st->print("BinaryTree");
+  FreeList_t::print_labels_on(st, "size");
   PrintTreeCensusClosure<Chunk_t, FreeList_t> ptc;
   ptc.do_tree(root());
 
   FreeList_t* total = ptc.total();
-  FreeList_t::print_labels_on(gclog_or_tty, " ");
+  FreeList_t::print_labels_on(st, " ");
 }
 
 #if INCLUDE_ALL_GCS
 template <>
-void AFLBinaryTreeDictionary::print_dict_census(void) const {
+void AFLBinaryTreeDictionary::print_dict_census(outputStream* st) const {
 
-  gclog_or_tty->print("\nBinaryTree\n");
-  AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+  st->print_cr("BinaryTree");
+  AdaptiveFreeList<FreeChunk>::print_labels_on(st, "size");
   PrintTreeCensusClosure<FreeChunk, AdaptiveFreeList<FreeChunk> > ptc;
   ptc.do_tree(root());
 
   AdaptiveFreeList<FreeChunk>* total = ptc.total();
-  AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, " ");
-  total->print_on(gclog_or_tty, "TOTAL\t");
-  gclog_or_tty->print(
-              "total_free(words): " SIZE_FORMAT_W(16)
-              " growth: %8.5f  deficit: %8.5f\n",
-              ptc.total_free(),
-              (double)(total->split_births() + total->coal_births()
-                     - total->split_deaths() - total->coal_deaths())
-              /(total->prev_sweep() != 0 ? (double)total->prev_sweep() : 1.0),
-             (double)(total->desired() - total->count())
-             /(total->desired() != 0 ? (double)total->desired() : 1.0));
+  AdaptiveFreeList<FreeChunk>::print_labels_on(st, " ");
+  total->print_on(st, "TOTAL\t");
+  st->print_cr("total_free(words): " SIZE_FORMAT_W(16) " growth: %8.5f  deficit: %8.5f",
+               ptc.total_free(),
+               (double)(total->split_births() + total->coal_births()
+                      - total->split_deaths() - total->coal_deaths())
+               /(total->prev_sweep() != 0 ? (double)total->prev_sweep() : 1.0),
+              (double)(total->desired() - total->count())
+              /(total->desired() != 0 ? (double)total->desired() : 1.0));
 }
 #endif // INCLUDE_ALL_GCS
 
@@ -1311,7 +1317,7 @@
       FreeList_t::print_labels_on(_st, "size");
       _print_line = 0;
     }
-    fl->print_on(gclog_or_tty);
+    fl->print_on(_st);
     size_t sz = fl->size();
     for (Chunk_t* fc = fl->head(); fc != NULL;
          fc = fc->next()) {
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -324,7 +324,7 @@
   void       clear_tree_census(void);
   // Print the statistics for all the lists in the tree.  Also may
   // print out summaries.
-  void       print_dict_census(void) const;
+  void       print_dict_census(outputStream* st) const;
   void       print_free_lists(outputStream* st) const;
 
   // For debugging.  Returns the sum of the _returned_bytes for
@@ -335,7 +335,7 @@
   // For debugging.  Return the total number of chunks in the dictionary.
   size_t     total_count()       PRODUCT_RETURN0;
 
-  void       report_statistics() const;
+  void       report_statistics(outputStream* st) const;
 
   void       verify() const;
 };
--- a/hotspot/src/share/vm/memory/filemap.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -954,11 +954,11 @@
 }
 
 void FileMapInfo::print_shared_spaces() {
-  gclog_or_tty->print_cr("Shared Spaces:");
+  tty->print_cr("Shared Spaces:");
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
     struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
     char *base = _header->region_addr(i);
-    gclog_or_tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
+    tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
                         shared_region_name[i],
                         p2i(base), p2i(base + si->_used));
   }
--- a/hotspot/src/share/vm/memory/freeBlockDictionary.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -89,11 +89,11 @@
     virtual size_t   total_count() = 0;
   )
 
-  virtual void       report_statistics() const {
-    gclog_or_tty->print("No statistics available");
+  virtual void       report_statistics(outputStream* st) const {
+    st->print_cr("No statistics available");
   }
 
-  virtual void       print_dict_census() const = 0;
+  virtual void       print_dict_census(outputStream* st) const = 0;
   virtual void       print_free_lists(outputStream* st) const = 0;
 
   virtual void       verify()         const = 0;
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -25,6 +25,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcLocker.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/binaryTreeDictionary.hpp"
 #include "memory/filemap.hpp"
@@ -811,8 +812,10 @@
 BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {}
 
 BlockFreelist::~BlockFreelist() {
-  if (Verbose && TraceMetadataChunkAllocation) {
-    dictionary()->print_free_lists(gclog_or_tty);
+  LogHandle(gc, metaspace, freelist) log;
+  if (log.is_trace()) {
+    ResourceMark rm;
+    dictionary()->print_free_lists(log.trace_stream());
   }
   delete _dictionary;
 }
@@ -892,11 +895,11 @@
       "The committed memory doesn't match the expanded memory.");
 
   if (!is_available(chunk_word_size)) {
-    if (TraceMetadataChunkAllocation) {
-      gclog_or_tty->print("VirtualSpaceNode::take_from_committed() not available " SIZE_FORMAT " words ", chunk_word_size);
-      // Dump some information about the virtual space that is nearly full
-      print_on(gclog_or_tty);
-    }
+    LogHandle(gc, metaspace, freelist) log;
+    log.debug("VirtualSpaceNode::take_from_committed() not available " SIZE_FORMAT " words ", chunk_word_size);
+    // Dump some information about the virtual space that is nearly full
+    ResourceMark rm;
+    print_on(log.debug_stream());
     return NULL;
   }
 
@@ -1231,9 +1234,11 @@
 #ifdef ASSERT
   new_entry->mangle();
 #endif
-  if (TraceMetavirtualspaceAllocation && Verbose) {
+  if (develop_log_is_enabled(Trace, gc, metaspace)) {
+    LogHandle(gc, metaspace) log;
     VirtualSpaceNode* vsl = current_virtual_space();
-    vsl->print_on(gclog_or_tty);
+    ResourceMark rm;
+    vsl->print_on(log.trace_stream());
   }
 }
 
@@ -1330,12 +1335,10 @@
 }
 
 void VirtualSpaceList::print_on(outputStream* st) const {
-  if (TraceMetadataChunkAllocation && Verbose) {
-    VirtualSpaceListIterator iter(virtual_space_list());
-    while (iter.repeat()) {
-      VirtualSpaceNode* node = iter.get_next();
-      node->print_on(st);
-    }
+  VirtualSpaceListIterator iter(virtual_space_list());
+  while (iter.repeat()) {
+    VirtualSpaceNode* node = iter.get_next();
+    node->print_on(st);
   }
 }
 
@@ -1497,17 +1500,10 @@
   minimum_desired_capacity = MAX2(minimum_desired_capacity,
                                   MetaspaceSize);
 
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print_cr("\nMetaspaceGC::compute_new_size: ");
-    gclog_or_tty->print_cr("  "
-                  "  minimum_free_percentage: %6.2f"
-                  "  maximum_used_percentage: %6.2f",
-                  minimum_free_percentage,
-                  maximum_used_percentage);
-    gclog_or_tty->print_cr("  "
-                  "   used_after_gc       : %6.1fKB",
-                  used_after_gc / (double) K);
-  }
+  log_trace(gc, metaspace)("MetaspaceGC::compute_new_size: ");
+  log_trace(gc, metaspace)("    minimum_free_percentage: %6.2f  maximum_used_percentage: %6.2f",
+                           minimum_free_percentage, maximum_used_percentage);
+  log_trace(gc, metaspace)("     used_after_gc       : %6.1fKB", used_after_gc / (double) K);
 
 
   size_t shrink_bytes = 0;
@@ -1525,17 +1521,11 @@
       Metaspace::tracer()->report_gc_threshold(capacity_until_GC,
                                                new_capacity_until_GC,
                                                MetaspaceGCThresholdUpdater::ComputeNewSize);
-      if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("    expanding:"
-                      "  minimum_desired_capacity: %6.1fKB"
-                      "  expand_bytes: %6.1fKB"
-                      "  MinMetaspaceExpansion: %6.1fKB"
-                      "  new metaspace HWM:  %6.1fKB",
-                      minimum_desired_capacity / (double) K,
-                      expand_bytes / (double) K,
-                      MinMetaspaceExpansion / (double) K,
-                      new_capacity_until_GC / (double) K);
-      }
+      log_trace(gc, metaspace)("    expanding:  minimum_desired_capacity: %6.1fKB  expand_bytes: %6.1fKB  MinMetaspaceExpansion: %6.1fKB  new metaspace HWM:  %6.1fKB",
+                               minimum_desired_capacity / (double) K,
+                               expand_bytes / (double) K,
+                               MinMetaspaceExpansion / (double) K,
+                               new_capacity_until_GC / (double) K);
     }
     return;
   }
@@ -1555,18 +1545,10 @@
     size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
     maximum_desired_capacity = MAX2(maximum_desired_capacity,
                                     MetaspaceSize);
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("  "
-                             "  maximum_free_percentage: %6.2f"
-                             "  minimum_used_percentage: %6.2f",
-                             maximum_free_percentage,
-                             minimum_used_percentage);
-      gclog_or_tty->print_cr("  "
-                             "  minimum_desired_capacity: %6.1fKB"
-                             "  maximum_desired_capacity: %6.1fKB",
-                             minimum_desired_capacity / (double) K,
-                             maximum_desired_capacity / (double) K);
-    }
+    log_trace(gc, metaspace)("    maximum_free_percentage: %6.2f  minimum_used_percentage: %6.2f",
+                             maximum_free_percentage, minimum_used_percentage);
+    log_trace(gc, metaspace)("    minimum_desired_capacity: %6.1fKB  maximum_desired_capacity: %6.1fKB",
+                             minimum_desired_capacity / (double) K, maximum_desired_capacity / (double) K);
 
     assert(minimum_desired_capacity <= maximum_desired_capacity,
            "sanity check");
@@ -1592,23 +1574,10 @@
       } else {
         _shrink_factor = MIN2(current_shrink_factor * 4, (uint) 100);
       }
-      if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("  "
-                      "  shrinking:"
-                      "  initSize: %.1fK"
-                      "  maximum_desired_capacity: %.1fK",
-                      MetaspaceSize / (double) K,
-                      maximum_desired_capacity / (double) K);
-        gclog_or_tty->print_cr("  "
-                      "  shrink_bytes: %.1fK"
-                      "  current_shrink_factor: %d"
-                      "  new shrink factor: %d"
-                      "  MinMetaspaceExpansion: %.1fK",
-                      shrink_bytes / (double) K,
-                      current_shrink_factor,
-                      _shrink_factor,
-                      MinMetaspaceExpansion / (double) K);
-      }
+      log_trace(gc, metaspace)("    shrinking:  initSize: %.1fK  maximum_desired_capacity: %.1fK",
+                               MetaspaceSize / (double) K, maximum_desired_capacity / (double) K);
+      log_trace(gc, metaspace)("    shrink_bytes: %.1fK  current_shrink_factor: %d  new shrink factor: %d  MinMetaspaceExpansion: %.1fK",
+                               shrink_bytes / (double) K, current_shrink_factor, _shrink_factor, MinMetaspaceExpansion / (double) K);
     }
   }
 
@@ -1638,10 +1607,7 @@
     if (_allocation_fail_alot_count > 0) {
       _allocation_fail_alot_count--;
     } else {
-      if (TraceMetadataChunkAllocation && Verbose) {
-        gclog_or_tty->print_cr("Metadata allocation failing for "
-                               "MetadataAllocationFailALot");
-      }
+      log_trace(gc, metaspace, freelist)("Metadata allocation failing for MetadataAllocationFailALot");
       init_allocation_fail_alot_count();
       return true;
     }
@@ -1786,11 +1752,8 @@
     // Remove the chunk as the head of the list.
     free_list->remove_chunk(chunk);
 
-    if (TraceMetadataChunkAllocation && Verbose) {
-      gclog_or_tty->print_cr("ChunkManager::free_chunks_get: free_list "
-                             PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
-                             p2i(free_list), p2i(chunk), chunk->word_size());
-    }
+    log_trace(gc, metaspace, freelist)("ChunkManager::free_chunks_get: free_list " PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
+                                       p2i(free_list), p2i(chunk), chunk->word_size());
   } else {
     chunk = humongous_dictionary()->get_chunk(
       word_size,
@@ -1800,13 +1763,8 @@
       return NULL;
     }
 
-    if (TraceMetadataHumongousAllocation) {
-      size_t waste = chunk->word_size() - word_size;
-      gclog_or_tty->print_cr("Free list allocate humongous chunk size "
-                             SIZE_FORMAT " for requested size " SIZE_FORMAT
-                             " waste " SIZE_FORMAT,
-                             chunk->word_size(), word_size, waste);
-    }
+    log_debug(gc, metaspace, alloc)("Free list allocate humongous chunk size " SIZE_FORMAT " for requested size " SIZE_FORMAT " waste " SIZE_FORMAT,
+                                    chunk->word_size(), word_size, chunk->word_size() - word_size);
   }
 
   // Chunk is being removed from the chunks free list.
@@ -1839,7 +1797,8 @@
   assert((word_size <= chunk->word_size()) ||
          list_index(chunk->word_size() == HumongousIndex),
          "Non-humongous variable sized chunk");
-  if (TraceMetadataChunkAllocation) {
+  LogHandle(gc, metaspace, freelist) log;
+  if (log.is_debug()) {
     size_t list_count;
     if (list_index(word_size) < HumongousIndex) {
       ChunkList* list = find_free_chunks_list(word_size);
@@ -1847,19 +1806,17 @@
     } else {
       list_count = humongous_dictionary()->total_count();
     }
-    gclog_or_tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
-                        PTR_FORMAT "  size " SIZE_FORMAT " count " SIZE_FORMAT " ",
-                        p2i(this), p2i(chunk), chunk->word_size(), list_count);
-    locked_print_free_chunks(gclog_or_tty);
+    log.debug("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " PTR_FORMAT "  size " SIZE_FORMAT " count " SIZE_FORMAT " ",
+               p2i(this), p2i(chunk), chunk->word_size(), list_count);
+    ResourceMark rm;
+    locked_print_free_chunks(log.debug_stream());
   }
 
   return chunk;
 }
 
 void ChunkManager::print_on(outputStream* out) const {
-  if (PrintFLSStatistics != 0) {
-    const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics();
-  }
+  const_cast<ChunkManager *>(this)->humongous_dictionary()->report_statistics(out);
 }
 
 // SpaceManager methods
@@ -2039,14 +1996,12 @@
          "Size calculation is wrong, word_size " SIZE_FORMAT
          " chunk_word_size " SIZE_FORMAT,
          word_size, chunk_word_size);
-  if (TraceMetadataHumongousAllocation &&
-      SpaceManager::is_humongous(word_size)) {
-    gclog_or_tty->print_cr("Metadata humongous allocation:");
-    gclog_or_tty->print_cr("  word_size " PTR_FORMAT, word_size);
-    gclog_or_tty->print_cr("  chunk_word_size " PTR_FORMAT,
-                           chunk_word_size);
-    gclog_or_tty->print_cr("    chunk overhead " PTR_FORMAT,
-                           Metachunk::overhead());
+  LogHandle(gc, metaspace, alloc) log;
+  if (log.is_debug() && SpaceManager::is_humongous(word_size)) {
+    log.debug("Metadata humongous allocation:");
+    log.debug("  word_size " PTR_FORMAT, word_size);
+    log.debug("  chunk_word_size " PTR_FORMAT, chunk_word_size);
+    log.debug("    chunk overhead " PTR_FORMAT, Metachunk::overhead());
   }
   return chunk_word_size;
 }
@@ -2068,17 +2023,15 @@
          "Don't need to expand");
   MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
 
-  if (TraceMetadataChunkAllocation && Verbose) {
+  if (log_is_enabled(Trace, gc, metaspace, freelist)) {
     size_t words_left = 0;
     size_t words_used = 0;
     if (current_chunk() != NULL) {
       words_left = current_chunk()->free_word_size();
       words_used = current_chunk()->used_word_size();
     }
-    gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT
-                           " words " SIZE_FORMAT " words used " SIZE_FORMAT
-                           " words left",
-                            word_size, words_used, words_left);
+    log_trace(gc, metaspace, freelist)("SpaceManager::grow_and_allocate for " SIZE_FORMAT " words " SIZE_FORMAT " words used " SIZE_FORMAT " words left",
+                                       word_size, words_used, words_left);
   }
 
   // Get another chunk
@@ -2169,9 +2122,7 @@
     _chunks_in_use[i] = NULL;
   }
   _current_chunk = NULL;
-  if (TraceMetadataChunkAllocation && Verbose) {
-    gclog_or_tty->print_cr("SpaceManager(): " PTR_FORMAT, p2i(this));
-  }
+  log_trace(gc, metaspace, freelist)("SpaceManager(): " PTR_FORMAT, p2i(this));
 }
 
 void ChunkManager::return_chunks(ChunkIndex index, Metachunk* chunks) {
@@ -2213,9 +2164,11 @@
 
   dec_total_from_size_metrics();
 
-  if (TraceMetadataChunkAllocation && Verbose) {
-    gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, p2i(this));
-    locked_print_chunks_in_use_on(gclog_or_tty);
+  LogHandle(gc, metaspace, freelist) log;
+  if (log.is_trace()) {
+    log.trace("~SpaceManager(): " PTR_FORMAT, p2i(this));
+    ResourceMark rm;
+    locked_print_chunks_in_use_on(log.trace_stream());
   }
 
   // Do not mangle freed Metachunks.  The chunk size inside Metachunks
@@ -2233,19 +2186,11 @@
   // free lists.  Each list is NULL terminated.
 
   for (ChunkIndex i = ZeroIndex; i < HumongousIndex; i = next_chunk_index(i)) {
-    if (TraceMetadataChunkAllocation && Verbose) {
-      gclog_or_tty->print_cr("returned " SIZE_FORMAT " %s chunks to freelist",
-                             sum_count_in_chunks_in_use(i),
-                             chunk_size_name(i));
-    }
+    log.trace("returned " SIZE_FORMAT " %s chunks to freelist", sum_count_in_chunks_in_use(i), chunk_size_name(i));
     Metachunk* chunks = chunks_in_use(i);
     chunk_manager()->return_chunks(i, chunks);
     set_chunks_in_use(i, NULL);
-    if (TraceMetadataChunkAllocation && Verbose) {
-      gclog_or_tty->print_cr("updated freelist count " SSIZE_FORMAT " %s",
-                             chunk_manager()->free_chunks(i)->count(),
-                             chunk_size_name(i));
-    }
+    log.trace("updated freelist count " SSIZE_FORMAT " %s", chunk_manager()->free_chunks(i)->count(), chunk_size_name(i));
     assert(i != HumongousIndex, "Humongous chunks are handled explicitly later");
   }
 
@@ -2254,12 +2199,9 @@
   // the current chunk but there are probably exceptions.
 
   // Humongous chunks
-  if (TraceMetadataChunkAllocation && Verbose) {
-    gclog_or_tty->print_cr("returned " SIZE_FORMAT " %s humongous chunks to dictionary",
-                            sum_count_in_chunks_in_use(HumongousIndex),
-                            chunk_size_name(HumongousIndex));
-    gclog_or_tty->print("Humongous chunk dictionary: ");
-  }
+  log.trace("returned " SIZE_FORMAT " %s humongous chunks to dictionary",
+            sum_count_in_chunks_in_use(HumongousIndex), chunk_size_name(HumongousIndex));
+  log.trace("Humongous chunk dictionary: ");
   // Humongous chunks are never the current chunk.
   Metachunk* humongous_chunks = chunks_in_use(HumongousIndex);
 
@@ -2267,11 +2209,7 @@
 #ifdef ASSERT
     humongous_chunks->set_is_tagged_free(true);
 #endif
-    if (TraceMetadataChunkAllocation && Verbose) {
-      gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ",
-                          p2i(humongous_chunks),
-                          humongous_chunks->word_size());
-    }
+    log.trace(PTR_FORMAT " (" SIZE_FORMAT ") ", p2i(humongous_chunks), humongous_chunks->word_size());
     assert(humongous_chunks->word_size() == (size_t)
            align_size_up(humongous_chunks->word_size(),
                              smallest_chunk_size()),
@@ -2283,12 +2221,7 @@
     chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks);
     humongous_chunks = next_humongous_chunks;
   }
-  if (TraceMetadataChunkAllocation && Verbose) {
-    gclog_or_tty->cr();
-    gclog_or_tty->print_cr("updated dictionary count " SIZE_FORMAT " %s",
-                     chunk_manager()->humongous_dictionary()->total_count(),
-                     chunk_size_name(HumongousIndex));
-  }
+  log.trace("updated dictionary count " SIZE_FORMAT " %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex));
   chunk_manager()->slow_locked_verify();
 }
 
@@ -2374,11 +2307,13 @@
   inc_size_metrics(new_chunk->word_size());
 
   assert(new_chunk->is_empty(), "Not ready for reuse");
-  if (TraceMetadataChunkAllocation && Verbose) {
-    gclog_or_tty->print("SpaceManager::add_chunk: " SIZE_FORMAT ") ",
-                        sum_count_in_chunks_in_use());
-    new_chunk->print_on(gclog_or_tty);
-    chunk_manager()->locked_print_free_chunks(gclog_or_tty);
+  LogHandle(gc, metaspace, freelist) log;
+  if (log.is_trace()) {
+    log.trace("SpaceManager::add_chunk: " SIZE_FORMAT ") ", sum_count_in_chunks_in_use());
+    ResourceMark rm;
+    outputStream* out = log.trace_stream();
+    new_chunk->print_on(out);
+    chunk_manager()->locked_print_free_chunks(out);
   }
 }
 
@@ -2403,10 +2338,10 @@
                                     medium_chunk_bunch());
   }
 
-  if (TraceMetadataHumongousAllocation && next != NULL &&
+  LogHandle(gc, metaspace, alloc) log;
+  if (log.is_debug() && next != NULL &&
       SpaceManager::is_humongous(next->word_size())) {
-    gclog_or_tty->print_cr("  new humongous chunk word size "
-                           PTR_FORMAT, next->word_size());
+    log.debug("  new humongous chunk word size " PTR_FORMAT, next->word_size());
   }
 
   return next;
@@ -2571,7 +2506,7 @@
     }
   }
 
-  if (TraceMetadataChunkAllocation && Verbose) {
+  if (log_is_enabled(Trace, gc, metaspace, freelist)) {
     block_freelists()->print_on(out);
   }
 
@@ -2756,27 +2691,10 @@
 }
 
 void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
-  gclog_or_tty->print(", [Metaspace:");
-  if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print(" "  SIZE_FORMAT
-                        "->" SIZE_FORMAT
-                        "("  SIZE_FORMAT ")",
-                        prev_metadata_used,
-                        used_bytes(),
-                        reserved_bytes());
-  } else {
-    gclog_or_tty->print(" "  SIZE_FORMAT "K"
-                        "->" SIZE_FORMAT "K"
-                        "("  SIZE_FORMAT "K)",
-                        prev_metadata_used/K,
-                        used_bytes()/K,
-                        reserved_bytes()/K);
-  }
-
-  gclog_or_tty->print("]");
+  log_info(gc, metaspace)("Metaspace: "  SIZE_FORMAT "K->" SIZE_FORMAT "K("  SIZE_FORMAT "K)",
+                          prev_metadata_used/K, used_bytes()/K, reserved_bytes()/K);
 }
 
-// This is printed when PrintGCDetails
 void MetaspaceAux::print_on(outputStream* out) {
   Metaspace::MetadataType nct = Metaspace::NonClassType;
 
@@ -3133,8 +3051,10 @@
 
   initialize_class_space(metaspace_rs);
 
-  if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
-    print_compressed_class_space(gclog_or_tty, requested_addr);
+  if (develop_log_is_enabled(Trace, gc, metaspace)) {
+    LogHandle(gc, metaspace) log;
+    ResourceMark rm;
+    print_compressed_class_space(log.trace_stream(), requested_addr);
   }
 }
 
@@ -3256,10 +3176,8 @@
     assert(UseCompressedOops && UseCompressedClassPointers,
       "UseCompressedOops and UseCompressedClassPointers must be set");
     Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
-    if (TraceMetavirtualspaceAllocation && Verbose) {
-      gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
-                             p2i(_space_list->current_virtual_space()->bottom()));
-    }
+    log_develop_trace(gc, metaspace)("Setting_narrow_klass_base to Address: " PTR_FORMAT,
+                                     p2i(_space_list->current_virtual_space()->bottom()));
 
     Universe::set_narrow_klass_shift(0);
 #endif // _LP64
@@ -3446,10 +3364,7 @@
   if (incremented) {
     tracer()->report_gc_threshold(before, after,
                                   MetaspaceGCThresholdUpdater::ExpandAndAllocate);
-    if (PrintGCDetails && Verbose) {
-      gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
-          " to " SIZE_FORMAT, before, after);
-    }
+    log_trace(gc, metaspace)("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before, after);
   }
 
   return res;
@@ -3612,13 +3527,15 @@
   tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
 
   // If result is still null, we are out of memory.
-  if (Verbose && TraceMetadataChunkAllocation) {
-    gclog_or_tty->print_cr("Metaspace allocation failed for size "
-        SIZE_FORMAT, word_size);
+  LogHandle(gc, metaspace, freelist) log;
+  if (log.is_trace()) {
+    log.trace("Metaspace allocation failed for size " SIZE_FORMAT, word_size);
+    ResourceMark rm;
+    outputStream* out = log.trace_stream();
     if (loader_data->metaspace_or_null() != NULL) {
-      loader_data->dump(gclog_or_tty);
+      loader_data->dump(out);
     }
-    MetaspaceAux::dump(gclog_or_tty);
+    MetaspaceAux::dump(out);
   }
 
   bool out_of_compressed_class_space = false;
--- a/hotspot/src/share/vm/memory/universe.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -36,8 +36,10 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/generation.hpp"
+#include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/space.hpp"
 #include "interpreter/interpreter.hpp"
+#include "logging/log.hpp"
 #include "memory/filemap.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
@@ -72,6 +74,7 @@
 #include "utilities/events.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
+#include "utilities/ostream.hpp"
 #include "utilities/preserveException.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/cms/cmsCollectorPolicy.hpp"
@@ -122,6 +125,7 @@
 oop Universe::_out_of_memory_error_array_size         = NULL;
 oop Universe::_out_of_memory_error_gc_overhead_limit  = NULL;
 oop Universe::_out_of_memory_error_realloc_objects    = NULL;
+oop Universe::_delayed_stack_overflow_error_message   = NULL;
 objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
 volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
 bool Universe::_verify_in_progress                    = false;
@@ -197,7 +201,8 @@
   f->do_oop((oop*)&_out_of_memory_error_array_size);
   f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit);
   f->do_oop((oop*)&_out_of_memory_error_realloc_objects);
-    f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
+  f->do_oop((oop*)&_delayed_stack_overflow_error_message);
+  f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
   f->do_oop((oop*)&_null_ptr_exception_instance);
   f->do_oop((oop*)&_arithmetic_exception_instance);
   f->do_oop((oop*)&_virtual_machine_error_instance);
@@ -489,7 +494,7 @@
   has_run_finalizers_on_exit = true;
 
   // Called on VM exit. This ought to be run in a separate thread.
-  if (TraceReferenceGC) tty->print_cr("Callback to run finalizers on exit");
+  log_trace(ref)("Callback to run finalizers on exit");
   {
     PRESERVE_EXCEPTION_MARK;
     KlassHandle finalizer_klass(THREAD, SystemDictionary::Finalizer_klass());
@@ -713,6 +718,7 @@
   if (status != JNI_OK) {
     return status;
   }
+  log_info(gc)("Using %s", _collectedHeap->name());
 
   ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
 
@@ -905,6 +911,12 @@
       k_h->allocate_instance(CHECK_false);
     Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false);
 
+    // Setup preallocated cause message for delayed StackOverflowError
+    if (StackReservedPages > 0) {
+      Universe::_delayed_stack_overflow_error_message =
+        java_lang_String::create_oop_from_str("Delayed StackOverflowError due to ReservedStackAccess annotated method", CHECK_false);
+    }
+
     // Setup preallocated NullPointerException
     // (this is currently used for a cheap & dirty solution in compiler exception handling)
     k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false);
@@ -1059,18 +1071,9 @@
   _base_vtable_size = ClassLoader::compute_Object_vtable();
 }
 
-
-void Universe::print() {
-  print_on(gclog_or_tty);
-}
-
-void Universe::print_on(outputStream* st, bool extended) {
+void Universe::print_on(outputStream* st) {
   st->print_cr("Heap");
-  if (!extended) {
-    heap()->print_on(st);
-  } else {
-    heap()->print_extended_on(st);
-  }
+  heap()->print_on(st);
 }
 
 void Universe::print_heap_at_SIGBREAK() {
@@ -1082,30 +1085,25 @@
   }
 }
 
-void Universe::print_heap_before_gc(outputStream* st, bool ignore_extended) {
-  st->print_cr("{Heap before GC invocations=%u (full %u):",
-               heap()->total_collections(),
-               heap()->total_full_collections());
-  if (!PrintHeapAtGCExtended || ignore_extended) {
-    heap()->print_on(st);
-  } else {
-    heap()->print_extended_on(st);
+void Universe::print_heap_before_gc() {
+  LogHandle(gc, heap) log;
+  if (log.is_trace()) {
+    log.trace("Heap before GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
+    ResourceMark rm;
+    heap()->print_on(log.trace_stream());
   }
 }
 
-void Universe::print_heap_after_gc(outputStream* st, bool ignore_extended) {
-  st->print_cr("Heap after GC invocations=%u (full %u):",
-               heap()->total_collections(),
-               heap()->total_full_collections());
-  if (!PrintHeapAtGCExtended || ignore_extended) {
-    heap()->print_on(st);
-  } else {
-    heap()->print_extended_on(st);
+void Universe::print_heap_after_gc() {
+  LogHandle(gc, heap) log;
+  if (log.is_trace()) {
+    log.trace("Heap after GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
+    ResourceMark rm;
+    heap()->print_on(log.trace_stream());
   }
-  st->print_cr("}");
 }
 
-void Universe::verify(VerifyOption option, const char* prefix, bool silent) {
+void Universe::verify(VerifyOption option, const char* prefix) {
   // The use of _verify_in_progress is a temporary work around for
   // 6320749.  Don't bother with a creating a class to set and clear
   // it since it is only used in this method and the control flow is
@@ -1122,36 +1120,35 @@
   HandleMark hm;  // Handles created during verification can be zapped
   _verify_count++;
 
-  if (!silent) gclog_or_tty->print("%s", prefix);
-  if (!silent) gclog_or_tty->print("[Verifying ");
-  if (!silent) gclog_or_tty->print("threads ");
+  FormatBuffer<> title("Verifying %s", prefix);
+  GCTraceTime(Info, gc, verify) tm(title.buffer());
+  log_debug(gc, verify)("Threads");
   Threads::verify();
-  if (!silent) gclog_or_tty->print("heap ");
-  heap()->verify(silent, option);
-  if (!silent) gclog_or_tty->print("syms ");
+  log_debug(gc, verify)("Heap");
+  heap()->verify(option);
+  log_debug(gc, verify)("SymbolTable");
   SymbolTable::verify();
-  if (!silent) gclog_or_tty->print("strs ");
+  log_debug(gc, verify)("StringTable");
   StringTable::verify();
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    if (!silent) gclog_or_tty->print("zone ");
+    log_debug(gc, verify)("CodeCache");
     CodeCache::verify();
   }
-  if (!silent) gclog_or_tty->print("dict ");
+  log_debug(gc, verify)("SystemDictionary");
   SystemDictionary::verify();
 #ifndef PRODUCT
-  if (!silent) gclog_or_tty->print("cldg ");
+  log_debug(gc, verify)("ClassLoaderDataGraph");
   ClassLoaderDataGraph::verify();
 #endif
-  if (!silent) gclog_or_tty->print("metaspace chunks ");
+  log_debug(gc, verify)("MetaspaceAux");
   MetaspaceAux::verify_free_chunks();
-  if (!silent) gclog_or_tty->print("hand ");
+  log_debug(gc, verify)("JNIHandles");
   JNIHandles::verify();
-  if (!silent) gclog_or_tty->print("C-heap ");
+  log_debug(gc, verify)("C-heap");
   os::check_heap();
-  if (!silent) gclog_or_tty->print("code cache ");
+  log_debug(gc, verify)("CodeCache Oops");
   CodeCache::verify_oops();
-  if (!silent) gclog_or_tty->print_cr("]");
 
   _verify_in_progress = false;
 }
--- a/hotspot/src/share/vm/memory/universe.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/memory/universe.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -159,6 +159,9 @@
   static oop          _out_of_memory_error_gc_overhead_limit;
   static oop          _out_of_memory_error_realloc_objects;
 
+  // preallocated cause message for delayed StackOverflowError
+  static oop          _delayed_stack_overflow_error_message;
+
   static Array<int>*       _the_empty_int_array;    // Canonicalized int array
   static Array<u2>*        _the_empty_short_array;  // Canonicalized short array
   static Array<Klass*>*  _the_empty_klass_array;  // Canonicalized klass obj array
@@ -339,6 +342,7 @@
   static oop out_of_memory_error_array_size()         { return gen_out_of_memory_error(_out_of_memory_error_array_size); }
   static oop out_of_memory_error_gc_overhead_limit()  { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit);  }
   static oop out_of_memory_error_realloc_objects()    { return gen_out_of_memory_error(_out_of_memory_error_realloc_objects);  }
+  static oop delayed_stack_overflow_error_message()   { return _delayed_stack_overflow_error_message; }
 
   // Accessors needed for fast allocation
   static Klass** boolArrayKlassObj_addr()           { return &_boolArrayKlassObj;   }
@@ -460,26 +464,19 @@
 
   // Debugging
   static bool verify_in_progress() { return _verify_in_progress; }
-  static void verify(VerifyOption option, const char* prefix, bool silent = VerifySilently);
-  static void verify(const char* prefix, bool silent = VerifySilently) {
-    verify(VerifyOption_Default, prefix, silent);
+  static void verify(VerifyOption option, const char* prefix);
+  static void verify(const char* prefix) {
+    verify(VerifyOption_Default, prefix);
   }
-  static void verify(bool silent = VerifySilently) {
-    verify("", silent);
+  static void verify() {
+    verify("");
   }
 
   static int  verify_count()       { return _verify_count; }
-  // The default behavior is to call print_on() on gclog_or_tty.
-  static void print();
-  // The extended parameter determines which method on the heap will
-  // be called: print_on() (extended == false) or print_extended_on()
-  // (extended == true).
-  static void print_on(outputStream* st, bool extended = false);
+  static void print_on(outputStream* st);
   static void print_heap_at_SIGBREAK();
-  static void print_heap_before_gc() { print_heap_before_gc(gclog_or_tty); }
-  static void print_heap_after_gc()  { print_heap_after_gc(gclog_or_tty); }
-  static void print_heap_before_gc(outputStream* st, bool ignore_extended = false);
-  static void print_heap_after_gc(outputStream* st, bool ignore_extended = false);
+  static void print_heap_before_gc();
+  static void print_heap_after_gc();
 
   // Change the number of dummy objects kept reachable by the full gc dummy
   // array; this should trigger relocation in a sliding compaction collector.
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -2957,7 +2957,7 @@
     oop obj = oopDesc::load_decode_heap_oop(p);
     if (!obj->is_oop_or_null()) {
       tty->print_cr("Failed: " PTR_FORMAT " -> " PTR_FORMAT, p2i(p), p2i(obj));
-      Universe::print();
+      Universe::print_on(tty);
       guarantee(false, "boom");
     }
   }
--- a/hotspot/src/share/vm/oops/instanceRefKlass.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 
 #include "classfile/javaClasses.hpp"
 #include "gc/shared/referenceProcessor.hpp"
+#include "logging/log.hpp"
 #include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/oop.inline.hpp"
@@ -59,12 +60,7 @@
   // Treat discovered as normal oop, if ref is not "active" (next non-NULL)
   if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {
     // i.e. ref is not "active"
-    debug_only(
-      if(TraceReferenceGC && PrintGCDetails) {
-        gclog_or_tty->print_cr("   Process discovered as normal "
-                               PTR_FORMAT, p2i(disc_addr));
-      }
-    )
+    log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(disc_addr));
     Devirtualizer<nv>::do_oop(closure, disc_addr);
   }
   // treat next as normal oop
--- a/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -75,16 +75,17 @@
 
   // Flags
   enum Flags {
-    _jfr_towrite          = 1 << 0,
-    _caller_sensitive     = 1 << 1,
-    _force_inline         = 1 << 2,
-    _dont_inline          = 1 << 3,
-    _hidden               = 1 << 4,
-    _has_injected_profile = 1 << 5,
-    _running_emcp         = 1 << 6,
-    _intrinsic_candidate  = 1 << 7
+    _jfr_towrite           = 1 << 0,
+    _caller_sensitive      = 1 << 1,
+    _force_inline          = 1 << 2,
+    _dont_inline           = 1 << 3,
+    _hidden                = 1 << 4,
+    _has_injected_profile  = 1 << 5,
+    _running_emcp          = 1 << 6,
+    _intrinsic_candidate   = 1 << 7,
+    _reserved_stack_access = 1 << 8
   };
-  mutable u1 _flags;
+  mutable u2 _flags;
 
 #ifndef PRODUCT
   int               _compiled_invocation_count;  // Number of nmethod invocations so far (for perf. debugging)
@@ -835,6 +836,14 @@
     _flags = x ? (_flags | _has_injected_profile) : (_flags & ~_has_injected_profile);
   }
 
+  bool has_reserved_stack_access() {
+    return (_flags & _reserved_stack_access) != 0;
+  }
+
+  void set_has_reserved_stack_access(bool x) {
+    _flags = x ? (_flags | _reserved_stack_access) : (_flags & ~_reserved_stack_access);
+  }
+
   ConstMethod::MethodType method_type() const {
       return _constMethod->method_type();
   }
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -672,7 +672,8 @@
                   _print_inlining_idx(0),
                   _print_inlining_output(NULL),
                   _interpreter_frame_size(0),
-                  _max_node_limit(MaxNodeLimit) {
+                  _max_node_limit(MaxNodeLimit),
+                  _has_reserved_stack_access(target->has_reserved_stack_access()) {
   C = this;
 #ifndef PRODUCT
   if (_printer != NULL) {
--- a/hotspot/src/share/vm/opto/compile.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -364,6 +364,7 @@
   bool                  _has_unsafe_access;     // True if the method _may_ produce faults in unsafe loads or stores.
   bool                  _has_stringbuilder;     // True StringBuffers or StringBuilders are allocated
   bool                  _has_boxed_value;       // True if a boxed object is allocated
+  bool                  _has_reserved_stack_access; // True if the method or an inlined method is annotated with ReservedStackAccess
   int                   _max_vector_size;       // Maximum size of generated vectors
   uint                  _trap_hist[trapHistLength];  // Cumulative traps
   bool                  _trap_can_recompile;    // Have we emitted a recompiling trap?
@@ -637,6 +638,8 @@
   void          set_has_stringbuilder(bool z)   { _has_stringbuilder = z; }
   bool              has_boxed_value() const     { return _has_boxed_value; }
   void          set_has_boxed_value(bool z)     { _has_boxed_value = z; }
+  bool              has_reserved_stack_access() const { return _has_reserved_stack_access; }
+  void          set_has_reserved_stack_access(bool z) { _has_reserved_stack_access = z; }
   int               max_vector_size() const     { return _max_vector_size; }
   void          set_max_vector_size(int s)      { _max_vector_size = s; }
   void          set_trap_count(uint r, uint c)  { assert(r < trapHistLength, "oob");        _trap_hist[r] = c; }
--- a/hotspot/src/share/vm/opto/parse1.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -415,6 +415,10 @@
   _est_switch_depth = 0;
 #endif
 
+  if (parse_method->has_reserved_stack_access()) {
+    C->set_has_reserved_stack_access(true);
+  }
+
   _tf = TypeFunc::make(method());
   _iter.reset_to_method(method());
   _flow = method()->get_flow_analysis();
--- a/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -3917,7 +3917,6 @@
     run_unit_test(QuickSort::test_quick_sort());
     run_unit_test(GuardedMemory::test_guarded_memory());
     run_unit_test(AltHashing::test_alt_hash());
-    run_unit_test(test_loggc_filename());
     run_unit_test(TestNewSize_test());
     run_unit_test(TestOldSize_test());
     run_unit_test(TestKlass_test());
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -29,6 +29,7 @@
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
+#include "logging/logConfiguration.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/instanceKlass.hpp"
@@ -628,7 +629,22 @@
     TraceClassUnloading = value != 0;
     break;
   case JVMTI_VERBOSE_GC:
-    PrintGC = value != 0;
+    {
+      // This is a temporary solution to work around initialization issues.
+      // JDK-8145083 will fix this.
+      Mutex* conf_mutex = LogConfiguration_lock;
+      if (Threads::number_of_threads() == 0) {
+        // We're too early in the initialization to use mutexes
+        LogConfiguration_lock = NULL;
+      }
+      MutexLockerEx ml(LogConfiguration_lock);
+      if (value == 0) {
+        LogConfiguration::parse_log_arguments("stdout", "gc=off", NULL, NULL, NULL);
+      } else {
+        LogConfiguration::parse_log_arguments("stdout", "gc", NULL, NULL, NULL);
+      }
+      LogConfiguration_lock = conf_mutex;
+    }
     break;
   case JVMTI_VERBOSE_JNI:
     PrintJNIResolving = value != 0;
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -159,7 +159,7 @@
 
 WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
   CollectorPolicy * p = Universe::heap()->collector_policy();
-  gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
+  tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
     SIZE_FORMAT " Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT,
     p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
     p->space_alignment(), p->heap_alignment());
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,6 +32,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.hpp"
+#include "logging/log.hpp"
 #include "logging/logConfiguration.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/universe.inline.hpp"
@@ -81,7 +82,6 @@
 int    Arguments::_num_jvm_args                 = 0;
 char*  Arguments::_java_command                 = NULL;
 SystemProperty* Arguments::_system_properties   = NULL;
-const char*  Arguments::_gc_log_filename        = NULL;
 bool   Arguments::_has_profile                  = false;
 size_t Arguments::_conservative_max_heap_alignment = 0;
 size_t Arguments::_min_heap_size                = 0;
@@ -1308,18 +1308,20 @@
     PropertyList_unique_add(&_system_properties, key, value, true);
   } else {
     if (strcmp(key, "sun.java.command") == 0) {
-      if (_java_command != NULL) {
-        os::free(_java_command);
+      char *old_java_command = _java_command;
+      _java_command = os::strdup_check_oom(value, mtInternal);
+      if (old_java_command != NULL) {
+        os::free(old_java_command);
       }
-      _java_command = os::strdup_check_oom(value, mtInternal);
     } else if (strcmp(key, "java.vendor.url.bug") == 0) {
-      if (_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
-        assert(_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
-        os::free((void *)_java_vendor_url_bug);
-      }
+      const char* old_java_vendor_url_bug = _java_vendor_url_bug;
       // save it in _java_vendor_url_bug, so JVM fatal error handler can access
       // its value without going through the property list or making a Java call.
       _java_vendor_url_bug = os::strdup_check_oom(value, mtInternal);
+      if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
+        assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
+        os::free((void *)old_java_vendor_url_bug);
+      }
     }
 
     // Create new property and add at the end of the list
@@ -1600,19 +1602,11 @@
     } else {
       FLAG_SET_ERGO(size_t, MaxNewSize, preferred_max_new_size);
     }
-    if (PrintGCDetails && Verbose) {
-      // Too early to use gclog_or_tty
-      tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
-    }
+    log_trace(gc, heap)("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
 
     // Code along this path potentially sets NewSize and OldSize
-    if (PrintGCDetails && Verbose) {
-      // Too early to use gclog_or_tty
-      tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
-           " initial_heap_size:  " SIZE_FORMAT
-           " max_heap: " SIZE_FORMAT,
-           min_heap_size(), InitialHeapSize, max_heap);
-    }
+    log_trace(gc, heap)("CMS set min_heap_size: " SIZE_FORMAT " initial_heap_size:  " SIZE_FORMAT " max_heap: " SIZE_FORMAT,
+                        min_heap_size(), InitialHeapSize, max_heap);
     size_t min_new = preferred_max_new_size;
     if (FLAG_IS_CMDLINE(NewSize)) {
       min_new = NewSize;
@@ -1623,20 +1617,14 @@
       if (FLAG_IS_DEFAULT(NewSize)) {
         FLAG_SET_ERGO(size_t, NewSize, MAX2(NewSize, min_new));
         FLAG_SET_ERGO(size_t, NewSize, MIN2(preferred_max_new_size, NewSize));
-        if (PrintGCDetails && Verbose) {
-          // Too early to use gclog_or_tty
-          tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
-        }
+        log_trace(gc, heap)("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
       }
       // Unless explicitly requested otherwise, size old gen
       // so it's NewRatio x of NewSize.
       if (FLAG_IS_DEFAULT(OldSize)) {
         if (max_heap > NewSize) {
           FLAG_SET_ERGO(size_t, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
-          if (PrintGCDetails && Verbose) {
-            // Too early to use gclog_or_tty
-            tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
-          }
+          log_trace(gc, heap)("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
         }
       }
     }
@@ -1680,11 +1668,8 @@
     FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false);
   }
 
-  if (PrintGCDetails && Verbose) {
-    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
-      (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
-    tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
-  }
+  log_trace(gc)("MarkStackSize: %uk  MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
+  log_trace(gc)("ConcGCThreads: %u", ConcGCThreads);
 }
 #endif // INCLUDE_ALL_GCS
 
@@ -1731,11 +1716,7 @@
   if (UseAutoGCSelectPolicy &&
       !FLAG_IS_DEFAULT(MaxGCPauseMillis) &&
       (MaxGCPauseMillis <= AutoGCSelectPauseMillis)) {
-    if (PrintGCDetails) {
-      // Cannot use gclog_or_tty yet.
-      tty->print_cr("Automatic selection of the low pause collector"
-       " based on pause goal of %d (ms)", (int) MaxGCPauseMillis);
-    }
+    log_trace(gc)("Automatic selection of the low pause collector based on pause goal of %d (ms)", (int) MaxGCPauseMillis);
     return true;
   }
   return false;
@@ -1954,11 +1935,8 @@
     FLAG_SET_DEFAULT(GCTimeRatio, 12);
   }
 
-  if (PrintGCDetails && Verbose) {
-    tty->print_cr("MarkStackSize: %uk  MarkStackSizeMax: %uk",
-      (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
-    tty->print_cr("ConcGCThreads: %u", ConcGCThreads);
-  }
+  log_trace(gc)("MarkStackSize: %uk  MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
+  log_trace(gc)("ConcGCThreads: %u", ConcGCThreads);
 }
 
 #if !INCLUDE_ALL_GCS
@@ -2070,10 +2048,7 @@
       reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
     }
 
-    if (PrintGCDetails && Verbose) {
-      // Cannot use gclog_or_tty yet.
-      tty->print_cr("  Maximum heap size " SIZE_FORMAT, (size_t) reasonable_max);
-    }
+    log_trace(gc, heap)("  Maximum heap size " SIZE_FORMAT, (size_t) reasonable_max);
     FLAG_SET_ERGO(size_t, MaxHeapSize, (size_t)reasonable_max);
   }
 
@@ -2094,20 +2069,14 @@
 
       reasonable_initial = limit_by_allocatable_memory(reasonable_initial);
 
-      if (PrintGCDetails && Verbose) {
-        // Cannot use gclog_or_tty yet.
-        tty->print_cr("  Initial heap size " SIZE_FORMAT, (size_t)reasonable_initial);
-      }
+      log_trace(gc, heap)("  Initial heap size " SIZE_FORMAT, (size_t)reasonable_initial);
       FLAG_SET_ERGO(size_t, InitialHeapSize, (size_t)reasonable_initial);
     }
     // If the minimum heap size has not been set (via -Xms),
     // synchronize with InitialHeapSize to avoid errors with the default value.
     if (min_heap_size() == 0) {
       set_min_heap_size(MIN2((size_t)reasonable_minimum, InitialHeapSize));
-      if (PrintGCDetails && Verbose) {
-        // Cannot use gclog_or_tty yet.
-        tty->print_cr("  Minimum heap size " SIZE_FORMAT, min_heap_size());
-      }
+      log_trace(gc, heap)("  Minimum heap size " SIZE_FORMAT, min_heap_size());
     }
   }
 }
@@ -2310,77 +2279,8 @@
 //===========================================================================================================
 // Parsing of main arguments
 
-// check if do gclog rotation
-// +UseGCLogFileRotation is a must,
-// no gc log rotation when log file not supplied or
-// NumberOfGCLogFiles is 0
-void check_gclog_consistency() {
-  if (UseGCLogFileRotation) {
-    if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
-      jio_fprintf(defaultStream::output_stream(),
-                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n"
-                  "where num_of_file > 0\n"
-                  "GC log rotation is turned off\n");
-      UseGCLogFileRotation = false;
-    }
-  }
-
-  if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
-    if (FLAG_SET_CMDLINE(size_t, GCLogFileSize, 8*K) == Flag::SUCCESS) {
-      jio_fprintf(defaultStream::output_stream(),
-                "GCLogFileSize changed to minimum 8K\n");
-    }
-  }
-}
-
-// This function is called for -Xloggc:<filename>, it can be used
-// to check if a given file name(or string) conforms to the following
-// specification:
-// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]"
-// %p and %t only allowed once. We only limit usage of filename not path
-bool is_filename_valid(const char *file_name) {
-  const char* p = file_name;
-  char file_sep = os::file_separator()[0];
-  const char* cp;
-  // skip prefix path
-  for (cp = file_name; *cp != '\0'; cp++) {
-    if (*cp == '/' || *cp == file_sep) {
-      p = cp + 1;
-    }
-  }
-
-  int count_p = 0;
-  int count_t = 0;
-  while (*p != '\0') {
-    if ((*p >= '0' && *p <= '9') ||
-        (*p >= 'A' && *p <= 'Z') ||
-        (*p >= 'a' && *p <= 'z') ||
-         *p == '-'               ||
-         *p == '_'               ||
-         *p == '.') {
-       p++;
-       continue;
-    }
-    if (*p == '%') {
-      if(*(p + 1) == 'p') {
-        p += 2;
-        count_p ++;
-        continue;
-      }
-      if (*(p + 1) == 't') {
-        p += 2;
-        count_t ++;
-        continue;
-      }
-    }
-    return false;
-  }
-  return count_p < 2 && count_t < 2;
-}
-
 // Check consistency of GC selection
 bool Arguments::check_gc_consistency() {
-  check_gclog_consistency();
   // Ensure that the user has not selected conflicting sets
   // of collectors.
   uint i = 0;
@@ -2526,6 +2426,12 @@
     warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
   }
 
+#ifndef SUPPORT_RESERVED_STACK_AREA
+  if (StackReservedPages != 0) {
+    FLAG_SET_CMDLINE(intx, StackReservedPages, 0);
+    warning("Reserved Stack Area not supported on this platform");
+  }
+#endif
   return status;
 }
 
@@ -2723,7 +2629,9 @@
           return JNI_EINVAL;
         }
       } else if (!strcmp(tail, ":gc")) {
-        if (FLAG_SET_CMDLINE(bool, PrintGC, true) != Flag::SUCCESS) {
+        // LogConfiguration_lock is not set up yet, but this code is executed by a single thread
+        bool ret = LogConfiguration::parse_log_arguments("stdout", "gc", NULL, NULL, NULL);
+        if (!ret) {
           return JNI_EINVAL;
         }
       } else if (!strcmp(tail, ":jni")) {
@@ -3156,24 +3064,6 @@
     // -Xnoagent
     } else if (match_option(option, "-Xnoagent")) {
       // For compatibility with classic. HotSpot refuses to load the old style agent.dll.
-    } else if (match_option(option, "-Xloggc:", &tail)) {
-      // Redirect GC output to the file. -Xloggc:<filename>
-      // ostream_init_log(), when called will use this filename
-      // to initialize a fileStream.
-      _gc_log_filename = os::strdup_check_oom(tail);
-     if (!is_filename_valid(_gc_log_filename)) {
-       jio_fprintf(defaultStream::output_stream(),
-                  "Invalid file name for use with -Xloggc: Filename can only contain the "
-                  "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n"
-                  "Note %%p or %%t can only be used once\n", _gc_log_filename);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(bool, PrintGC, true) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
     } else if (match_option(option, "-Xlog", &tail)) {
       bool ret = false;
       if (strcmp(tail, ":help") == 0) {
@@ -4178,11 +4068,6 @@
     ScavengeRootsInCode = 1;
   }
 
-  if (PrintGCDetails) {
-    // Turn on -verbose:gc options as well
-    PrintGC = true;
-  }
-
   // Set object alignment values.
   set_object_alignment();
 
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -284,7 +284,6 @@
 
   // Option flags
   static bool   _has_profile;
-  static const char*  _gc_log_filename;
   // Value of the conservative maximum heap alignment needed
   static size_t  _conservative_max_heap_alignment;
 
@@ -543,9 +542,6 @@
   // -Dsun.java.launcher.pid
   static int sun_java_launcher_pid()        { return _sun_java_launcher_pid; }
 
-  // -Xloggc:<file>, if not specified will be NULL
-  static const char* gc_log_filename()      { return _gc_log_filename; }
-
   // -Xprof
   static bool has_profile()                 { return _has_profile; }
 
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1431,7 +1431,7 @@
     // stack bang causes a stack overflow we crash.
     assert(THREAD->is_Java_thread(), "only a java thread can be here");
     JavaThread* thread = (JavaThread*)THREAD;
-    bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+    bool guard_pages_enabled = thread->stack_guards_enabled();
     if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
     assert(guard_pages_enabled, "stack banging in uncommon trap blob may cause crash");
   }
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -985,9 +985,6 @@
   develop(bool, ZapUnusedHeapArea, trueInDebug,                             \
           "Zap unused heap space with 0xBAADBABE")                          \
                                                                             \
-  develop(bool, TraceZapUnusedHeapArea, false,                              \
-          "Trace zapping of unused heap space")                             \
-                                                                            \
   develop(bool, CheckZapUnusedHeapArea, false,                              \
           "Check zapping of unused heap space")                             \
                                                                             \
@@ -997,12 +994,6 @@
   develop(bool, PrintVMMessages, true,                                      \
           "Print VM messages on console")                                   \
                                                                             \
-  product(bool, PrintGCApplicationConcurrentTime, false,                    \
-          "Print the time the application has been running")                \
-                                                                            \
-  product(bool, PrintGCApplicationStoppedTime, false,                       \
-          "Print the time the application has been stopped")                \
-                                                                            \
   diagnostic(bool, VerboseVerification, false,                              \
           "Display detailed verification details")                          \
                                                                             \
@@ -1576,9 +1567,6 @@
           "number of GC threads")                                           \
           range((size_t)os::vm_page_size(), (size_t)max_uintx)              \
                                                                             \
-  product(bool, TraceDynamicGCThreads, false,                               \
-          "Trace the dynamic GC thread usage")                              \
-                                                                            \
   product(uint, ConcGCThreads, 0,                                           \
           "Number of threads concurrent gc will use")                       \
           constraint(ConcGCThreadsConstraintFunc,AfterErgo)                 \
@@ -1629,12 +1617,6 @@
   product(bool, UseParNewGC, false,                                         \
           "Use parallel threads in the new generation")                     \
                                                                             \
-  product(bool, PrintTaskqueue, false,                                      \
-          "Print taskqueue statistics for parallel collectors")             \
-                                                                            \
-  product(bool, PrintTerminationStats, false,                               \
-          "Print termination statistics for parallel collectors")           \
-                                                                            \
   product(uintx, ParallelGCBufferWastePct, 10,                              \
           "Wasted fraction of parallel allocation buffer")                  \
           range(0, 100)                                                     \
@@ -1652,9 +1634,6 @@
   product(bool, ResizePLAB, true,                                           \
           "Dynamically resize (survivor space) promotion LAB's")            \
                                                                             \
-  product(bool, PrintPLAB, false,                                           \
-          "Print (survivor space) promotion LAB's sizing decisions")        \
-                                                                            \
   product(intx, ParGCArrayScanChunk, 50,                                    \
           "Scan a subset of object array and push remainder, if array is "  \
           "bigger than this")                                               \
@@ -1698,9 +1677,6 @@
   product(bool, ResizeOldPLAB, true,                                        \
           "Dynamically resize (old gen) promotion LAB's")                   \
                                                                             \
-  product(bool, PrintOldPLAB, false,                                        \
-          "Print (old gen) promotion LAB's sizing decisions")               \
-                                                                            \
   product(size_t, CMSOldPLABMax, 1024,                                      \
           "Maximum size of CMS gen promotion LAB caches per worker "        \
           "per block size")                                                 \
@@ -1899,10 +1875,6 @@
           "Always record eden chunks used for the parallel initial mark "   \
           "or remark of eden")                                              \
                                                                             \
-  product(bool, CMSPrintEdenSurvivorChunks, false,                          \
-          "Print the eden and the survivor chunks used for the parallel "   \
-          "initial mark or remark of the eden/survivor spaces")             \
-                                                                            \
   product(bool, CMSConcurrentMTEnabled, true,                               \
           "Whether multi-threaded concurrent work enabled "                 \
           "(effective only if ParNewGC)")                                   \
@@ -1971,9 +1943,6 @@
   product(bool, CMSScavengeBeforeRemark, false,                             \
           "Attempt scavenge before the CMS remark step")                    \
                                                                             \
-  develop(bool, CMSTraceSweeper, false,                                     \
-          "Trace some actions of the CMS sweeper")                          \
-                                                                            \
   product(uintx, CMSWorkQueueDrainThreshold, 10,                            \
           "Don't drain below this size per parallel worker/thief")          \
           range(1, max_juint)                                               \
@@ -1995,17 +1964,15 @@
           "between yields")                                                 \
           range(1, max_uintx)                                               \
                                                                             \
-  product(bool, CMSDumpAtPromotionFailure, false,                           \
-          "Dump useful information about the state of the CMS old "         \
-          "generation upon a promotion failure")                            \
-                                                                            \
   product(bool, CMSPrintChunksInDump, false,                                \
-          "In a dump enabled by CMSDumpAtPromotionFailure, include "        \
-          "more detailed information about the free chunks")                \
+          "If logging for the \"gc\" and \"promotion\" tags is enabled on"  \
+          "trace level include more detailed information about the"         \
+          "free chunks")                \
                                                                             \
   product(bool, CMSPrintObjectsInDump, false,                               \
-          "In a dump enabled by CMSDumpAtPromotionFailure, include "        \
-          "more detailed information about the allocated objects")          \
+          "If logging for the \"gc\" and \"promotion\" tags is enabled on"  \
+          "trace level include more detailed information about the"         \
+          "allocated objects")                                              \
                                                                             \
   diagnostic(bool, FLSVerifyAllHeapReferences, false,                       \
           "Verify that all references across the FLS boundary "             \
@@ -2027,9 +1994,6 @@
           "Maintain _unallocated_block in BlockOffsetArray "                \
           "(currently applicable only to CMS collector)")                   \
                                                                             \
-  develop(bool, TraceCMSState, false,                                       \
-          "Trace the state of the CMS collection")                          \
-                                                                            \
   product(intx, RefDiscoveryPolicy, 0,                                      \
           "Select type of reference discovery policy: "                     \
           "reference-based(0) or referent-based(1)")                        \
@@ -2097,10 +2061,6 @@
   notproduct(bool, GCALotAtAllSafepoints, false,                            \
           "Enforce ScavengeALot/GCALot at all potential safepoints")        \
                                                                             \
-  product(bool, PrintPromotionFailure, false,                               \
-          "Print additional diagnostic information following "              \
-          "promotion failure")                                              \
-                                                                            \
   notproduct(bool, PromotionFailureALot, false,                             \
           "Use promotion failure handling on every youngest generation "    \
           "collection")                                                     \
@@ -2140,12 +2100,6 @@
   develop(bool, TraceMetadataChunkAllocation, false,                        \
           "Trace chunk metadata allocations")                               \
                                                                             \
-  product(bool, TraceMetadataHumongousAllocation, false,                    \
-          "Trace humongous metadata allocations")                           \
-                                                                            \
-  develop(bool, TraceMetavirtualspaceAllocation, false,                     \
-          "Trace virtual space metadata allocations")                       \
-                                                                            \
   notproduct(bool, ExecuteInternalVMTests, false,                           \
           "Enable execution of internal VM tests")                          \
                                                                             \
@@ -2163,12 +2117,8 @@
   product(bool, FastTLABRefill, true,                                       \
           "Use fast TLAB refill code")                                      \
                                                                             \
-  product(bool, PrintTLAB, false,                                           \
-          "Print various TLAB related information")                         \
-                                                                            \
   product(bool, TLABStats, true,                                            \
-          "Provide more detailed and expensive TLAB statistics "            \
-          "(with PrintTLAB)")                                               \
+          "Provide more detailed and expensive TLAB statistics.")           \
                                                                             \
   product_pd(bool, NeverActAsServerClassMachine,                            \
           "Never act like a server-class machine")                          \
@@ -2228,9 +2178,6 @@
   product(bool, UseAdaptiveGCBoundary, false,                               \
           "Allow young-old boundary to move")                               \
                                                                             \
-  develop(bool, TraceAdaptiveGCBoundary, false,                             \
-          "Trace young-old boundary moves")                                 \
-                                                                            \
   develop(intx, PSAdaptiveSizePolicyResizeVirtualSpaceAlot, -1,             \
           "Resize the virtual spaces of the young or old generations")      \
           range(-1, 1)                                                      \
@@ -2366,9 +2313,6 @@
           "Number of consecutive collections before gc time limit fires")   \
           range(1, max_uintx)                                               \
                                                                             \
-  product(bool, PrintAdaptiveSizePolicy, false,                             \
-          "Print information about AdaptiveSizePolicy")                     \
-                                                                            \
   product(intx, PrefetchCopyIntervalInBytes, -1,                            \
           "How far ahead to prefetch destination area (<= 0 means off)")    \
           range(-1, max_jint)                                               \
@@ -2381,9 +2325,6 @@
           "How many fields ahead to prefetch in oop scan (<= 0 means off)") \
           range(-1, max_jint)                                               \
                                                                             \
-  diagnostic(bool, VerifySilently, false,                                   \
-          "Do not print the verification progress")                         \
-                                                                            \
   diagnostic(bool, VerifyDuringStartup, false,                              \
           "Verify memory system before executing any Java code "            \
           "during VM initialization")                                       \
@@ -2449,37 +2390,11 @@
           "will sleep while yielding before giving up and resuming GC")     \
           range(0, max_juint)                                               \
                                                                             \
-  /* gc tracing */                                                          \
-  manageable(bool, PrintGC, false,                                          \
-          "Print message at garbage collection")                            \
-                                                                            \
-  manageable(bool, PrintGCDetails, false,                                   \
-          "Print more details at garbage collection")                       \
-                                                                            \
-  manageable(bool, PrintGCDateStamps, false,                                \
-          "Print date stamps at garbage collection")                        \
-                                                                            \
-  manageable(bool, PrintGCTimeStamps, false,                                \
-          "Print timestamps at garbage collection")                         \
-                                                                            \
-  manageable(bool, PrintGCID, true,                                         \
-          "Print an identifier for each garbage collection")                \
-                                                                            \
-  product(bool, PrintGCTaskTimeStamps, false,                               \
-          "Print timestamps for individual gc worker thread tasks")         \
-                                                                            \
   develop(intx, ConcGCYieldTimeout, 0,                                      \
           "If non-zero, assert that GC threads yield within this "          \
           "number of milliseconds")                                         \
           range(0, max_intx)                                                \
                                                                             \
-  product(bool, PrintReferenceGC, false,                                    \
-          "Print times spent handling reference objects during GC "         \
-          "(enabled only when PrintGCDetails)")                             \
-                                                                            \
-  develop(bool, TraceReferenceGC, false,                                    \
-          "Trace handling of soft/weak/final/phantom references")           \
-                                                                            \
   develop(bool, TraceFinalizerRegistration, false,                          \
           "Trace registration of final references")                         \
                                                                             \
@@ -2519,37 +2434,15 @@
   product(bool, TraceOldGenTime, false,                                     \
           "Trace accumulated time for old collection")                      \
                                                                             \
-  product(bool, PrintTenuringDistribution, false,                           \
-          "Print tenuring age information")                                 \
-                                                                            \
-  product_rw(bool, PrintHeapAtGC, false,                                    \
-          "Print heap layout before and after each GC")                     \
-                                                                            \
-  product_rw(bool, PrintHeapAtGCExtended, false,                            \
-          "Print extended information about the layout of the heap "        \
-          "when -XX:+PrintHeapAtGC is set")                                 \
-                                                                            \
   product(bool, PrintHeapAtSIGBREAK, true,                                  \
           "Print heap layout in response to SIGBREAK")                      \
                                                                             \
-  manageable(bool, PrintClassHistogramBeforeFullGC, false,                  \
-          "Print a class histogram before any major stop-world GC")         \
-                                                                            \
-  manageable(bool, PrintClassHistogramAfterFullGC, false,                   \
-          "Print a class histogram after any major stop-world GC")          \
-                                                                            \
   manageable(bool, PrintClassHistogram, false,                              \
           "Print a histogram of class instances")                           \
                                                                             \
   develop(bool, TraceWorkGang, false,                                       \
           "Trace activities of work gangs")                                 \
                                                                             \
-  develop(bool, TraceBlockOffsetTable, false,                               \
-          "Print BlockOffsetTable maps")                                    \
-                                                                            \
-  develop(bool, TraceCardTableModRefBS, false,                              \
-          "Print CardTableModRefBS maps")                                   \
-                                                                            \
   develop(bool, TraceGCTaskManager, false,                                  \
           "Trace actions of the GC task manager")                           \
                                                                             \
@@ -2559,50 +2452,20 @@
   diagnostic(bool, TraceGCTaskThread, false,                                \
           "Trace actions of the GC task threads")                           \
                                                                             \
-  product(bool, PrintParallelOldGCPhaseTimes, false,                        \
-          "Print the time taken by each phase in ParallelOldGC "            \
-          "(PrintGCDetails must also be enabled)")                          \
-                                                                            \
   develop(bool, TraceParallelOldGCMarkingPhase, false,                      \
           "Trace marking phase in ParallelOldGC")                           \
                                                                             \
-  develop(bool, TraceParallelOldGCSummaryPhase, false,                      \
-          "Trace summary phase in ParallelOldGC")                           \
-                                                                            \
-  develop(bool, TraceParallelOldGCCompactionPhase, false,                   \
-          "Trace compaction phase in ParallelOldGC")                        \
-                                                                            \
   develop(bool, TraceParallelOldGCDensePrefix, false,                       \
           "Trace dense prefix computation for ParallelOldGC")               \
                                                                             \
   develop(bool, IgnoreLibthreadGPFault, false,                              \
           "Suppress workaround for libthread GP fault")                     \
                                                                             \
-  product(bool, PrintJNIGCStalls, false,                                    \
-          "Print diagnostic message when GC is stalled "                    \
-          "by JNI critical section")                                        \
-                                                                            \
   experimental(double, ObjectCountCutOffPercent, 0.5,                       \
           "The percentage of the used heap that the instances of a class "  \
           "must occupy for the class to generate a trace event")            \
           range(0.0, 100.0)                                                 \
                                                                             \
-  /* GC log rotation setting */                                             \
-                                                                            \
-  product(bool, UseGCLogFileRotation, false,                                \
-          "Rotate gclog files (for long running applications). It requires "\
-          "-Xloggc:<filename>")                                             \
-                                                                            \
-  product(uintx, NumberOfGCLogFiles, 0,                                     \
-          "Number of gclog files in rotation "                              \
-          "(default: 0, no rotation)")                                      \
-          range(0, max_uintx)                                               \
-                                                                            \
-  product(size_t, GCLogFileSize, 8*K,                                       \
-          "GC log file size, requires UseGCLogFileRotation. "               \
-          "Set to 0 to only trigger rotation via jcmd")                     \
-          range(0, max_uintx)                                               \
-                                                                            \
   /* JVMTI heap profiling */                                                \
                                                                             \
   diagnostic(bool, TraceJVMTIObjectTagging, false,                          \
@@ -3539,21 +3402,6 @@
           "space parameters)")                                              \
           range(1, max_uintx)                                               \
                                                                             \
-  product(intx, PrintCMSStatistics, 0,                                      \
-          "Statistics for CMS")                                             \
-          range(0, 2)                                                       \
-                                                                            \
-  product(bool, PrintCMSInitiationStatistics, false,                        \
-          "Statistics for initiating a CMS collection")                     \
-                                                                            \
-  product(intx, PrintFLSStatistics, 0,                                      \
-          "Statistics for CMS' FreeListSpace")                              \
-          range(0, 2)                                                       \
-                                                                            \
-  product(intx, PrintFLSCensus, 0,                                          \
-          "Census for CMS' FreeListSpace")                                  \
-          range(0, 1)                                                       \
-                                                                            \
   develop(uintx, GCExpandToAllocateDelayMillis, 0,                          \
           "Delay between expansion and allocation (in milliseconds)")       \
                                                                             \
@@ -3590,6 +3438,13 @@
           "Number of red zone (unrecoverable overflows) pages")             \
           range(MIN_STACK_RED_PAGES, (DEFAULT_STACK_RED_PAGES+2))           \
                                                                             \
+  product_pd(intx, StackReservedPages,                                      \
+          "Number of reserved zone (reserved to annotated methods) pages")  \
+          range(MIN_STACK_RESERVED_PAGES, (DEFAULT_STACK_RESERVED_PAGES+10))\
+                                                                            \
+  product(bool, RestrictReservedStack, true,                                \
+          "Restrict @ReservedStackAccess to trusted classes")               \
+                                                                            \
   /* greater stack shadow pages can't generate instruction to bang stack */ \
   product_pd(intx, StackShadowPages,                                        \
           "Number of shadow zone (for overflow checking) pages "            \
@@ -4248,9 +4103,6 @@
   product(bool, UseStringDeduplication, false,                              \
           "Use string deduplication")                                       \
                                                                             \
-  product(bool, PrintStringDeduplicationStatistics, false,                  \
-          "Print string deduplication statistics")                          \
-                                                                            \
   product(uintx, StringDeduplicationAgeThreshold, 3,                        \
           "A string must reach this age (or be promoted to an old region) " \
           "to be considered for deduplication")                             \
@@ -4265,9 +4117,6 @@
   diagnostic(bool, WhiteBoxAPI, false,                                      \
           "Enable internal testing APIs")                                   \
                                                                             \
-  product(bool, PrintGCCause, true,                                         \
-          "Include GC cause in GC logging")                                 \
-                                                                            \
   experimental(intx, SurvivorAlignmentInBytes, 0,                           \
            "Default survivor space alignment in bytes")                     \
            constraint(SurvivorAlignmentInBytesConstraintFunc,AfterErgo)     \
--- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -101,15 +101,13 @@
       // Compute new interval
       if (FullGCALotInterval > 1) {
         _fullgc_alot_counter = 1+(long)((double)FullGCALotInterval*os::random()/(max_jint+1.0));
-        if (PrintGCDetails && Verbose) {
-          tty->print_cr("Full gc no: %u\tInterval: %ld", invocations, _fullgc_alot_counter);
-        }
+        log_trace(gc)("Full gc no: %u\tInterval: %ld", invocations, _fullgc_alot_counter);
       } else {
         _fullgc_alot_counter = 1;
       }
       // Print progress message
       if (invocations % 100 == 0) {
-        if (PrintGCDetails && Verbose) tty->print_cr("Full gc no: %u", invocations);
+        log_trace(gc)("Full gc no: %u", invocations);
       }
     } else {
       if (ScavengeALot) _scavenge_alot_counter--;
@@ -121,15 +119,13 @@
         // Compute new interval
         if (ScavengeALotInterval > 1) {
           _scavenge_alot_counter = 1+(long)((double)ScavengeALotInterval*os::random()/(max_jint+1.0));
-          if (PrintGCDetails && Verbose) {
-            tty->print_cr("Scavenge no: %u\tInterval: %ld", invocations, _scavenge_alot_counter);
-          }
+          log_trace(gc)("Scavenge no: %u\tInterval: %ld", invocations, _scavenge_alot_counter);
         } else {
           _scavenge_alot_counter = 1;
         }
         // Print progress message
         if (invocations % 1000 == 0) {
-          if (PrintGCDetails && Verbose) tty->print_cr("Scavenge no: %u", invocations);
+          log_trace(gc)("Scavenge no: %u", invocations);
         }
       }
     }
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -35,6 +35,7 @@
 #include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 #endif
+#include "logging/log.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.hpp"
 #include "oops/constantPool.hpp"
@@ -453,13 +454,15 @@
   Universe::heap()->stop();
 
   // Print GC/heap related information.
-  if (PrintGCDetails) {
-    Universe::print();
-    AdaptiveSizePolicyOutput(0);
-    if (Verbose) {
-      ClassLoaderDataGraph::dump_on(gclog_or_tty);
+  LogHandle(gc, heap, exit) log;
+  if (log.is_info()) {
+    ResourceMark rm;
+    Universe::print_on(log.info_stream());
+    if (log.is_trace()) {
+      ClassLoaderDataGraph::dump_on(log.trace_stream());
     }
   }
+  AdaptiveSizePolicyOutput::print();
 
   if (PrintBytecodeHistogram) {
     BytecodeHistogram::print();
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -371,9 +371,9 @@
   // Find receiver
   Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
 
-  // When we reenter Java, we need to reenable the yellow zone which
+  // When we reenter Java, we need to reenable the reserved/yellow zone which
   // might already be disabled when we are in VM.
-  if (thread->stack_yellow_zone_disabled()) {
+  if (!thread->stack_guards_enabled()) {
     thread->reguard_stack();
   }
 
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/jniHandles.hpp"
@@ -393,9 +394,7 @@
           f->do_oop(root);
         } else {
           // The weakly referenced object is not alive, clear the reference by storing NULL
-          if (TraceReferenceGC) {
-            tty->print_cr("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
-          }
+          log_develop_trace(gc, ref)("Clearing JNI weak reference (" INTPTR_FORMAT ")", p2i(root));
           *root = NULL;
         }
       }
--- a/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -262,7 +262,7 @@
         VMThread::execute(&op1);
         Universe::print_heap_at_SIGBREAK();
         if (PrintClassHistogram) {
-          VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */);
+          VM_GC_HeapInspection op1(tty, true /* force full GC before heap inspection */);
           VMThread::execute(&op1);
         }
         if (JvmtiExport::should_post_data_dump()) {
@@ -315,6 +315,10 @@
   // We need to initialize large page support here because ergonomics takes some
   // decisions depending on large page support and the calculated large page size.
   large_page_init();
+
+  // VM version initialization identifies some characteristics of the
+  // the platform that are used during ergonomic decisions.
+  VM_Version::init_before_ergo();
 }
 
 void os::signal_init() {
@@ -1382,8 +1386,9 @@
   // respectively.
   const int framesize_in_bytes =
     Interpreter::size_top_interpreter_activation(method()) * wordSize;
-  int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages)
-                      * vm_page_size()) + framesize_in_bytes;
+  int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages
+                      + StackReservedPages) * vm_page_size())
+                      + framesize_in_bytes;
   // The very lower end of the stack
   address stack_limit = thread->stack_base() - thread->stack_size();
   return (sp > (stack_limit + reserved_area));
--- a/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -471,8 +471,9 @@
 
   static int pd_self_suspend_thread(Thread* thread);
 
-  static ExtendedPC fetch_frame_from_context(void* ucVoid, intptr_t** sp, intptr_t** fp);
-  static frame      fetch_frame_from_context(void* ucVoid);
+  static ExtendedPC fetch_frame_from_context(const void* ucVoid, intptr_t** sp, intptr_t** fp);
+  static frame      fetch_frame_from_context(const void* ucVoid);
+  static frame      fetch_frame_from_ucontext(Thread* thread, void* ucVoid);
 
   static ExtendedPC get_thread_pc(Thread *thread);
   static void breakpoint();
@@ -498,7 +499,7 @@
 
   // Terminate with an error.  Default is to generate a core file on platforms
   // that support such things.  This calls shutdown() and then aborts.
-  static void abort(bool dump_core, void *siginfo, void *context);
+  static void abort(bool dump_core, void *siginfo, const void *context);
   static void abort(bool dump_core = true);
 
   // Die immediately, no exit hook, no abort hook, no cleanup.
@@ -603,8 +604,8 @@
   static void print_memory_info(outputStream* st);
   static void print_dll_info(outputStream* st);
   static void print_environment_variables(outputStream* st, const char** env_list);
-  static void print_context(outputStream* st, void* context);
-  static void print_register_info(outputStream* st, void* context);
+  static void print_context(outputStream* st, const void* context);
+  static void print_register_info(outputStream* st, const void* context);
   static void print_siginfo(outputStream* st, void* siginfo);
   static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
   static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
@@ -847,7 +848,7 @@
  public:
 #ifndef PLATFORM_PRINT_NATIVE_STACK
   // No platform-specific code for printing the native stack.
-  static bool platform_print_native_stack(outputStream* st, void* context,
+  static bool platform_print_native_stack(outputStream* st, const void* context,
                                           char *buf, int buf_size) {
     return false;
   }
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -515,11 +515,6 @@
     StringTable::rehash_table();
   }
 
-  // rotate log files?
-  if (UseGCLogFileRotation) {
-    gclog_or_tty->rotate_log(false);
-  }
-
   {
     // CMS delays purging the CLDG until the beginning of the next safepoint and to
     // make sure concurrent sweep is done
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -57,6 +57,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
+#include "trace/tracing.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
@@ -254,8 +255,10 @@
        ((ybits.i & float_sign_mask) == float_infinity) ) {
     return x;
   }
+  return ((jfloat)fmod_winx64((double)x, (double)y));
+#else
+  return ((jfloat)fmod((double)x,(double)y));
 #endif
-  return ((jfloat)fmod((double)x,(double)y));
 JRT_END
 
 
@@ -269,8 +272,10 @@
        ((ybits.l & double_sign_mask) == double_infinity) ) {
     return x;
   }
+  return ((jdouble)fmod_winx64((double)x, (double)y));
+#else
+  return ((jdouble)fmod((double)x,(double)y));
 #endif
-  return ((jdouble)fmod((double)x,(double)y));
 JRT_END
 
 #ifdef __SOFTFP__
@@ -483,8 +488,11 @@
       // unguarded. Reguard the stack otherwise if we return to the
       // deopt blob and the stack bang causes a stack overflow we
       // crash.
-      bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
+      bool guard_pages_enabled = thread->stack_guards_enabled();
       if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
+      if (thread->reserved_stack_activation() != thread->stack_base()) {
+        thread->set_reserved_stack_activation(thread->stack_base());
+      }
       assert(guard_pages_enabled, "stack banging in deopt blob may cause crash");
       return SharedRuntime::deopt_blob()->unpack_with_exception();
     } else {
@@ -757,10 +765,23 @@
 JRT_END
 
 JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
+  throw_StackOverflowError_common(thread, false);
+JRT_END
+
+JRT_ENTRY(void, SharedRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
+  throw_StackOverflowError_common(thread, true);
+JRT_END
+
+void SharedRuntime::throw_StackOverflowError_common(JavaThread* thread, bool delayed) {
   // We avoid using the normal exception construction in this case because
   // it performs an upcall to Java, and we're already out of stack space.
+  Thread* THREAD = thread;
   Klass* k = SystemDictionary::StackOverflowError_klass();
   oop exception_oop = InstanceKlass::cast(k)->allocate_instance(CHECK);
+  if (delayed) {
+    java_lang_Throwable::set_message(exception_oop,
+                                     Universe::delayed_stack_overflow_error_message());
+  }
   Handle exception (thread, exception_oop);
   if (StackTraceInThrowable) {
     java_lang_Throwable::fill_in_stack_trace(exception);
@@ -768,7 +789,7 @@
   // Increment counter for hs_err file reporting
   Atomic::inc(&Exceptions::_stack_overflow_errors);
   throw_and_post_jvmti_exception(thread, exception);
-JRT_END
+}
 
 #if INCLUDE_JVMCI
 address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
@@ -2930,3 +2951,68 @@
 }
 
 #endif /* PRODUCT */
+
+JRT_LEAF(void, SharedRuntime::enable_stack_reserved_zone(JavaThread* thread))
+  assert(thread->is_Java_thread(), "Only Java threads have a stack reserved zone");
+  thread->enable_stack_reserved_zone();
+  thread->set_reserved_stack_activation(thread->stack_base());
+JRT_END
+
+frame SharedRuntime::look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr) {
+  frame activation;
+  int decode_offset = 0;
+  nmethod* nm = NULL;
+  frame prv_fr = fr;
+  int count = 1;
+
+  assert(fr.is_java_frame(), "Must start on Java frame");
+
+  while (!fr.is_first_frame()) {
+    Method* method = NULL;
+    // Compiled java method case.
+    if (decode_offset != 0) {
+      DebugInfoReadStream stream(nm, decode_offset);
+      decode_offset = stream.read_int();
+      method = (Method*)nm->metadata_at(stream.read_int());
+    } else {
+      if (fr.is_first_java_frame()) break;
+      address pc = fr.pc();
+      prv_fr = fr;
+      if (fr.is_interpreted_frame()) {
+        method = fr.interpreter_frame_method();
+        fr = fr.java_sender();
+      } else {
+        CodeBlob* cb = fr.cb();
+        fr = fr.java_sender();
+        if (cb == NULL || !cb->is_nmethod()) {
+          continue;
+        }
+        nm = (nmethod*)cb;
+        if (nm->method()->is_native()) {
+          method = nm->method();
+        } else {
+          PcDesc* pd = nm->pc_desc_at(pc);
+          assert(pd != NULL, "PcDesc must not be NULL");
+          decode_offset = pd->scope_decode_offset();
+          // if decode_offset is not equal to 0, it will execute the
+          // "compiled java method case" at the beginning of the loop.
+          continue;
+        }
+      }
+    }
+    if (method->has_reserved_stack_access()) {
+      ResourceMark rm(thread);
+      activation = prv_fr;
+      warning("Potentially dangerous stack overflow in "
+              "ReservedStackAccess annotated method %s [%d]",
+              method->name_and_sig_as_C_string(), count++);
+      EventReservedStackActivation event;
+      if (event.should_commit()) {
+        event.set_method(method);
+        event.commit();
+      }
+    }
+  }
+  return activation;
+}
+
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -100,6 +100,12 @@
   static jfloat  frem(jfloat  x, jfloat  y);
   static jdouble drem(jdouble x, jdouble y);
 
+
+#ifdef _WIN64
+  // Workaround for fmod issue in the Windows x64 CRT
+  static double fmod_winx64(double x, double y);
+#endif
+
 #ifdef __SOFTFP__
   static jfloat  fadd(jfloat x, jfloat y);
   static jfloat  fsub(jfloat x, jfloat y);
@@ -195,6 +201,8 @@
   static void    throw_NullPointerException(JavaThread* thread);
   static void    throw_NullPointerException_at_call(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
+  static void    throw_delayed_StackOverflowError(JavaThread* thread);
+  static void    throw_StackOverflowError_common(JavaThread* thread, bool delayed);
   static address continuation_for_implicit_exception(JavaThread* thread,
                                                      address faulting_pc,
                                                      ImplicitExceptionKind exception_kind);
@@ -202,6 +210,9 @@
   static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason);
 #endif
 
+  static void enable_stack_reserved_zone(JavaThread* thread);
+  static frame look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr);
+
   // Shared stub locations
   static address get_poll_stub(address pc);
 
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -54,6 +54,7 @@
 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
 address StubRoutines::_throw_StackOverflowError_entry           = NULL;
+address StubRoutines::_throw_delayed_StackOverflowError_entry   = NULL;
 address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
 jint    StubRoutines::_verify_oop_count                         = 0;
 address StubRoutines::_verify_oop_subroutine_entry              = NULL;
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -111,6 +111,7 @@
   static address _throw_IncompatibleClassChangeError_entry;
   static address _throw_NullPointerException_at_call_entry;
   static address _throw_StackOverflowError_entry;
+  static address _throw_delayed_StackOverflowError_entry;
   static address _handler_for_unsafe_access_entry;
 
   static address _atomic_xchg_entry;
@@ -275,6 +276,7 @@
   static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
   static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
   static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }
+  static address throw_delayed_StackOverflowError_entry()  { return _throw_delayed_StackOverflowError_entry; }
 
   // Exceptions during unsafe access - should throw Java exception rather
   // than crash.
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -307,6 +307,7 @@
   set_stack_size(os::current_stack_size());
   if (is_Java_thread()) {
     ((JavaThread*) this)->set_stack_overflow_limit();
+    ((JavaThread*) this)->set_reserved_stack_activation(stack_base());
   }
   // CR 7190089: on Solaris, primordial thread's stack is adjusted
   // in initialize_thread(). Without the adjustment, stack size is
@@ -908,7 +909,7 @@
 
 
 bool Thread::is_in_usable_stack(address adr) const {
-  size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
+  size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
   size_t usable_stack_size = _stack_size - stack_guard_size;
 
   return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
@@ -1460,6 +1461,7 @@
     _jvmci_counters = NULL;
   }
 #endif // INCLUDE_JVMCI
+  _reserved_stack_activation = NULL;  // stack base not known yet
   (void)const_cast<oop&>(_exception_oop = oop(NULL));
   _exception_pc  = 0;
   _exception_handler_pc = 0;
@@ -1532,7 +1534,8 @@
 }
 
 bool JavaThread::reguard_stack(address cur_sp) {
-  if (_stack_guard_state != stack_guard_yellow_disabled) {
+  if (_stack_guard_state != stack_guard_yellow_disabled
+      && _stack_guard_state != stack_guard_reserved_disabled) {
     return true; // Stack already guarded or guard pages not needed.
   }
 
@@ -1549,8 +1552,15 @@
   // some exception code in c1, c2 or the interpreter isn't unwinding
   // when it should.
   guarantee(cur_sp > stack_yellow_zone_base(), "not enough space to reguard - increase StackShadowPages");
-
-  enable_stack_yellow_zone();
+  if (_stack_guard_state == stack_guard_yellow_disabled) {
+    enable_stack_yellow_zone();
+    if (reserved_stack_activation() != stack_base()) {
+      set_reserved_stack_activation(stack_base());
+    }
+  } else if (_stack_guard_state == stack_guard_reserved_disabled) {
+    set_reserved_stack_activation(stack_base());
+    enable_stack_reserved_zone();
+  }
   return true;
 }
 
@@ -2473,7 +2483,7 @@
 void JavaThread::create_stack_guard_pages() {
   if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return;
   address low_addr = stack_base() - stack_size();
-  size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
+  size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
 
   int allocate = os::allocate_stack_guard_pages();
   // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
@@ -2497,7 +2507,7 @@
   assert(Thread::current() == this, "from different thread");
   if (_stack_guard_state == stack_guard_unused) return;
   address low_addr = stack_base() - stack_size();
-  size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
+  size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
 
   if (os::allocate_stack_guard_pages()) {
     if (os::remove_stack_guard_pages((char *) low_addr, len)) {
@@ -2515,6 +2525,44 @@
   }
 }
 
+void JavaThread::enable_stack_reserved_zone() {
+  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
+  assert(_stack_guard_state != stack_guard_enabled, "already enabled");
+
+  // The base notation is from the stack's point of view, growing downward.
+  // We need to adjust it to work correctly with guard_memory()
+  address base = stack_reserved_zone_base() - stack_reserved_zone_size();
+
+  guarantee(base < stack_base(),"Error calculating stack reserved zone");
+  guarantee(base < os::current_stack_pointer(),"Error calculating stack reserved zone");
+
+  if (os::guard_memory((char *) base, stack_reserved_zone_size())) {
+    _stack_guard_state = stack_guard_enabled;
+  } else {
+    warning("Attempt to guard stack reserved zone failed.");
+  }
+  enable_register_stack_guard();
+}
+
+void JavaThread::disable_stack_reserved_zone() {
+  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
+  assert(_stack_guard_state != stack_guard_reserved_disabled, "already disabled");
+
+  // Simply return if called for a thread that does not use guard pages.
+  if (_stack_guard_state == stack_guard_unused) return;
+
+  // The base notation is from the stack's point of view, growing downward.
+  // We need to adjust it to work correctly with guard_memory()
+  address base = stack_reserved_zone_base() - stack_reserved_zone_size();
+
+  if (os::unguard_memory((char *)base, stack_reserved_zone_size())) {
+    _stack_guard_state = stack_guard_reserved_disabled;
+  } else {
+    warning("Attempt to unguard stack reserved zone failed.");
+  }
+  disable_register_stack_guard();
+}
+
 void JavaThread::enable_stack_yellow_zone() {
   assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
   assert(_stack_guard_state != stack_guard_enabled, "already enabled");
--- a/hotspot/src/share/vm/runtime/thread.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -909,6 +909,7 @@
   // State of the stack guard pages for this thread.
   enum StackGuardState {
     stack_guard_unused,         // not needed
+    stack_guard_reserved_disabled,
     stack_guard_yellow_disabled,// disabled (temporarily) after stack overflow
     stack_guard_enabled         // enabled
   };
@@ -957,6 +958,7 @@
   // Precompute the limit of the stack as used in stack overflow checks.
   // We load it from here to simplify the stack overflow check in assembly.
   address          _stack_overflow_limit;
+  address          _reserved_stack_activation;
 
   // Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is
   // used to temp. parsing values into and out of the runtime system during exception handling for compiled
@@ -1343,18 +1345,25 @@
 
   // Stack overflow support
   inline size_t stack_available(address cur_sp);
+  address stack_reserved_zone_base() {
+    return stack_yellow_zone_base(); }
+  size_t stack_reserved_zone_size() {
+    return StackReservedPages * os::vm_page_size(); }
   address stack_yellow_zone_base() {
     return (address)(stack_base() -
                      (stack_size() -
                      (stack_red_zone_size() + stack_yellow_zone_size())));
   }
   size_t  stack_yellow_zone_size() {
-    return StackYellowPages * os::vm_page_size();
+    return StackYellowPages * os::vm_page_size() + stack_reserved_zone_size();
   }
   address stack_red_zone_base() {
     return (address)(stack_base() - (stack_size() - stack_red_zone_size()));
   }
   size_t stack_red_zone_size() { return StackRedPages * os::vm_page_size(); }
+  bool in_stack_reserved_zone(address a) {
+    return (a <= stack_reserved_zone_base()) && (a >= (address)((intptr_t)stack_reserved_zone_base() - stack_reserved_zone_size()));
+  }
   bool in_stack_yellow_zone(address a) {
     return (a <= stack_yellow_zone_base()) && (a >= stack_red_zone_base());
   }
@@ -1366,6 +1375,8 @@
   void create_stack_guard_pages();
   void remove_stack_guard_pages();
 
+  void enable_stack_reserved_zone();
+  void disable_stack_reserved_zone();
   void enable_stack_yellow_zone();
   void disable_stack_yellow_zone();
   void enable_stack_red_zone();
@@ -1373,7 +1384,16 @@
 
   inline bool stack_guard_zone_unused();
   inline bool stack_yellow_zone_disabled();
-  inline bool stack_yellow_zone_enabled();
+  inline bool stack_reserved_zone_disabled();
+  inline bool stack_guards_enabled();
+
+  address reserved_stack_activation() const { return _reserved_stack_activation; }
+  void      set_reserved_stack_activation(address addr) {
+    assert(_reserved_stack_activation == stack_base()
+            || _reserved_stack_activation == NULL
+            || addr == stack_base(), "Must not be set twice");
+    _reserved_stack_activation = addr;
+  }
 
   // Attempt to reguard the stack after a stack overflow may have occurred.
   // Returns true if (a) guard pages are not needed on this thread, (b) the
@@ -1390,6 +1410,7 @@
   void set_stack_overflow_limit() {
     _stack_overflow_limit = _stack_base - _stack_size +
                             ((StackShadowPages +
+                              StackReservedPages +
                               StackYellowPages +
                               StackRedPages) * os::vm_page_size());
   }
@@ -1439,6 +1460,7 @@
   static ByteSize stack_overflow_limit_offset()  { return byte_offset_of(JavaThread, _stack_overflow_limit); }
   static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
   static ByteSize stack_guard_state_offset()     { return byte_offset_of(JavaThread, _stack_guard_state); }
+  static ByteSize reserved_stack_activation_offset() { return byte_offset_of(JavaThread, _reserved_stack_activation); }
   static ByteSize suspend_flags_offset()         { return byte_offset_of(JavaThread, _suspend_flags); }
 
   static ByteSize do_not_unlock_if_synchronized_offset() { return byte_offset_of(JavaThread, _do_not_unlock_if_synchronized); }
--- a/hotspot/src/share/vm/runtime/thread.inline.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.inline.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,10 @@
   return _stack_guard_state == stack_guard_yellow_disabled;
 }
 
+inline bool JavaThread::stack_reserved_zone_disabled() {
+  return _stack_guard_state == stack_guard_reserved_disabled;
+}
+
 inline size_t JavaThread::stack_available(address cur_sp) {
   // This code assumes java stacks grow down
   address low_addr; // Limit on the address for deepest stack depth
@@ -141,7 +145,7 @@
   return cur_sp > low_addr ? cur_sp - low_addr : 0;
 }
 
-inline bool JavaThread::stack_yellow_zone_enabled() {
+inline bool JavaThread::stack_guards_enabled() {
 #ifdef ASSERT
   if (os::uses_stack_guard_pages()) {
     assert(_stack_guard_state != stack_guard_unused, "guard pages must be in use");
--- a/hotspot/src/share/vm/runtime/timer.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/timer.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -120,7 +120,6 @@
 
   if (_active) {
     _accum = NULL;
-    tty->stamp(PrintGCTimeStamps);
     tty->print("[%s", title);
     tty->flush();
     _t.start();
@@ -135,7 +134,6 @@
   _verbose = verbose;
   if (_active) {
     if (_verbose) {
-      tty->stamp(PrintGCTimeStamps);
       tty->print("[%s", title);
       tty->flush();
     }
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -396,7 +396,7 @@
   nonstatic_field(Method,                      _access_flags,                                 AccessFlags)                           \
   nonstatic_field(Method,                      _vtable_index,                                 int)                                   \
   nonstatic_field(Method,                      _intrinsic_id,                                 u2)                                    \
-  nonstatic_field(Method,                      _flags,                                        u1)                                    \
+  nonstatic_field(Method,                      _flags,                                        u2)                                    \
   nonproduct_nonstatic_field(Method,           _compiled_invocation_count,                    int)                                   \
   volatile_nonstatic_field(Method,             _code,                                         nmethod*)                              \
   nonstatic_field(Method,                      _i2i_entry,                                    address)                               \
--- a/hotspot/src/share/vm/runtime/vmThread.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -285,7 +285,7 @@
     os::check_heap();
     // Silent verification so as not to pollute normal output,
     // unless we really asked for it.
-    Universe::verify(!(PrintGCDetails || Verbose) || VerifySilently);
+    Universe::verify();
   }
 
   CompileBroker::set_should_block();
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -189,7 +189,7 @@
 
 void VM_Verify::doit() {
   Universe::heap()->prepare_for_verify();
-  Universe::verify(_silent);
+  Universe::verify();
 }
 
 bool VM_PrintThreads::doit_prologue() {
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -311,10 +311,7 @@
 };
 
 class VM_Verify: public VM_Operation {
- private:
-  bool _silent;
  public:
-  VM_Verify(bool silent = VerifySilently) : _silent(silent) {}
   VMOp_Type type() const { return VMOp_Verify; }
   void doit();
 };
@@ -418,17 +415,6 @@
   void doit();
 };
 
-
-class VM_RotateGCLog: public VM_Operation {
- private:
-  outputStream* _out;
-
- public:
-  VM_RotateGCLog(outputStream* st) : _out(st) {}
-  VMOp_Type type() const { return VMOp_RotateGCLog; }
-  void doit() { gclog_or_tty->rotate_log(true, _out); }
-};
-
 class VM_PrintCompileQueue: public VM_Operation {
  private:
   outputStream* _out;
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -170,14 +170,19 @@
 #ifndef CPU
 #ifdef ZERO
 #define CPU      ZERO_LIBARCH
+#elif defined(PPC64)
+#if defined(VM_LITTLE_ENDIAN)
+#define CPU      "ppc64le"
+#else
+#define CPU      "ppc64"
+#endif
 #else
 #define CPU      IA32_ONLY("x86")                \
                  IA64_ONLY("ia64")               \
                  AMD64_ONLY("amd64")             \
-                 PPC64_ONLY("ppc64")             \
                  AARCH64_ONLY("aarch64")         \
                  SPARC_ONLY("sparc")
-#endif // ZERO
+#endif //
 #endif
 
 const char *Abstract_VM_Version::vm_platform_string() {
--- a/hotspot/src/share/vm/runtime/vm_version.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_version.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -56,6 +56,12 @@
                                                   unsigned int dem,
                                                   unsigned int switch_pt);
  public:
+  // Called as part of the runtime services initialization which is
+  // called from the management module initialization (via init_globals())
+  // after argument parsing and attaching of the main thread has
+  // occurred.  Examines a variety of the hardware capabilities of
+  // the platform to determine which features can be used to execute the
+  // program.
   static void initialize();
 
   // This allows for early initialization of VM_Version information
@@ -65,6 +71,11 @@
   // need to specialize this define VM_Version::early_initialize().
   static void early_initialize() { }
 
+  // Called to initialize VM variables needing initialization
+  // after command line parsing. Platforms that need to specialize
+  // this should define VM_Version::init_before_ergo().
+  static void init_before_ergo() {}
+
   // Name
   static const char* vm_name();
   // Vendor
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -73,7 +73,6 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIDataDumpDCmd>(full_export, true, false));
 #endif // INCLUDE_JVMTI
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
-  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));
@@ -826,15 +825,6 @@
   output()->cr();
 }
 
-void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) {
-  if (UseGCLogFileRotation) {
-    VM_RotateGCLog rotateop(output());
-    VMThread::execute(&rotateop);
-  } else {
-    output()->print_cr("Target VM does not support GC log file rotation.");
-  }
-}
-
 void CompileQueueDCmd::execute(DCmdSource source, TRAPS) {
   VM_PrintCompileQueue printCompileQueueOp(output());
   VMThread::execute(&printCompileQueueOp);
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -549,23 +549,6 @@
 
 };
 
-class RotateGCLogDCmd : public DCmd {
-public:
-  RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
-  static const char* name() { return "GC.rotate_log"; }
-  static const char* description() {
-    return "Force the GC log file to be rotated.";
-  }
-  static const char* impact() { return "Low"; }
-  virtual void execute(DCmdSource source, TRAPS);
-  static int num_arguments() { return 0; }
-  static const JavaPermission permission() {
-    JavaPermission p = {"java.lang.management.ManagementPermission",
-                        "control", NULL};
-    return p;
-  }
-};
-
 class CompileQueueDCmd : public DCmd {
 public:
   CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
--- a/hotspot/src/share/vm/services/memoryService.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/services/memoryService.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -32,6 +32,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/generation.hpp"
 #include "gc/shared/generationSpec.hpp"
+#include "logging/logConfiguration.hpp"
 #include "memory/heap.hpp"
 #include "memory/memRegion.hpp"
 #include "oops/oop.inline.hpp"
@@ -517,8 +518,12 @@
 bool MemoryService::set_verbose(bool verbose) {
   MutexLocker m(Management_lock);
   // verbose will be set to the previous value
-  Flag::Error error = CommandLineFlags::boolAtPut("PrintGC", &verbose, Flag::MANAGEMENT);
-  assert(error==Flag::SUCCESS, "Setting PrintGC flag failed with error %s", Flag::flag_error_str(error));
+  MutexLocker ml(LogConfiguration_lock);
+  if (verbose) {
+    LogConfiguration::parse_log_arguments("stdout", "gc", NULL, NULL, NULL);
+  } else {
+    LogConfiguration::parse_log_arguments("stdout", "gc=off", NULL, NULL, NULL);
+  }
   ClassLoadingService::reset_trace_class_unloading();
 
   return verbose;
--- a/hotspot/src/share/vm/services/memoryService.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/services/memoryService.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -27,6 +27,7 @@
 
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/generation.hpp"
+#include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
 #include "services/memoryUsage.hpp"
@@ -164,7 +165,7 @@
 
   static void oops_do(OopClosure* f);
 
-  static bool get_verbose() { return PrintGC; }
+  static bool get_verbose() { return log_is_enabled(Info, gc); }
   static bool set_verbose(bool verbose);
 
   // Create an instance of java/lang/management/MemoryUsage
--- a/hotspot/src/share/vm/services/runtimeService.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/services/runtimeService.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
+#include "logging/log.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/attachListener.hpp"
 #include "services/management.hpp"
@@ -87,11 +88,8 @@
   HS_PRIVATE_SAFEPOINT_BEGIN();
 
   // Print the time interval in which the app was executing
-  if (PrintGCApplicationConcurrentTime && _app_timer.is_updated()) {
-    gclog_or_tty->date_stamp(PrintGCDateStamps);
-    gclog_or_tty->stamp(PrintGCTimeStamps);
-    gclog_or_tty->print_cr("Application time: %3.7f seconds",
-                                last_application_time_sec());
+  if (_app_timer.is_updated()) {
+    log_info(safepoint)("Application time: %3.7f seconds", last_application_time_sec());
   }
 
   // update the time stamp to begin recording safepoint time
@@ -109,7 +107,7 @@
   if (UsePerfData) {
     _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
   }
-  if (PrintGCApplicationStoppedTime) {
+  if (log_is_enabled(Info, safepoint)) {
     _last_safepoint_sync_time_sec = last_safepoint_time_sec();
   }
 }
@@ -119,15 +117,8 @@
 
   // Print the time interval for which the app was stopped
   // during the current safepoint operation.
-  if (PrintGCApplicationStoppedTime) {
-    gclog_or_tty->date_stamp(PrintGCDateStamps);
-    gclog_or_tty->stamp(PrintGCTimeStamps);
-    gclog_or_tty->print_cr("Total time for which application threads "
-                           "were stopped: %3.7f seconds, "
-                           "Stopping threads took: %3.7f seconds",
-                           last_safepoint_time_sec(),
-                           _last_safepoint_sync_time_sec);
-  }
+  log_info(safepoint)("Total time for which application threads were stopped: %3.7f seconds, Stopping threads took: %3.7f seconds",
+                      last_safepoint_time_sec(), _last_safepoint_sync_time_sec);
 
   // update the time stamp to begin recording app time
   _app_timer.update();
--- a/hotspot/src/share/vm/trace/trace.xml	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/trace/trace.xml	Tue Jan 05 13:08:02 2016 -0800
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 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
@@ -109,6 +109,11 @@
       <value type="ADDRESS" field="address" label="Monitor Address" description="Address of object waited on" relation="JAVA_MONITOR_ADDRESS"/>
     </event>
 
+    <event id="ReservedStackActivation" path="java/reserved_stack_activation" label="Reserved Stack Activation" description="Activation of Reserved Stack Area caused by stack overflow with ReservedStackAccess annotated method in call stack"
+            has_thread="true" has_stacktrace="true" is_instant="true">
+        <value type="METHOD" field="method" label="Java Method"/>
+    </event>
+
     <event id="ClassLoad" path="vm/class/load" label="Class Load"
             has_thread="true" has_stacktrace="true" is_instant="false">
       <value type="CLASS" field="loadedClass" label="Loaded Class"/>
--- a/hotspot/src/share/vm/utilities/debug.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -505,7 +505,7 @@
 
 extern "C" void universe() {
   Command c("universe");
-  Universe::print();
+  Universe::print_on(tty);
 }
 
 
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -234,7 +234,7 @@
 
 // Printing/Debugging Support
 
-void AbsSeq::dump() { dump_on(gclog_or_tty); }
+void AbsSeq::dump() { dump_on(tty); }
 
 void AbsSeq::dump_on(outputStream* s) {
   s->print_cr("\t _num = %d, _sum = %7.3f, _sum_of_squares = %7.3f",
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Tue Jan 05 13:08:02 2016 -0800
@@ -239,14 +239,6 @@
   return;
 }
 
-void outputStream::gclog_stamp() {
-  date_stamp(PrintGCDateStamps);
-  stamp(PrintGCTimeStamps);
-  if (PrintGCID) {
-    print("#%u: ", GCId::current());
-  }
-}
-
 outputStream& outputStream::indent() {
   while (_position < _indentation) sp();
   return *this;
@@ -366,7 +358,6 @@
 
 xmlStream*   xtty;
 outputStream* tty;
-outputStream* gclog_or_tty;
 CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
 extern Mutex* tty_lock;
 
@@ -482,7 +473,7 @@
   return buf;
 }
 
-// log_name comes from -XX:LogFile=log_name, -Xloggc:log_name or
+// log_name comes from -XX:LogFile=log_name or
 // -XX:DumpLoadedClassList=<file_name>
 // in log_name, %p => pid1234 and
 //              %t => YYYY-MM-DD_HH-MM-SS
@@ -493,95 +484,6 @@
                                 timestr);
 }
 
-#ifndef PRODUCT
-void test_loggc_filename() {
-  int pid;
-  char  tms[32];
-  char  i_result[JVM_MAXPATHLEN];
-  const char* o_result;
-  get_datetime_string(tms, sizeof(tms));
-  pid = os::current_process_id();
-
-  // test.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "test.log", tms);
-  o_result = make_log_name_internal("test.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  // test-%t-%p.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%s-pid%u.log", tms, pid);
-  o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  // test-%t%p.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%spid%u.log", tms, pid);
-  o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  // %p%t.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u%s.log", pid, tms);
-  o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  // %p-test.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u-test.log", pid);
-  o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  // %t.log
-  jio_snprintf(i_result, JVM_MAXPATHLEN, "%s.log", tms);
-  o_result = make_log_name_internal("%t.log", NULL, pid, tms);
-  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
-  FREE_C_HEAP_ARRAY(char, o_result);
-
-  {
-    // longest filename
-    char longest_name[JVM_MAXPATHLEN];
-    memset(longest_name, 'a', sizeof(longest_name));
-    longest_name[JVM_MAXPATHLEN - 1] = '\0';
-    o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(strcmp(longest_name, o_result) == 0, "longest name does not match. expected '%s' but got '%s'", longest_name, o_result);
-    FREE_C_HEAP_ARRAY(char, o_result);
-  }
-
-  {
-    // too long file name
-    char too_long_name[JVM_MAXPATHLEN + 100];
-    int too_long_length = sizeof(too_long_name);
-    memset(too_long_name, 'a', too_long_length);
-    too_long_name[too_long_length - 1] = '\0';
-    o_result = make_log_name_internal((const char*)&too_long_name, NULL, pid, tms);
-    assert(o_result == NULL, "Too long file name should return NULL, but got '%s'", o_result);
-  }
-
-  {
-    // too long with timestamp
-    char longest_name[JVM_MAXPATHLEN];
-    memset(longest_name, 'a', JVM_MAXPATHLEN);
-    longest_name[JVM_MAXPATHLEN - 3] = '%';
-    longest_name[JVM_MAXPATHLEN - 2] = 't';
-    longest_name[JVM_MAXPATHLEN - 1] = '\0';
-    o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(o_result == NULL, "Too long file name after timestamp expansion should return NULL, but got '%s'", o_result);
-  }
-
-  {
-    // too long with pid
-    char longest_name[JVM_MAXPATHLEN];
-    memset(longest_name, 'a', JVM_MAXPATHLEN);
-    longest_name[JVM_MAXPATHLEN - 3] = '%';
-    longest_name[JVM_MAXPATHLEN - 2] = 'p';
-    longest_name[JVM_MAXPATHLEN - 1] = '\0';
-    o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
-    assert(o_result == NULL, "Too long file name after pid expansion should return NULL, but got '%s'", o_result);
-  }
-}
-#endif // PRODUCT
-
 fileStream::fileStream(const char* file_name) {
   _file = fopen(file_name, "w");
   if (_file != NULL) {
@@ -660,202 +562,6 @@
   update_position(s, len);
 }
 
-// dump vm version, os version, platform info, build id,
-// memory usage and command line flags into header
-void gcLogFileStream::dump_loggc_header() {
-  if (is_open()) {
-    print_cr("%s", Abstract_VM_Version::internal_vm_info_string());
-    os::print_memory_info(this);
-    print("CommandLine flags: ");
-    CommandLineFlags::printSetFlags(this);
-  }
-}
-
-gcLogFileStream::~gcLogFileStream() {
-  if (_file != NULL) {
-    if (_need_close) fclose(_file);
-    _file = NULL;
-  }
-  if (_file_name != NULL) {
-    FREE_C_HEAP_ARRAY(char, _file_name);
-    _file_name = NULL;
-  }
-}
-
-gcLogFileStream::gcLogFileStream(const char* file_name) {
-  _cur_file_num = 0;
-  _bytes_written = 0L;
-  _file_name = make_log_name(file_name, NULL);
-
-  if (_file_name == NULL) {
-    warning("Cannot open file %s: file name is too long.\n", file_name);
-    _need_close = false;
-    UseGCLogFileRotation = false;
-    return;
-  }
-
-  // gc log file rotation
-  if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
-    char tempbuf[JVM_MAXPATHLEN];
-    jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
-    _file = fopen(tempbuf, "w");
-  } else {
-    _file = fopen(_file_name, "w");
-  }
-  if (_file != NULL) {
-    _need_close = true;
-    dump_loggc_header();
-  } else {
-    warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
-    _need_close = false;
-  }
-}
-
-void gcLogFileStream::write(const char* s, size_t len) {
-  if (_file != NULL) {
-    size_t count = fwrite(s, 1, len, _file);
-    _bytes_written += count;
-  }
-  update_position(s, len);
-}
-
-// rotate_log must be called from VMThread at safepoint. In case need change parameters
-// for gc log rotation from thread other than VMThread, a sub type of VM_Operation
-// should be created and be submitted to VMThread's operation queue. DO NOT call this
-// function directly. Currently, it is safe to rotate log at safepoint through VMThread.
-// That is, no mutator threads and concurrent GC threads run parallel with VMThread to
-// write to gc log file at safepoint. If in future, changes made for mutator threads or
-// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
-// must be synchronized.
-void gcLogFileStream::rotate_log(bool force, outputStream* out) {
-  char time_msg[O_BUFLEN];
-  char time_str[EXTRACHARLEN];
-  char current_file_name[JVM_MAXPATHLEN];
-  char renamed_file_name[JVM_MAXPATHLEN];
-
-  if (!should_rotate(force)) {
-    return;
-  }
-
-#ifdef ASSERT
-  Thread *thread = Thread::current_or_null();
-  assert(thread == NULL ||
-         (thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()),
-         "Must be VMThread at safepoint");
-#endif
-  if (NumberOfGCLogFiles == 1) {
-    // rotate in same file
-    rewind();
-    _bytes_written = 0L;
-    jio_snprintf(time_msg, sizeof(time_msg), "File  %s rotated at %s\n",
-                 _file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
-    write(time_msg, strlen(time_msg));
-
-    if (out != NULL) {
-      out->print("%s", time_msg);
-    }
-
-    dump_loggc_header();
-    return;
-  }
-
-#if defined(_WINDOWS)
-#ifndef F_OK
-#define F_OK 0
-#endif
-#endif // _WINDOWS
-
-  // rotate file in names extended_filename.0, extended_filename.1, ...,
-  // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will
-  // have a form of extended_filename.<i>.current where i is the current rotation
-  // file number. After it reaches max file size, the file will be saved and renamed
-  // with .current removed from its tail.
-  if (_file != NULL) {
-    jio_snprintf(renamed_file_name, JVM_MAXPATHLEN, "%s.%d",
-                 _file_name, _cur_file_num);
-    int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN,
-                              "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
-    if (result >= JVM_MAXPATHLEN) {
-      warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
-      return;
-    }
-
-    const char* msg = force ? "GC log rotation request has been received."
-                            : "GC log file has reached the maximum size.";
-    jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n",
-                     os::local_time_string((char *)time_str, sizeof(time_str)),
-                                                         msg, renamed_file_name);
-    write(time_msg, strlen(time_msg));
-
-    if (out != NULL) {
-      out->print("%s", time_msg);
-    }
-
-    fclose(_file);
-    _file = NULL;
-
-    bool can_rename = true;
-    if (access(current_file_name, F_OK) != 0) {
-      // current file does not exist?
-      warning("No source file exists, cannot rename\n");
-      can_rename = false;
-    }
-    if (can_rename) {
-      if (access(renamed_file_name, F_OK) == 0) {
-        if (remove(renamed_file_name) != 0) {
-          warning("Could not delete existing file %s\n", renamed_file_name);
-          can_rename = false;
-        }
-      } else {
-        // file does not exist, ok to rename
-      }
-    }
-    if (can_rename && rename(current_file_name, renamed_file_name) != 0) {
-      warning("Could not rename %s to %s\n", _file_name, renamed_file_name);
-    }
-  }
-
-  _cur_file_num++;
-  if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
-  int result = jio_snprintf(current_file_name,  JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX,
-               _file_name, _cur_file_num);
-  if (result >= JVM_MAXPATHLEN) {
-    warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
-    return;
-  }
-
-  _file = fopen(current_file_name, "w");
-
-  if (_file != NULL) {
-    _bytes_written = 0L;
-    _need_close = true;
-    // reuse current_file_name for time_msg
-    jio_snprintf(current_file_name, JVM_MAXPATHLEN,
-                 "%s.%d", _file_name, _cur_file_num);
-    jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
-                 os::local_time_string((char *)time_str, sizeof(time_str)), current_file_name);
-    write(time_msg, strlen(time_msg));
-
-    if (out != NULL) {
-      out->print("%s", time_msg);
-    }
-
-    dump_loggc_header();
-    // remove the existing file
-    if (access(current_file_name, F_OK) == 0) {
-      if (remove(current_file_name) != 0) {
-        warning("Could not delete existing file %s\n", current_file_name);
-      }
-    }
-  } else {
-    warning("failed to open rotation log file %s due to %s\n"
-            "Turned off GC log file rotation\n",
-                  _file_name, strerror(errno));
-    _need_close = false;
-    FLAG_SET_DEFAULT(UseGCLogFileRotation, false);
-  }
-}
-
 defaultStream* defaultStream::instance = NULL;
 int defaultStream::_output_fd = 1;
 int defaultStream::_error_fd  = 2;
@@ -1194,21 +900,8 @@
 }
 
 void ostream_init_log() {
-  // For -Xloggc:<file> option - called in runtime/thread.cpp
   // Note : this must be called AFTER ostream_init()
 
-  gclog_or_tty = tty; // default to tty
-  if (Arguments::gc_log_filename() != NULL) {
-    fileStream * gclog  = new(ResourceObj::C_HEAP, mtInternal)
-                             gcLogFileStream(Arguments::gc_log_filename());
-    if (gclog->is_open()) {
-      // now we update the time stamp of the GC log to be synced up
-      // with tty.
-      gclog->time_stamp().update_to(tty->time_stamp().ticks());
-    }
-    gclog_or_tty = gclog;
-  }
-
 #if INCLUDE_CDS
   // For -XX:DumpLoadedClassList=<file> option
   if (DumpLoadedClassList != NULL) {
@@ -1236,9 +929,6 @@
     delete classlist_file;
   }
 #endif
-  if (gclog_or_tty != tty) {
-      delete gclog_or_tty;
-  }
   {
       // we temporaly disable PrintMallocFree here
       // as otherwise it'll lead to using of almost deleted
@@ -1254,14 +944,12 @@
   }
   tty = NULL;
   xtty = NULL;
-  gclog_or_tty = NULL;
   defaultStream::instance = NULL;
 }
 
 // ostream_abort() is called by os::abort() when VM is about to die.
 void ostream_abort() {
-  // Here we can't delete gclog_or_tty and tty, just flush their output
-  if (gclog_or_tty) gclog_or_tty->flush();
+  // Here we can't delete tty, just flush its output
   if (tty) tty->flush();
 
   if (defaultStream::instance != NULL) {
--- a/hotspot/src/share/vm/utilities/ostream.hpp	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/src/share/vm/utilities/ostream.hpp	Tue Jan 05 13:08:02 2016 -0800
@@ -108,7 +108,6 @@
    void date_stamp(bool guard) {
      date_stamp(guard, "", ": ");
    }
-   void gclog_stamp();
 
    // portable printing of 64 bit integers
    void print_jlong(jlong value);
@@ -127,7 +126,6 @@
 // standard output
 // ANSI C++ name collision
 extern outputStream* tty;           // tty output
-extern outputStream* gclog_or_tty;  // stream for gc log if -Xloggc:<f>, or tty
 
 class streamIndentor : public StackObj {
  private:
@@ -247,30 +245,6 @@
   }
 };
 
-class gcLogFileStream : public fileStream {
- protected:
-  const char*  _file_name;
-  jlong  _bytes_written;
-  uintx  _cur_file_num;             // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
- public:
-  gcLogFileStream(const char* file_name);
-  ~gcLogFileStream();
-  virtual void write(const char* c, size_t len);
-  virtual void rotate_log(bool force, outputStream* out = NULL);
-  void dump_loggc_header();
-
-  /* If "force" sets true, force log file rotation from outside JVM */
-  bool should_rotate(bool force) {
-    return force ||
-             ((GCLogFileSize != 0) && (_bytes_written >= (jlong)GCLogFileSize));
-  }
-};
-
-#ifndef PRODUCT
-// unit test for checking -Xloggc:<filename> parsing result
-void test_loggc_filename();
-#endif
-
 void ostream_init();
 void ostream_init_log();
 void ostream_exit();
--- a/hotspot/test/TEST.groups	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/TEST.groups	Tue Jan 05 13:08:02 2016 -0800
@@ -145,7 +145,6 @@
   gc/g1/TestShrinkAuxiliaryData25.java \
   gc/g1/TestShrinkAuxiliaryData30.java \
   gc/survivorAlignment \
-  gc/TestGCLogRotationViaJcmd.java \
   runtime/InternalApi/ThreadCpuTimesDeadlock.java \
   runtime/NMT/JcmdSummaryDiff.java \
   runtime/RedefineTests/RedefineAnnotations.java
--- a/hotspot/test/compiler/floatingpoint/ModNaN.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/compiler/floatingpoint/ModNaN.java	Tue Jan 05 13:08:02 2016 -0800
@@ -25,7 +25,6 @@
  * @test
  * @bug 8015396
  * @summary double a%b returns NaN for some (a,b) (|a| < inf, |b|>0) (on Core i7 980X)
- * @ignore 8015396
  * @run main ModNaN
  */
 public class ModNaN {
--- a/hotspot/test/gc/6941923/Test6941923.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * @test Test6941923.java
- * @bug 6941923
- * @summary test flags for gc log rotation
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management
- * @run main/othervm/timeout=600 Test6941923
- *
- */
-import jdk.test.lib.*;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-class GCLoggingGenerator {
-
-    public static void main(String[] args) throws Exception {
-
-        long sizeOfLog = Long.parseLong(args[0]);
-        long lines = sizeOfLog / 80;
-        // full.GC generates ad least 1-line which is not shorter then 80 chars
-        // for some GC 2 shorter lines are generated
-        for (long i = 0; i < lines; i++) {
-            System.gc();
-        }
-    }
-}
-
-public class Test6941923 {
-
-    static final File currentDirectory = new File(".");
-    static final String logFileName = "test.log";
-    static final int logFileSizeK = 16;
-    static FilenameFilter logFilter = new FilenameFilter() {
-        @Override
-        public boolean accept(File dir, String name) {
-            return name.startsWith(logFileName);
-        }
-    };
-
-    public static void cleanLogs() {
-        for (File log : currentDirectory.listFiles(logFilter)) {
-            if (!log.delete()) {
-                throw new Error("Unable to delete " + log.getAbsolutePath());
-            }
-        }
-    }
-
-    public static void runTest(int numberOfFiles) throws Exception {
-
-        ArrayList<String> args = new ArrayList();
-        String[] logOpts = new String[]{
-            "-cp", System.getProperty("java.class.path"),
-            "-Xloggc:" + logFileName,
-            "-XX:-DisableExplicitGC", // to sure that System.gc() works
-            "-XX:+PrintGC", "-XX:+PrintGCDetails", "-XX:+UseGCLogFileRotation",
-            "-XX:NumberOfGCLogFiles=" + numberOfFiles,
-            "-XX:GCLogFileSize=" + logFileSizeK + "K", "-Xmx128M"};
-        // System.getProperty("test.java.opts") is '' if no options is set
-        // need to skip such empty
-        String[] externalVMopts = System.getProperty("test.java.opts").length() == 0
-                ? new String[0]
-                : System.getProperty("test.java.opts").split(" ");
-        args.addAll(Arrays.asList(externalVMopts));
-        args.addAll(Arrays.asList(logOpts));
-        args.add(GCLoggingGenerator.class.getName());
-        args.add(String.valueOf(numberOfFiles * logFileSizeK * 1024));
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
-        pb.redirectErrorStream(true);
-        pb.redirectOutput(new File(GCLoggingGenerator.class.getName() + ".log"));
-        Process process = pb.start();
-        int result = process.waitFor();
-        if (result != 0) {
-            throw new Error("Unexpected exit code = " + result);
-        }
-        File[] logs = currentDirectory.listFiles(logFilter);
-        int smallFilesNumber = 0;
-        for (File log : logs) {
-            if (log.length() < logFileSizeK * 1024) {
-                smallFilesNumber++;
-            }
-        }
-        if (logs.length != numberOfFiles) {
-            throw new Error("There are only " + logs.length + " logs instead " + numberOfFiles);
-        }
-        if (smallFilesNumber > 1) {
-            throw new Error("There should maximum one log with size < " + logFileSizeK + "K");
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        cleanLogs();
-        runTest(1);
-        cleanLogs();
-        runTest(3);
-        cleanLogs();
-    }
-}
--- a/hotspot/test/gc/7072527/TestFullGCCount.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/7072527/TestFullGCCount.java	Tue Jan 05 13:08:02 2016 -0800
@@ -26,7 +26,7 @@
  * @bug 7072527
  * @summary CMS: JMM GC counters overcount in some cases
  * @modules java.management
- * @run main/othervm -XX:+PrintGC TestFullGCCount
+ * @run main/othervm -Xlog:gc TestFullGCCount
  */
 import java.util.*;
 import java.lang.management.*;
--- a/hotspot/test/gc/TestDisableExplicitGC.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/TestDisableExplicitGC.java	Tue Jan 05 13:08:02 2016 -0800
@@ -26,9 +26,9 @@
  * @requires vm.opt.DisableExplicitGC == null
  * @summary Verify GC behavior with DisableExplicitGC flag.
  * @library /testlibrary
- * @run main/othervm                             -XX:+PrintGCDetails TestDisableExplicitGC
- * @run main/othervm/fail -XX:+DisableExplicitGC -XX:+PrintGCDetails TestDisableExplicitGC
- * @run main/othervm      -XX:-DisableExplicitGC -XX:+PrintGCDetails TestDisableExplicitGC
+ * @run main/othervm                             -Xlog:gc=debug TestDisableExplicitGC
+ * @run main/othervm/fail -XX:+DisableExplicitGC -Xlog:gc=debug TestDisableExplicitGC
+ * @run main/othervm      -XX:-DisableExplicitGC -Xlog:gc=debug TestDisableExplicitGC
  */
 import java.lang.management.GarbageCollectorMXBean;
 import java.util.List;
--- a/hotspot/test/gc/TestGCLogRotationViaJcmd.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2014, 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.
- */
-
-/*
- * @test TestGCLogRotationViaJcmd.java
- * @bug 7090324
- * @summary test for gc log rotation via jcmd
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management
- * @run main/othervm -Xloggc:test.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 TestGCLogRotationViaJcmd
- *
- */
-import jdk.test.lib.*;
-import java.io.File;
-import java.io.FilenameFilter;
-
-public class TestGCLogRotationViaJcmd {
-
-    static final File currentDirectory = new File(".");
-    static final String LOG_FILE_NAME = "test.log";
-    static final int NUM_LOGS = 3;
-
-    static FilenameFilter logFilter = new FilenameFilter() {
-        @Override
-        public boolean accept(File dir, String name) {
-            return name.startsWith(LOG_FILE_NAME);
-        }
-    };
-
-    public static void main(String[] args) throws Exception {
-        // Grab the pid from the current java process
-        String pid = Integer.toString(ProcessTools.getProcessId());
-
-        // Create a JDKToolLauncher
-        JDKToolLauncher jcmd = JDKToolLauncher.create("jcmd")
-                                              .addToolArg(pid)
-                                              .addToolArg("GC.rotate_log");
-
-        for (int times = 1; times < NUM_LOGS; times++) {
-            // Run jcmd <pid> GC.rotate_log
-            ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand());
-
-            // Make sure we didn't crash
-            OutputAnalyzer output = new OutputAnalyzer(pb.start());
-            output.shouldHaveExitValue(0);
-        }
-
-        // GC log check
-        File[] logs = currentDirectory.listFiles(logFilter);
-        if (logs.length != NUM_LOGS) {
-            throw new Error("There are only " + logs.length
-                                              + " logs instead " + NUM_LOGS);
-        }
-
-    }
-
-}
-
--- a/hotspot/test/gc/TestVerifyDuringStartup.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/TestVerifyDuringStartup.java	Tue Jan 05 13:08:02 2016 -0800
@@ -48,6 +48,7 @@
     Collections.addAll(vmOpts, new String[] {"-XX:-UseTLAB",
                                              "-XX:+UnlockDiagnosticVMOptions",
                                              "-XX:+VerifyDuringStartup",
+                                             "-Xlog:gc+verify=debug",
                                              "-version"});
 
     System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java"));
@@ -62,7 +63,7 @@
 
     System.out.println("Output:\n" + output.getOutput());
 
-    output.shouldContain("[Verifying");
+    output.shouldContain("Verifying");
     output.shouldHaveExitValue(0);
   }
 }
--- a/hotspot/test/gc/TestVerifySilently.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/TestVerifySilently.java	Tue Jan 05 13:08:02 2016 -0800
@@ -60,7 +60,7 @@
                                              "-XX:+VerifyDuringStartup",
                                              "-XX:+VerifyBeforeGC",
                                              "-XX:+VerifyAfterGC",
-                                             "-XX:" + (verifySilently ? "+":"-") + "VerifySilently",
+                                             (verifySilently ? "-Xlog:gc":"-Xlog:gc+verify=debug"),
                                              RunSystemGC.class.getName()});
     ProcessBuilder pb =
       ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
@@ -76,11 +76,11 @@
     OutputAnalyzer output;
 
     output = runTest(false);
-    output.shouldContain("[Verifying");
+    output.shouldContain("Verifying");
     output.shouldHaveExitValue(0);
 
     output = runTest(true);
-    output.shouldNotContain("[Verifying");
+    output.shouldNotContain("Verifying");
     output.shouldHaveExitValue(0);
   }
 }
--- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Tue Jan 05 13:08:02 2016 -0800
@@ -79,7 +79,7 @@
 
     // Patterns used during log parsing
     public static final String TENURING_DISTRIBUTION = "Desired survivor size";
-    public static final String AGE_TABLE_ENTRY = "-[\\s]+age[\\s]+([0-9]+):[\\s]+([0-9]+)[\\s]+bytes,[\\s]+([0-9]+)[\\s]+total";
+    public static final String AGE_TABLE_ENTRY = ".*-[\\s]+age[\\s]+([0-9]+):[\\s]+([0-9]+)[\\s]+bytes,[\\s]+([0-9]+)[\\s]+total";
     public static final String MAX_SURVIVOR_SIZE = "Max survivor size: ([0-9]+)";
 
     public static void main(String args[]) throws Exception {
@@ -133,7 +133,7 @@
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:+WhiteBoxAPI",
                 "-XX:+UseAdaptiveSizePolicy",
-                "-XX:+PrintTenuringDistribution",
+                "-Xlog:gc+age=trace",
                 "-XX:MaxTenuringThreshold=" + MAX_TENURING_THRESHOLD,
                 "-XX:NewSize=" + MAX_NEW_SIZE,
                 "-XX:MaxNewSize=" + MAX_NEW_SIZE,
--- a/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java	Tue Jan 05 13:08:02 2016 -0800
@@ -39,11 +39,11 @@
   public static void main(String args[]) throws Exception {
     // The first two JAVA processes are expected to fail, but with a correct VM option suggestion
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-      "-XX:+PrintGc",
+      "-XX:+UseDynamicNumberOfGcThreads",
       "-version"
       );
     OutputAnalyzer outputWithError = new OutputAnalyzer(pb.start());
-    outputWithError.shouldContain("Did you mean '(+/-)PrintGC'?");
+    outputWithError.shouldContain("Did you mean '(+/-)UseDynamicNumberOfGCThreads'?");
     if (outputWithError.getExitValue() == 0) {
       throw new RuntimeException("Not expected to get exit value 0");
     }
@@ -60,11 +60,11 @@
 
     // The last JAVA process should run successfully for the purpose of sanity check
     pb = ProcessTools.createJavaProcessBuilder(
-      "-XX:+PrintGC",
+      "-XX:+UseDynamicNumberOfGCThreads",
       "-version"
       );
     OutputAnalyzer outputWithNoError = new OutputAnalyzer(pb.start());
-    outputWithNoError.shouldNotContain("Did you mean '(+/-)PrintGC'?");
+    outputWithNoError.shouldNotContain("Did you mean '(+/-)UseDynamicNumberOfGCThreads'?");
     outputWithNoError.shouldHaveExitValue(0);
   }
 }
--- a/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java	Tue Jan 05 13:08:02 2016 -0800
@@ -43,18 +43,18 @@
 public class TestVerifyBeforeAndAfterGCFlags {
 
     // VerifyBeforeGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ]
-    public static final String VERIFY_BEFORE_GC_PATTERN = "VerifyBeforeGC:\\[Verifying\\s+([^]\\s]+\\s+)+\\]";
+    public static final String VERIFY_BEFORE_GC_PATTERN = "Verifying Before GC";
     // VerifyBeforeGC: VerifyBeforeGC: VerifyBeforeGC:
     public static final String VERIFY_BEFORE_GC_CORRUPTED_PATTERN = "VerifyBeforeGC:(?!\\[Verifying[^]]+\\])";
 
     // VerifyAfterGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand C-heap code cache ]
-    public static final String VERIFY_AFTER_GC_PATTERN = "VerifyAfterGC:\\[Verifying\\s+([^]\\s]+\\s+)+\\]";
+    public static final String VERIFY_AFTER_GC_PATTERN = "Verifying After GC";
     // VerifyAfterGC: VerifyAfterGC: VerifyAfterGC:
     public static final String VERIFY_AFTER_GC_CORRUPTED_PATTERN = "VerifyAfterGC:(?!\\[Verifying[^]]+\\])";
 
     public static void main(String args[]) throws Exception {
         String[] filteredOpts = Utils.getFilteredTestJavaOpts(
-                                    new String[] { "-Xloggc:",
+                                    new String[] { "-Xlog:gc+verify=debug",
                                                    "-XX:+UseGCLogFileRotation",
                                                    "-XX:-DisplayVMOutput",
                                                    "VerifyBeforeGC",
@@ -74,6 +74,7 @@
         }
 
         Collections.addAll(vmOpts, new String[] {
+                                       "-Xlog:gc+verify=debug",
                                        "-Xmx5m",
                                        "-Xms5m",
                                        "-Xmn3m",
--- a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java	Tue Jan 05 13:08:02 2016 -0800
@@ -59,9 +59,7 @@
       "-Xmn" + YoungGenSize,
       "-XX:+UseConcMarkSweepGC",
       "-XX:" + (enableUnloading ? "+" : "-") + "CMSClassUnloadingEnabled",
-      "-XX:+PrintHeapAtGC",
-      "-XX:+PrintGCDetails",
-      "-XX:+PrintGCTimeStamps",
+      "-Xlog:gc",
       TestCMSClassUnloadingEnabledHWM.AllocateBeyondMetaspaceSize.class.getName(),
       "" + MetaspaceSize);
     return new OutputAnalyzer(pb.start());
@@ -79,16 +77,16 @@
     // -XX:-CMSClassUnloadingEnabled is used, so we expect a full GC instead of a concurrent cycle.
     OutputAnalyzer out = runWithoutCMSClassUnloading();
 
-    out.shouldMatch(".*Full GC.*");
-    out.shouldNotMatch(".*CMS Initial Mark.*");
+    out.shouldMatch(".*Pause Full.*");
+    out.shouldNotMatch(".*Pause Initial Mark.*");
   }
 
   public static void testWithCMSClassUnloading() throws Exception {
     // -XX:+CMSClassUnloadingEnabled is used, so we expect a concurrent cycle instead of a full GC.
     OutputAnalyzer out = runWithCMSClassUnloading();
 
-    out.shouldMatch(".*CMS Initial Mark.*");
-    out.shouldNotMatch(".*Full GC.*");
+    out.shouldMatch(".*Pause Initial Mark.*");
+    out.shouldNotMatch(".*Pause Full.*");
   }
 
   public static void main(String args[]) throws Exception {
--- a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java	Tue Jan 05 13:08:02 2016 -0800
@@ -54,8 +54,7 @@
       "-Xmn" + YoungGenSize,
       "-XX:+UseG1GC",
       "-XX:" + (enableUnloading ? "+" : "-") + "ClassUnloadingWithConcurrentMark",
-      "-XX:+PrintHeapAtGC",
-      "-XX:+PrintGCDetails",
+      "-Xlog:gc",
       TestG1ClassUnloadingHWM.AllocateBeyondMetaspaceSize.class.getName(),
       "" + MetaspaceSize,
       "" + YoungGenSize);
@@ -74,16 +73,16 @@
     // -XX:-ClassUnloadingWithConcurrentMark is used, so we expect a full GC instead of a concurrent cycle.
     OutputAnalyzer out = runWithoutG1ClassUnloading();
 
-    out.shouldMatch(".*Full GC.*");
-    out.shouldNotMatch(".*initial-mark.*");
+    out.shouldMatch(".*Pause Full.*");
+    out.shouldNotMatch(".*Pause Initial Mark.*");
   }
 
   public static void testWithG1ClassUnloading() throws Exception {
     // -XX:+ClassUnloadingWithConcurrentMark is used, so we expect a concurrent cycle instead of a full GC.
     OutputAnalyzer out = runWithG1ClassUnloading();
 
-    out.shouldMatch(".*initial-mark.*");
-    out.shouldNotMatch(".*Full GC.*");
+    out.shouldMatch(".*Pause Initial Mark.*");
+    out.shouldNotMatch(".*Pause Full.*");
   }
 
   public static void main(String args[]) throws Exception {
--- a/hotspot/test/gc/cms/DisableResizePLAB.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/cms/DisableResizePLAB.java	Tue Jan 05 13:08:02 2016 -0800
@@ -28,7 +28,7 @@
  * @author filipp.zhinkin@oracle.com, john.coomes@oracle.com
  * @requires vm.gc=="ConcMarkSweep" | vm.gc=="null"
  * @summary Run CMS with PLAB resizing disabled and a small OldPLABSize
- * @run main/othervm -XX:+UseConcMarkSweepGC -XX:-ResizePLAB -XX:OldPLABSize=1k -Xmx256m -XX:+PrintGCDetails DisableResizePLAB
+ * @run main/othervm -XX:+UseConcMarkSweepGC -XX:-ResizePLAB -XX:OldPLABSize=1k -Xmx256m -Xlog:gc=debug DisableResizePLAB
  */
 
 public class DisableResizePLAB {
--- a/hotspot/test/gc/cms/TestCMSScavengeBeforeRemark.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/cms/TestCMSScavengeBeforeRemark.java	Tue Jan 05 13:08:02 2016 -0800
@@ -27,7 +27,7 @@
  * @bug 8139868
  * @requires vm.gc=="ConcMarkSweep" | vm.gc=="null"
  * @summary Run CMS with CMSScavengeBeforeRemark
- * @run main/othervm -XX:+UseConcMarkSweepGC -XX:+CMSScavengeBeforeRemark -XX:+ExplicitGCInvokesConcurrent -Xmx256m -XX:+PrintGCDetails TestCMSScavengeBeforeRemark
+ * @run main/othervm -XX:+UseConcMarkSweepGC -XX:+CMSScavengeBeforeRemark -XX:+ExplicitGCInvokesConcurrent -Xmx256m -Xlog:gc=debug TestCMSScavengeBeforeRemark
  */
 
 public class TestCMSScavengeBeforeRemark {
--- a/hotspot/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/ergonomics/TestDynamicNumberOfGCThreads.java	Tue Jan 05 13:08:02 2016 -0800
@@ -50,7 +50,7 @@
 
   private static void testDynamicNumberOfGCThreads(String gcFlag) throws Exception {
     // UseDynamicNumberOfGCThreads and TraceDynamicGCThreads enabled
-    String[] baseArgs = {"-XX:+" + gcFlag, "-Xmx10M", "-XX:+PrintGCDetails",  "-XX:+UseDynamicNumberOfGCThreads", "-XX:+TraceDynamicGCThreads", GCTest.class.getName()};
+    String[] baseArgs = {"-XX:+" + gcFlag, "-Xmx10M", "-XX:+UseDynamicNumberOfGCThreads", "-Xlog:gc+task=trace", GCTest.class.getName()};
 
     // Base test with gc and +UseDynamicNumberOfGCThreads:
     ProcessBuilder pb_enabled = ProcessTools.createJavaProcessBuilder(baseArgs);
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions.java	Tue Jan 05 13:08:02 2016 -0800
@@ -82,7 +82,7 @@
             "-Xms128M",
             "-Xmx128M",
             "-Xmn16M",
-            "-XX:+PrintGC",
+            "-Xlog:gc",
             ReclaimRegionFast.class.getName());
 
         Pattern p = Pattern.compile("Full GC");
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java	Tue Jan 05 13:08:02 2016 -0800
@@ -120,7 +120,7 @@
             "-Xmn2M",
             "-XX:G1HeapRegionSize=1M",
             "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible initial marks.
-            "-XX:+PrintGC",
+            "-Xlog:gc",
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:+VerifyAfterGC",
             "-XX:ConcGCThreads=1", // Want to make marking as slow as possible.
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java	Tue Jan 05 13:08:02 2016 -0800
@@ -94,7 +94,7 @@
             "-Xms128M",
             "-Xmx128M",
             "-Xmn16M",
-            "-XX:+PrintGC",
+            "-Xlog:gc",
             ReclaimRegionFast.class.getName());
 
         Pattern p = Pattern.compile("Full GC");
--- a/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java	Tue Jan 05 13:08:02 2016 -0800
@@ -49,20 +49,18 @@
                                                "-Xmx128M",
                                                "-Xmn16M",
                                                "-XX:G1HeapRegionSize=1M",
-                                               "-XX:+PrintGC",
+                                               "-Xlog:gc+phases=trace",
                                                "-XX:+UnlockExperimentalVMOptions",
-                                               "-XX:G1LogLevel=finest",
-                                               "-XX:+G1TraceEagerReclaimHumongousObjects",
                                                GCTest.class.getName());
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
     // As G1EagerReclaimHumongousObjects is set(default), below logs should be displayed.
     // And GCTest doesn't have humongous objects, so values should be zero.
-    output.shouldContain("[Humongous Reclaim");
-    output.shouldContain("[Humongous Total: 0]");
-    output.shouldContain("[Humongous Candidate: 0]");
-    output.shouldContain("[Humongous Reclaimed: 0]");
+    output.shouldContain("Humongous Reclaim");
+    output.shouldContain("Humongous Total: 0");
+    output.shouldContain("Humongous Candidate: 0");
+    output.shouldContain("Humongous Reclaimed: 0");
 
     output.shouldHaveExitValue(0);
   }
@@ -73,19 +71,17 @@
                                                "-Xmx128M",
                                                "-Xmn16M",
                                                "-XX:G1HeapRegionSize=1M",
-                                               "-XX:+PrintGC",
+                                               "-Xlog:gc+phases=trace,gc+humongous=trace",
                                                "-XX:+UnlockExperimentalVMOptions",
-                                               "-XX:G1LogLevel=finest",
-                                               "-XX:+G1TraceEagerReclaimHumongousObjects",
                                                GCWithHumongousObjectTest.class.getName());
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
     // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed.
-    output.shouldContain("[Humongous Reclaim");
-    output.shouldContain("[Humongous Total");
-    output.shouldContain("[Humongous Candidate");
-    output.shouldContain("[Humongous Reclaimed");
+    output.shouldContain("Humongous Reclaim");
+    output.shouldContain("Humongous Total");
+    output.shouldContain("Humongous Candidate");
+    output.shouldContain("Humongous Reclaimed");
 
     // As G1TraceReclaimDeadHumongousObjectsAtYoungGC is set and GCWithHumongousObjectTest has humongous objects,
     // these logs should be displayed.
--- a/hotspot/test/gc/g1/TestGCLogMessages.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java	Tue Jan 05 13:08:02 2016 -0800
@@ -24,7 +24,7 @@
 /*
  * @test TestGCLogMessages
  * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330
- * @summary Ensure that the PrintGCDetails output for a minor GC with G1
+ * @summary Ensure the output for a minor GC with G1
  * includes the expected necessary messages.
  * @key gc
  * @library /testlibrary
@@ -38,7 +38,7 @@
 public class TestGCLogMessages {
 
     private enum Level {
-        OFF, FINER, FINEST;
+        OFF, DEBUG, TRACE;
         public boolean lessOrEqualTo(Level other) {
             return this.compareTo(other) < 0;
         }
@@ -56,36 +56,36 @@
 
     private LogMessageWithLevel allLogMessages[] = new LogMessageWithLevel[] {
         // Update RS
-        new LogMessageWithLevel("Scan HCC (ms)", Level.FINER),
+        new LogMessageWithLevel("Scan HCC", Level.DEBUG),
         // Ext Root Scan
-        new LogMessageWithLevel("Thread Roots (ms)", Level.FINEST),
-        new LogMessageWithLevel("StringTable Roots (ms)", Level.FINEST),
-        new LogMessageWithLevel("Universe Roots (ms)", Level.FINEST),
-        new LogMessageWithLevel("JNI Handles Roots (ms)", Level.FINEST),
-        new LogMessageWithLevel("ObjectSynchronizer Roots (ms)", Level.FINEST),
-        new LogMessageWithLevel("FlatProfiler Roots", Level.FINEST),
-        new LogMessageWithLevel("Management Roots", Level.FINEST),
-        new LogMessageWithLevel("SystemDictionary Roots", Level.FINEST),
-        new LogMessageWithLevel("CLDG Roots", Level.FINEST),
-        new LogMessageWithLevel("JVMTI Roots", Level.FINEST),
-        new LogMessageWithLevel("SATB Filtering", Level.FINEST),
-        new LogMessageWithLevel("CM RefProcessor Roots", Level.FINEST),
-        new LogMessageWithLevel("Wait For Strong CLD", Level.FINEST),
-        new LogMessageWithLevel("Weak CLD Roots", Level.FINEST),
+        new LogMessageWithLevel("Thread Roots:", Level.DEBUG),
+        new LogMessageWithLevel("StringTable Roots:", Level.DEBUG),
+        new LogMessageWithLevel("Universe Roots:", Level.DEBUG),
+        new LogMessageWithLevel("JNI Handles Roots:", Level.DEBUG),
+        new LogMessageWithLevel("ObjectSynchronizer Roots:", Level.DEBUG),
+        new LogMessageWithLevel("FlatProfiler Roots", Level.DEBUG),
+        new LogMessageWithLevel("Management Roots", Level.DEBUG),
+        new LogMessageWithLevel("SystemDictionary Roots", Level.DEBUG),
+        new LogMessageWithLevel("CLDG Roots", Level.DEBUG),
+        new LogMessageWithLevel("JVMTI Roots", Level.DEBUG),
+        new LogMessageWithLevel("SATB Filtering", Level.DEBUG),
+        new LogMessageWithLevel("CM RefProcessor Roots", Level.DEBUG),
+        new LogMessageWithLevel("Wait For Strong CLD", Level.DEBUG),
+        new LogMessageWithLevel("Weak CLD Roots", Level.DEBUG),
         // Redirty Cards
-        new LogMessageWithLevel("Redirty Cards", Level.FINER),
-        new LogMessageWithLevel("Parallel Redirty", Level.FINEST),
-        new LogMessageWithLevel("Redirtied Cards", Level.FINEST),
+        new LogMessageWithLevel("Redirty Cards", Level.DEBUG),
+        new LogMessageWithLevel("Parallel Redirty", Level.DEBUG),
+        new LogMessageWithLevel("Redirtied Cards", Level.DEBUG),
         // Misc Top-level
-        new LogMessageWithLevel("Code Root Purge", Level.FINER),
-        new LogMessageWithLevel("String Dedup Fixup", Level.FINER),
-        new LogMessageWithLevel("Expand Heap After Collection", Level.FINER),
+        new LogMessageWithLevel("Code Root Purge", Level.DEBUG),
+        new LogMessageWithLevel("String Dedup Fixup", Level.DEBUG),
+        new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG),
         // Free CSet
-        new LogMessageWithLevel("Young Free CSet", Level.FINEST),
-        new LogMessageWithLevel("Non-Young Free CSet", Level.FINEST),
+        new LogMessageWithLevel("Young Free CSet", Level.TRACE),
+        new LogMessageWithLevel("Non-Young Free CSet", Level.TRACE),
         // Humongous Eager Reclaim
-        new LogMessageWithLevel("Humongous Reclaim", Level.FINER),
-        new LogMessageWithLevel("Humongous Register", Level.FINER),
+        new LogMessageWithLevel("Humongous Reclaim", Level.DEBUG),
+        new LogMessageWithLevel("Humongous Register", Level.DEBUG),
     };
 
     void checkMessagesAtLevel(OutputAnalyzer output, LogMessageWithLevel messages[], Level level) throws Exception {
@@ -116,53 +116,49 @@
         pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                    "-XX:+UseStringDeduplication",
                                                    "-Xmx10M",
-                                                   "-XX:+PrintGCDetails",
+                                                   "-Xlog:gc+phases=debug",
                                                    GCTest.class.getName());
 
         output = new OutputAnalyzer(pb.start());
-        checkMessagesAtLevel(output, allLogMessages, Level.FINER);
+        checkMessagesAtLevel(output, allLogMessages, Level.DEBUG);
 
         pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                    "-XX:+UseStringDeduplication",
                                                    "-Xmx10M",
-                                                   "-XX:+PrintGCDetails",
-                                                   "-XX:+UnlockExperimentalVMOptions",
-                                                   "-XX:G1LogLevel=finest",
+                                                   "-Xlog:gc+phases=trace",
                                                    GCTest.class.getName());
 
         output = new OutputAnalyzer(pb.start());
-        checkMessagesAtLevel(output, allLogMessages, Level.FINEST);
+        checkMessagesAtLevel(output, allLogMessages, Level.TRACE);
         output.shouldHaveExitValue(0);
     }
 
     LogMessageWithLevel exhFailureMessages[] = new LogMessageWithLevel[] {
-        new LogMessageWithLevel("Evacuation Failure", Level.FINER),
-        new LogMessageWithLevel("Recalculate Used", Level.FINEST),
-        new LogMessageWithLevel("Remove Self Forwards", Level.FINEST),
-        new LogMessageWithLevel("Restore RemSet", Level.FINEST),
+        new LogMessageWithLevel("Evacuation Failure", Level.DEBUG),
+        new LogMessageWithLevel("Recalculate Used", Level.TRACE),
+        new LogMessageWithLevel("Remove Self Forwards", Level.TRACE),
+        new LogMessageWithLevel("Restore RemSet", Level.TRACE),
     };
 
     private void testWithToSpaceExhaustionLogs() throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                                   "-Xmx32M",
                                                                   "-Xmn16M",
-                                                                  "-XX:+PrintGCDetails",
+                                                                  "-Xlog:gc+phases=debug",
                                                                   GCTestWithToSpaceExhaustion.class.getName());
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        checkMessagesAtLevel(output, exhFailureMessages, Level.FINER);
+        checkMessagesAtLevel(output, exhFailureMessages, Level.DEBUG);
         output.shouldHaveExitValue(0);
 
         pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                    "-Xmx32M",
                                                    "-Xmn16M",
-                                                   "-XX:+PrintGCDetails",
-                                                   "-XX:+UnlockExperimentalVMOptions",
-                                                   "-XX:G1LogLevel=finest",
+                                                   "-Xlog:gc+phases=trace",
                                                    GCTestWithToSpaceExhaustion.class.getName());
 
         output = new OutputAnalyzer(pb.start());
-        checkMessagesAtLevel(output, exhFailureMessages, Level.FINEST);
+        checkMessagesAtLevel(output, exhFailureMessages, Level.TRACE);
         output.shouldHaveExitValue(0);
     }
 
--- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java	Tue Jan 05 13:08:02 2016 -0800
@@ -46,11 +46,11 @@
             "-Xmx" + heapSize + "m",
             "-XX:G1HeapRegionSize=" + heapRegionSize + "m",
             "-XX:InitiatingHeapOccupancyPercent=" + initiatingHeapOccupancyPercent,
-            "-XX:+PrintGC",
+            "-Xlog:gc",
             HumongousObjectAllocator.class.getName());
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("GC pause (G1 Humongous Allocation) (young) (initial-mark)");
+        output.shouldContain("Pause Initial Mark (G1 Humongous Allocation)");
         output.shouldNotContain("Full GC");
         output.shouldHaveExitValue(0);
     }
--- a/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestHumongousAllocNearlyFullRegion.java	Tue Jan 05 13:08:02 2016 -0800
@@ -44,11 +44,11 @@
             "-Xms" + heapSize + "m",
             "-Xmx" + heapSize + "m",
             "-XX:G1HeapRegionSize=" + heapRegionSize + "m",
-            "-XX:+PrintGC",
+            "-Xlog:gc",
             HumongousObjectAllocator.class.getName());
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("GC pause (G1 Humongous Allocation) (young) (initial-mark)");
+        output.shouldContain("Pause Initial Mark (G1 Humongous Allocation)");
         output.shouldHaveExitValue(0);
     }
 
--- a/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java	Tue Jan 05 13:08:02 2016 -0800
@@ -34,7 +34,7 @@
  * @build TestNoEagerReclaimOfHumongousRegions
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+PrintGC -XX:+UseG1GC -XX:MaxTenuringThreshold=0 -XX:G1RSetSparseRegionEntries=32 -XX:G1HeapRegionSize=1m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+G1TraceEagerReclaimHumongousObjects TestNoEagerReclaimOfHumongousRegions
+ * @run main/othervm -Xbootclasspath/a:. -Xlog:gc,gc+humongous=debug -XX:+UseG1GC -XX:MaxTenuringThreshold=0 -XX:G1RSetSparseRegionEntries=32 -XX:G1HeapRegionSize=1m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestNoEagerReclaimOfHumongousRegions
  */
 
 import java.util.LinkedList;
--- a/hotspot/test/gc/g1/TestPLABOutput.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestPLABOutput.java	Tue Jan 05 13:08:02 2016 -0800
@@ -54,8 +54,7 @@
             "-XX:+WhiteBoxAPI",
             "-XX:+UseG1GC",
             "-Xmx10M",
-            "-XX:+PrintGC",
-            "-XX:+PrintPLAB",
+            "-Xlog:gc+plab=debug",
             GCTest.class.getName()
             };
 
@@ -66,7 +65,7 @@
 
         System.out.println(output.getStdout());
 
-        String pattern = "#0:.*allocated = (\\d+).*";
+        String pattern = ".*GC\\(0\\) .*allocated = (\\d+).*";
         Pattern r = Pattern.compile(pattern);
         Matcher m = r.matcher(output.getStdout());
 
--- a/hotspot/test/gc/g1/TestPrintGCDetails.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test TestPrintGCDetails
- * @bug 8010738
- * @summary Ensure that the PrintGCDetails for a full GC with G1 includes Metaspace.
- * @key gc
- * @key regression
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management
- */
-
-import jdk.test.lib.ProcessTools;
-import jdk.test.lib.OutputAnalyzer;
-
-public class TestPrintGCDetails {
-  public static void main(String[] args) throws Exception {
-
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
-                                                              "-XX:+PrintGCDetails",
-                                                              SystemGCTest.class.getName());
-
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-    System.out.println("Output:\n" + output.getOutput());
-
-    output.shouldContain("Metaspace");
-    output.shouldHaveExitValue(0);
-  }
-
-  static class SystemGCTest {
-    public static void main(String [] args) {
-      System.out.println("Calling System.gc()");
-      System.gc();
-    }
-  }
-}
--- a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Tue Jan 05 13:08:02 2016 -0800
@@ -57,7 +57,6 @@
             "-Xmx10m",
             "-XX:+ExplicitGCInvokesConcurrent",
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:+G1PrintRegionLivenessInfo",
             "-XX:G1HeapRegionSize=1M",
             "-XX:InitiatingHeapOccupancyPercent=0",
         };
@@ -79,13 +78,13 @@
     public static void main(String[] args) throws Exception {
         String result;
 
-        result = runTest("-XX:+G1PrintRegionLivenessInfo");
+        result = runTest("-Xlog:gc+liveness=trace");
         // check that we got region statistics output
         if (result.indexOf("PHASE") == -1) {
             throw new RuntimeException("Unexpected output from -XX:+PrintRegionLivenessInfo found.");
         }
 
-        result = runTest("-XX:-G1PrintRegionLivenessInfo");
+        result = runTest("-Xlog:gc+liveness");
         if (result.indexOf("remset") != -1) {
             throw new RuntimeException("Should find remembered set information in output.");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestRemsetLogging.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test TestRemsetLogging.java
+ * @bug 8013895 8129977
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management/sun.management
+ * @build TestRemsetLoggingTools TestRemsetLogging
+ * @summary Verify output of -Xlog:gc+remset*=trace
+ * @run main TestRemsetLogging
+ *
+ * Test the output of -Xlog:gc+remset*=trace in conjunction with G1SummarizeRSetStatsPeriod.
+ */
+
+public class TestRemsetLogging {
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        if (!TestRemsetLoggingTools.testingG1GC()) {
+            return;
+        }
+
+        // no remembered set summary output
+        result = TestRemsetLoggingTools.runTest(null, 0);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 0, 0);
+
+        // no remembered set summary output
+        result = TestRemsetLoggingTools.runTest(null, 2);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 0, 0);
+
+        // no remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 0, 0);
+
+        // single remembered set summary output at the end
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace" }, 0);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 0);
+
+        // single remembered set summary output at the end
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace" }, 2);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 0);
+
+        // single remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 0);
+
+        // two times remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 2);
+
+        // four times remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 6);
+
+        // three times remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 4);
+
+        // single remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
+        TestRemsetLoggingTools.expectRSetSummaries(result, 1, 2);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestRemsetLoggingPerRegion.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test TestRemsetLoggingPerRegion.java
+ * @bug 8014078 8129977
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management/sun.management
+ * @build TestRemsetLoggingTools TestRemsetLoggingPerRegion
+ * @summary Verify output of -Xlog:gc+remset*=trace in regards to per-region type output
+ * @run main TestRemsetLoggingPerRegion
+ */
+
+import jdk.test.lib.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class TestRemsetLoggingPerRegion {
+
+    public static void main(String[] args) throws Exception {
+        String result;
+
+        if (!TestRemsetLoggingTools.testingG1GC()) {
+            return;
+        }
+
+        // single remembered set summary output at the end
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace" }, 0);
+        TestRemsetLoggingTools.expectPerRegionRSetSummaries(result, 1, 0);
+
+        // two times remembered set summary output
+        result = TestRemsetLoggingTools.runTest(new String[] { "-Xlog:gc+remset*=trace", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+        TestRemsetLoggingTools.expectPerRegionRSetSummaries(result, 1, 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestRemsetLoggingThreads.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test TestRemsetLoggingThreads
+ * @bug 8025441
+ * @summary Ensure that various values of worker threads/concurrent
+ * refinement threads do not crash the VM.
+ * @key gc
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management/sun.management
+ */
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.OutputAnalyzer;
+
+public class TestRemsetLoggingThreads {
+
+  private static void runTest(int refinementThreads, int workerThreads) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                              "-XX:+UnlockDiagnosticVMOptions",
+                                                              "-Xlog:gc+remset+exit=trace",
+                                                              "-XX:G1ConcRefinementThreads=" + refinementThreads,
+                                                              "-XX:ParallelGCThreads=" + workerThreads,
+                                                              "-version");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used.
+    // Additionally use at least one thread.
+    int expectedNumRefinementThreads = refinementThreads;
+
+    String pattern = "Concurrent RS threads times \\(s\\)$";
+    Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout());
+
+    if (!m.find()) {
+      throw new Exception("Could not find correct output for concurrent RS threads times in stdout," +
+        " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout());
+    }
+    output.shouldHaveExitValue(0);
+  }
+
+  public static void main(String[] args) throws Exception {
+    if (!TestRemsetLoggingTools.testingG1GC()) {
+      return;
+    }
+    // different valid combinations of number of refinement and gc worker threads
+    runTest(1, 1);
+    runTest(1, 5);
+    runTest(5, 1);
+    runTest(10, 10);
+    runTest(1, 2);
+    runTest(4, 3);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestRemsetLoggingTools.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+/*
+ * Common helpers for TestRemsetLogging* tests
+ */
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+import jdk.test.lib.*;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class VerifySummaryOutput {
+    // 4M size, both are directly allocated into the old gen
+    static Object[] largeObject1 = new Object[1024 * 1024];
+    static Object[] largeObject2 = new Object[1024 * 1024];
+
+    static int[] temp;
+
+    public static void main(String[] args) {
+        // create some cross-references between these objects
+        for (int i = 0; i < largeObject1.length; i++) {
+            largeObject1[i] = largeObject2;
+        }
+
+        for (int i = 0; i < largeObject2.length; i++) {
+            largeObject2[i] = largeObject1;
+        }
+
+        int numGCs = Integer.parseInt(args[0]);
+
+        if (numGCs > 0) {
+            // try to force a minor collection: the young gen is 4M, the
+            // amount of data allocated below is roughly that (4*1024*1024 +
+            // some header data)
+            for (int i = 0; i < 1024 ; i++) {
+                temp = new int[1024];
+            }
+        }
+
+        for (int i = 0; i < numGCs - 1; i++) {
+            System.gc();
+        }
+    }
+}
+
+public class TestRemsetLoggingTools {
+
+    // the VM is currently run using G1GC, i.e. trying to test G1 functionality.
+    public static boolean testingG1GC() {
+        HotSpotDiagnosticMXBean diagnostic =
+            ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
+
+        VMOption option = diagnostic.getVMOption("UseG1GC");
+        if (option.getValue().equals("false")) {
+          System.out.println("Skipping this test. It is only a G1 test.");
+          return false;
+        }
+        return true;
+    }
+
+    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
+        ArrayList<String> finalargs = new ArrayList<String>();
+        String[] defaultArgs = new String[] {
+            "-XX:+UseG1GC",
+            "-Xmn4m",
+            "-Xms20m",
+            "-Xmx20m",
+            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:G1HeapRegionSize=1M",
+        };
+
+        finalargs.addAll(Arrays.asList(defaultArgs));
+
+        if (additionalArgs != null) {
+            finalargs.addAll(Arrays.asList(additionalArgs));
+        }
+
+        finalargs.add(VerifySummaryOutput.class.getName());
+        finalargs.add(String.valueOf(numGCs));
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            finalargs.toArray(new String[0]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.shouldHaveExitValue(0);
+
+        String result = output.getStdout();
+        return result;
+    }
+
+    private static void checkCounts(int expected, int actual, String which) throws Exception {
+        if (expected != actual) {
+            throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual);
+        }
+    }
+
+    public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+        expectRSetSummaries(result, expectedCumulative, expectedPeriodic);
+        int actualYoung = result.split("Young regions").length - 1;
+        int actualHumonguous = result.split("Humonguous regions").length - 1;
+        int actualFree = result.split("Free regions").length - 1;
+        int actualOther = result.split("Old regions").length - 1;
+
+        // the strings we check for above are printed four times per summary
+        int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4;
+
+        checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young");
+        checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous");
+        checkCounts(expectedPerRegionTypeInfo, actualFree, "Free");
+        checkCounts(expectedPerRegionTypeInfo, actualOther, "Old");
+    }
+
+    public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+        int actualTotal = result.split("concurrent refinement").length - 1;
+        int actualCumulative = result.split("Cumulative RS summary").length - 1;
+
+        if (expectedCumulative != actualCumulative) {
+            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
+        }
+
+        if (expectedPeriodic != (actualTotal - actualCumulative)) {
+            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
+        }
+    }
+}
--- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java	Tue Jan 05 13:08:02 2016 -0800
@@ -49,7 +49,7 @@
         "-XX:+UseG1GC",
         "-XX:G1HeapRegionSize=" + REGION_SIZE,
         "-XX:-ExplicitGCInvokesConcurrent",
-        "-XX:+PrintGCDetails",
+        "-Xlog:gc=debug",
         "-XX:+UnlockDiagnosticVMOptions",
         "-XX:+WhiteBoxAPI",
         "-Xbootclasspath/a:.",
--- a/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Tue Jan 05 13:08:02 2016 -0800
@@ -304,10 +304,8 @@
         }
 
         public static OutputAnalyzer run() throws Exception {
-            return runTest("-XX:+PrintGC",
-                           "-XX:+PrintGCDetails",
+            return runTest("-Xlog:gc=debug,gc+stringdedup=trace",
                            "-XX:+UseStringDeduplication",
-                           "-XX:+PrintStringDeduplicationStatistics",
                            "-XX:StringDeduplicationAgeThreshold=" + DefaultAgeThreshold,
                            InternedTest.class.getName(),
                            "" + DefaultAgeThreshold);
@@ -333,11 +331,10 @@
         OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
                                                       DefaultAgeThreshold,
                                                       YoungGC,
-                                                      "-XX:+PrintGC",
-                                                      "-XX:+PrintStringDeduplicationStatistics");
+                                                      "-Xlog:gc,gc+stringdedup=trace");
         output.shouldNotContain("Full GC");
-        output.shouldContain("GC pause (G1 Evacuation Pause) (young)");
-        output.shouldContain("GC concurrent-string-deduplication");
+        output.shouldContain("Pause Young (G1 Evacuation Pause)");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldHaveExitValue(0);
     }
@@ -347,11 +344,10 @@
         OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
                                                       DefaultAgeThreshold,
                                                       FullGC,
-                                                      "-XX:+PrintGC",
-                                                      "-XX:+PrintStringDeduplicationStatistics");
-        output.shouldNotContain("GC pause (G1 Evacuation Pause) (young)");
+                                                      "-Xlog:gc,gc+stringdedup=trace");
+        output.shouldNotContain("Pause Young (G1 Evacuation Pause)");
         output.shouldContain("Full GC");
-        output.shouldContain("GC concurrent-string-deduplication");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldHaveExitValue(0);
     }
@@ -361,10 +357,9 @@
         OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
                                                       DefaultAgeThreshold,
                                                       YoungGC,
-                                                      "-XX:+PrintGC",
-                                                      "-XX:+PrintStringDeduplicationStatistics",
+                                                      "-Xlog:gc,gc+stringdedup=trace",
                                                       "-XX:+StringDeduplicationResizeALot");
-        output.shouldContain("GC concurrent-string-deduplication");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldNotContain("Resize Count: 0");
         output.shouldHaveExitValue(0);
@@ -375,10 +370,9 @@
         OutputAnalyzer output = DeduplicationTest.run(LargeNumberOfStrings,
                                                       DefaultAgeThreshold,
                                                       YoungGC,
-                                                      "-XX:+PrintGC",
-                                                      "-XX:+PrintStringDeduplicationStatistics",
+                                                      "-Xlog:gc,gc+stringdedup=trace",
                                                       "-XX:+StringDeduplicationRehashALot");
-        output.shouldContain("GC concurrent-string-deduplication");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldNotContain("Rehash Count: 0");
         output.shouldNotContain("Hash Seed: 0x0");
@@ -392,9 +386,8 @@
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        MaxAgeThreshold,
                                        YoungGC,
-                                       "-XX:+PrintGC",
-                                       "-XX:+PrintStringDeduplicationStatistics");
-        output.shouldContain("GC concurrent-string-deduplication");
+                                       "-Xlog:gc,gc+stringdedup=trace");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldHaveExitValue(0);
 
@@ -402,9 +395,8 @@
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        MinAgeThreshold,
                                        YoungGC,
-                                       "-XX:+PrintGC",
-                                       "-XX:+PrintStringDeduplicationStatistics");
-        output.shouldContain("GC concurrent-string-deduplication");
+                                       "-Xlog:gc,gc+stringdedup=trace");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldContain("Deduplicated:");
         output.shouldHaveExitValue(0);
 
@@ -426,20 +418,20 @@
     public static void testPrintOptions() throws Exception {
         OutputAnalyzer output;
 
-        // Test without PrintGC and without PrintStringDeduplicationStatistics
+        // Test without -Xlog:gc
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        DefaultAgeThreshold,
                                        YoungGC);
-        output.shouldNotContain("GC concurrent-string-deduplication");
+        output.shouldNotContain("Concurrent String Deduplication");
         output.shouldNotContain("Deduplicated:");
         output.shouldHaveExitValue(0);
 
-        // Test with PrintGC but without PrintStringDeduplicationStatistics
+        // Test with -Xlog:gc+stringdedup
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        DefaultAgeThreshold,
                                        YoungGC,
-                                       "-XX:+PrintGC");
-        output.shouldContain("GC concurrent-string-deduplication");
+                                       "-Xlog:gc+stringdedup");
+        output.shouldContain("Concurrent String Deduplication");
         output.shouldNotContain("Deduplicated:");
         output.shouldHaveExitValue(0);
     }
--- a/hotspot/test/gc/g1/TestStringSymbolTableStats.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/TestStringSymbolTableStats.java	Tue Jan 05 13:08:02 2016 -0800
@@ -39,7 +39,7 @@
 
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
                                                               "-XX:+UnlockExperimentalVMOptions",
-                                                              "-XX:+G1TraceStringSymbolTableScrubbing",
+                                                              "-Xlog:gc+stringdedup=trace",
                                                               SystemGCTest.class.getName());
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/hotspot/test/gc/g1/TestSummarizeRSetStats.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test TestSummarizeRSetStats.java
- * @bug 8013895 8129977
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management/sun.management
- * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats
- * @summary Verify output of -XX:+G1SummarizeRSetStats
- * @run main TestSummarizeRSetStats
- *
- * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
- */
-
-public class TestSummarizeRSetStats {
-
-    public static void main(String[] args) throws Exception {
-        String result;
-
-        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
-            return;
-        }
-
-        // no remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(null, 0);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
-
-        // no remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(null, 2);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
-
-        // no remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
-
-        // single remembered set summary output at the end
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
-
-        // single remembered set summary output at the end
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
-
-        // single remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
-
-        // two times remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
-
-        // four times remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6);
-
-        // three times remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4);
-
-        // single remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
-        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
-    }
-}
-
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test TestSummarizeRSetStatsPerRegion.java
- * @bug 8014078 8129977
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management/sun.management
- * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion
- * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output
- * @run main TestSummarizeRSetStatsPerRegion
- */
-
-import jdk.test.lib.*;
-import java.lang.Thread;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class TestSummarizeRSetStatsPerRegion {
-
-    public static void main(String[] args) throws Exception {
-        String result;
-
-        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
-            return;
-        }
-
-        // single remembered set summary output at the end
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
-        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0);
-
-        // two times remembered set summary output
-        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
-        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2);
-    }
-}
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test TestSummarizeRSetStatsThreads
- * @bug 8025441
- * @summary Ensure that various values of worker threads/concurrent
- * refinement threads do not crash the VM.
- * @key gc
- * @library /testlibrary
- * @modules java.base/sun.misc
- *          java.management/sun.management
- */
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import jdk.test.lib.ProcessTools;
-import jdk.test.lib.OutputAnalyzer;
-
-public class TestSummarizeRSetStatsThreads {
-
-  private static void runTest(int refinementThreads, int workerThreads) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
-                                                              "-XX:+UnlockDiagnosticVMOptions",
-                                                              "-XX:+G1SummarizeRSetStats",
-                                                              "-XX:G1ConcRefinementThreads=" + refinementThreads,
-                                                              "-XX:ParallelGCThreads=" + workerThreads,
-                                                              "-version");
-
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-    // check output to contain the string "Concurrent RS threads times (s)" followed by
-    // the correct number of values in the next line.
-
-    // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used.
-    // Additionally use at least one thread.
-    int expectedNumRefinementThreads = refinementThreads;
-
-    // create the pattern made up of n copies of a floating point number pattern
-    String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0)
-      .replace("0", "\\s+\\d+\\.\\d+");
-    String pattern = "Concurrent RS threads times \\(s\\)$" + numberPattern + "$";
-    Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout());
-
-    if (!m.find()) {
-      throw new Exception("Could not find correct output for concurrent RS threads times in stdout," +
-        " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout());
-    }
-    output.shouldHaveExitValue(0);
-  }
-
-  public static void main(String[] args) throws Exception {
-    if (!TestSummarizeRSetStatsTools.testingG1GC()) {
-      return;
-    }
-    // different valid combinations of number of refinement and gc worker threads
-    runTest(1, 1);
-    runTest(1, 5);
-    runTest(5, 1);
-    runTest(10, 10);
-    runTest(1, 2);
-    runTest(4, 3);
-  }
-}
--- a/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java	Wed Jul 05 21:11:02 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * Common helpers for TestSummarizeRSetStats* tests
- */
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
-
-import jdk.test.lib.*;
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-class VerifySummaryOutput {
-    // 4M size, both are directly allocated into the old gen
-    static Object[] largeObject1 = new Object[1024 * 1024];
-    static Object[] largeObject2 = new Object[1024 * 1024];
-
-    static int[] temp;
-
-    public static void main(String[] args) {
-        // create some cross-references between these objects
-        for (int i = 0; i < largeObject1.length; i++) {
-            largeObject1[i] = largeObject2;
-        }
-
-        for (int i = 0; i < largeObject2.length; i++) {
-            largeObject2[i] = largeObject1;
-        }
-
-        int numGCs = Integer.parseInt(args[0]);
-
-        if (numGCs > 0) {
-            // try to force a minor collection: the young gen is 4M, the
-            // amount of data allocated below is roughly that (4*1024*1024 +
-            // some header data)
-            for (int i = 0; i < 1024 ; i++) {
-                temp = new int[1024];
-            }
-        }
-
-        for (int i = 0; i < numGCs - 1; i++) {
-            System.gc();
-        }
-    }
-}
-
-public class TestSummarizeRSetStatsTools {
-
-    // the VM is currently run using G1GC, i.e. trying to test G1 functionality.
-    public static boolean testingG1GC() {
-        HotSpotDiagnosticMXBean diagnostic =
-            ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
-
-        VMOption option = diagnostic.getVMOption("UseG1GC");
-        if (option.getValue().equals("false")) {
-          System.out.println("Skipping this test. It is only a G1 test.");
-          return false;
-        }
-        return true;
-    }
-
-    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
-        ArrayList<String> finalargs = new ArrayList<String>();
-        String[] defaultArgs = new String[] {
-            "-XX:+UseG1GC",
-            "-Xmn4m",
-            "-Xms20m",
-            "-Xmx20m",
-            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
-            "-XX:+PrintGC",
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:G1HeapRegionSize=1M",
-        };
-
-        finalargs.addAll(Arrays.asList(defaultArgs));
-
-        if (additionalArgs != null) {
-            finalargs.addAll(Arrays.asList(additionalArgs));
-        }
-
-        finalargs.add(VerifySummaryOutput.class.getName());
-        finalargs.add(String.valueOf(numGCs));
-
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            finalargs.toArray(new String[0]));
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-        output.shouldHaveExitValue(0);
-
-        String result = output.getStdout();
-        return result;
-    }
-
-    private static void checkCounts(int expected, int actual, String which) throws Exception {
-        if (expected != actual) {
-            throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual);
-        }
-    }
-
-    public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
-        expectRSetSummaries(result, expectedCumulative, expectedPeriodic);
-        int actualYoung = result.split("Young regions").length - 1;
-        int actualHumonguous = result.split("Humonguous regions").length - 1;
-        int actualFree = result.split("Free regions").length - 1;
-        int actualOther = result.split("Old regions").length - 1;
-
-        // the strings we check for above are printed four times per summary
-        int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4;
-
-        checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young");
-        checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous");
-        checkCounts(expectedPerRegionTypeInfo, actualFree, "Free");
-        checkCounts(expectedPerRegionTypeInfo, actualOther, "Old");
-    }
-
-    public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
-        int actualTotal = result.split("concurrent refinement").length - 1;
-        int actualCumulative = result.split("Cumulative RS summary").length - 1;
-
-        if (expectedCumulative != actualCumulative) {
-            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
-        }
-
-        if (expectedPeriodic != (actualTotal - actualCumulative)) {
-            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
-        }
-    }
-}
--- a/hotspot/test/gc/g1/mixedgc/TestLogging.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/g1/mixedgc/TestLogging.java	Tue Jan 05 13:08:02 2016 -0800
@@ -68,10 +68,10 @@
     public static final int ALLOCATION_COUNT = 15;
 
     public static void main(String args[]) throws Exception {
-        // Test turns logging on by giving -XX:+PrintGC flag
-        test("-XX:+PrintGC");
-        // Test turns logging on by giving -XX:+PrintGCDetails
-        test("-XX:+PrintGCDetails");
+        // Test turns logging on by giving -Xlog:gc flag
+        test("-Xlog:gc");
+        // Test turns logging on by giving -Xlog:gc=debug flag
+        test("-Xlog:gc=debug");
     }
 
     private static void test(String vmFlag) throws Exception {
@@ -79,7 +79,7 @@
         OutputAnalyzer output = spawnMixedGCProvoker(vmFlag);
         System.out.println(output.getStdout());
         output.shouldHaveExitValue(0);
-        output.shouldContain("GC pause (G1 Evacuation Pause) (mixed)");
+        output.shouldContain("Pause Mixed (G1 Evacuation Pause)");
     }
 
     /**
--- a/hotspot/test/gc/logging/TestGCId.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/logging/TestGCId.java	Tue Jan 05 13:08:02 2016 -0800
@@ -36,44 +36,21 @@
 
 public class TestGCId {
   public static void main(String[] args) throws Exception {
-    testGCId("UseParallelGC", "PrintGC");
-    testGCId("UseParallelGC", "PrintGCDetails");
-
-    testGCId("UseG1GC", "PrintGC");
-    testGCId("UseG1GC", "PrintGCDetails");
-
-    testGCId("UseConcMarkSweepGC", "PrintGC");
-    testGCId("UseConcMarkSweepGC", "PrintGCDetails");
-
-    testGCId("UseSerialGC", "PrintGC");
-    testGCId("UseSerialGC", "PrintGCDetails");
+    testGCId("UseParallelGC");
+    testGCId("UseG1GC");
+    testGCId("UseConcMarkSweepGC");
+    testGCId("UseSerialGC");
   }
 
   private static void verifyContainsGCIDs(OutputAnalyzer output) {
-    output.shouldMatch("^#0: \\[");
-    output.shouldMatch("^#1: \\[");
+    output.shouldMatch("\\[.*\\]\\[.*\\]\\[.*\\] GC\\(0\\) ");
+    output.shouldMatch("\\[.*\\]\\[.*\\]\\[.*\\] GC\\(1\\) ");
     output.shouldHaveExitValue(0);
   }
 
-  private static void verifyContainsNoGCIDs(OutputAnalyzer output) {
-    output.shouldNotMatch("^#[0-9]+: \\[");
-    output.shouldHaveExitValue(0);
-  }
-
-  private static void testGCId(String gcFlag, String logFlag) throws Exception {
-    // GCID logging enabled
-    ProcessBuilder pb_enabled =
-      ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", "-XX:+PrintGCID", GCTest.class.getName());
-    verifyContainsGCIDs(new OutputAnalyzer(pb_enabled.start()));
-
-    // GCID logging disabled
-    ProcessBuilder pb_disabled =
-      ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", "-XX:-PrintGCID", GCTest.class.getName());
-    verifyContainsNoGCIDs(new OutputAnalyzer(pb_disabled.start()));
-
-    // GCID logging default
+  private static void testGCId(String gcFlag) throws Exception {
     ProcessBuilder pb_default =
-      ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-XX:+" + logFlag, "-Xmx10M", GCTest.class.getName());
+      ProcessTools.createJavaProcessBuilder("-XX:+" + gcFlag, "-Xlog:gc", "-Xmx10M", GCTest.class.getName());
     verifyContainsGCIDs(new OutputAnalyzer(pb_default.start()));
   }
 
--- a/hotspot/test/gc/logging/TestPrintReferences.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/logging/TestPrintReferences.java	Tue Jan 05 13:08:02 2016 -0800
@@ -37,18 +37,18 @@
 public class TestPrintReferences {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb_enabled =
-      ProcessTools.createJavaProcessBuilder("-XX:+PrintGCDetails", "-XX:+PrintReferenceGC", "-Xmx10M", GCTest.class.getName());
+      ProcessTools.createJavaProcessBuilder("-Xlog:gc+ref=debug", "-Xmx10M", GCTest.class.getName());
     OutputAnalyzer output = new OutputAnalyzer(pb_enabled.start());
 
     String countRegex = "[0-9]+ refs";
-    String timeRegex = "[0-9]+[.,][0-9]+ secs";
+    String timeRegex = "\\([0-9]+[.,][0-9]+s, [0-9]+[.,][0-9]+s\\) [0-9]+[.,][0-9]+ms";
 
-    output.shouldMatch(
-      "#[0-9]+: \\[SoftReference, " + countRegex + ", " + timeRegex + "\\]" +
-      "#[0-9]+: \\[WeakReference, " + countRegex + ", " + timeRegex + "\\]" +
-      "#[0-9]+: \\[FinalReference, " + countRegex + ", " + timeRegex + "\\]" +
-      "#[0-9]+: \\[PhantomReference, " + countRegex + ", " + timeRegex + "\\]" +
-      "#[0-9]+: \\[JNI Weak Reference, (" + countRegex + ", )?" + timeRegex + "\\]");
+    output.shouldMatch(".* GC\\([0-9]+\\) SoftReference " + timeRegex + "\n" +
+                       ".* GC\\([0-9]+\\) WeakReference " + timeRegex + "\n" +
+                       ".* GC\\([0-9]+\\) FinalReference " + timeRegex + "\n" +
+                       ".* GC\\([0-9]+\\) PhantomReference " + timeRegex + "\n" +
+                       ".* GC\\([0-9]+\\) JNI Weak Reference " + timeRegex + "\n" +
+                       ".* GC\\([0-9]+\\) Ref Counts: Soft: [0-9]+ Weak: [0-9]+ Final: [0-9]+ Phantom: [0-9]+\n");
 
     output.shouldHaveExitValue(0);
   }
--- a/hotspot/test/gc/serial/HeapChangeLogging.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/serial/HeapChangeLogging.java	Tue Jan 05 13:08:02 2016 -0800
@@ -39,11 +39,11 @@
 
 public class HeapChangeLogging {
   public static void main(String[] args) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xmx128m", "-Xmn100m", "-XX:+UseSerialGC", "-XX:+PrintGC", "HeapFiller");
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xmx128m", "-Xmn100m", "-XX:+UseSerialGC", "-Xlog:gc", "HeapFiller");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     String stdout = output.getStdout();
     System.out.println(stdout);
-    Matcher stdoutMatcher = Pattern.compile("\\[GC .Allocation Failure.*K->.*K\\(.*K\\), .* secs\\]", Pattern.MULTILINE).matcher(stdout);
+    Matcher stdoutMatcher = Pattern.compile(".*\\(Allocation Failure\\) [0-9]+[KMG]->[0-9]+[KMG]\\([0-9]+[KMG]\\)", Pattern.MULTILINE).matcher(stdout);
     if (!stdoutMatcher.find()) {
       throw new RuntimeException("No proper GC log line found");
     }
--- a/hotspot/test/gc/whitebox/TestWBGC.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/gc/whitebox/TestWBGC.java	Tue Jan 05 13:08:02 2016 -0800
@@ -44,7 +44,7 @@
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:+WhiteBoxAPI",
                 "-XX:MaxTenuringThreshold=1",
-                "-XX:+PrintGC",
+                "-Xlog:gc",
                 GCYoungTest.class.getName());
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- a/hotspot/test/runtime/7158988/FieldMonitor.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/7158988/FieldMonitor.java	Tue Jan 05 13:08:02 2016 -0800
@@ -63,7 +63,7 @@
 
   public static final String CLASS_NAME = "TestPostFieldModification";
   public static final String FIELD_NAME = "value";
-  public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC";
+  public static final String ARGUMENTS = "-Xshare:off -Xlog:gc";
 
   public static void main(String[] args)
       throws IOException, InterruptedException {
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Tue Jan 05 13:08:02 2016 -0800
@@ -63,12 +63,26 @@
         allOptionsAsMap.remove(optionName);
     }
 
+    private static void setAllowedExitCodes(String optionName, Integer... allowedExitCodes) {
+        JVMOption option = allOptionsAsMap.get(optionName);
+
+        if (option != null) {
+            option.setAllowedExitCodes(allowedExitCodes);
+        }
+    }
+
     public static void main(String[] args) throws Exception {
         int failedTests;
         List<JVMOption> allOptions;
 
         allOptionsAsMap = JVMOptionsUtils.getOptionsWithRangeAsMap();
 
+        /* Shared flags can cause JVM to exit with error code 2 */
+        setAllowedExitCodes("SharedReadWriteSize", 2);
+        setAllowedExitCodes("SharedReadOnlySize", 2);
+        setAllowedExitCodes("SharedMiscDataSize", 2);
+        setAllowedExitCodes("SharedMiscCodeSize", 2);
+
         /*
          * Remove CICompilerCount from testing because currently it can hang system
          */
@@ -82,23 +96,13 @@
         excludeTestRange("ThreadStackSize");
 
         /*
-         * JDK-8141650
-         * Temporarily exclude SharedMiscDataSize as it will exit the VM with exit code 2 and
-         * "The shared miscellaneous data space is not large enough to preload requested classes."
-         * message at min value.
+         * JDK-8143958
+         * Temporarily exclude testing of max range for Shared* flags
          */
-        excludeTestRange("SharedMiscDataSize");
-
-        /*
-         * JDK-8142874
-         * Temporarily exclude Shared* flagse as they will exit the VM with exit code 2 and
-         * "The shared miscellaneous data space is not large enough to preload requested classes."
-         * message at max values.
-         */
-        excludeTestRange("SharedReadWriteSize");
-        excludeTestRange("SharedReadOnlySize");
-        excludeTestRange("SharedMiscDataSize");
-        excludeTestRange("SharedMiscCodeSize");
+        excludeTestMaxRange("SharedReadWriteSize");
+        excludeTestMaxRange("SharedReadOnlySize");
+        excludeTestMaxRange("SharedMiscDataSize");
+        excludeTestMaxRange("SharedMiscCodeSize");
 
         /*
          * Remove the flag controlling the size of the stack because the
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOption.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOption.java	Tue Jan 05 13:08:02 2016 -0800
@@ -25,7 +25,10 @@
 import com.sun.tools.attach.VirtualMachine;
 import com.sun.tools.attach.AttachOperationFailedException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import jdk.test.lib.DynamicVMOption;
 import jdk.test.lib.OutputAnalyzer;
 import jdk.test.lib.ProcessTools;
@@ -64,6 +67,8 @@
      */
     protected boolean testMaxRange;
 
+    private Set<Integer> allowedExitCodes;
+
     /**
      * Prepend string which added before testing option to the command line
      */
@@ -73,6 +78,9 @@
     protected JVMOption() {
         this.prepend = new ArrayList<>();
         prependString = new StringBuilder();
+        allowedExitCodes = new HashSet<>();
+        allowedExitCodes.add(0);
+        allowedExitCodes.add(1);
         withRange = false;
         testMinRange = true;
         testMaxRange = true;
@@ -161,6 +169,10 @@
         testMaxRange = false;
     }
 
+    public final void setAllowedExitCodes(Integer... allowedExitCodes) {
+        this.allowedExitCodes.addAll(Arrays.asList(allowedExitCodes));
+    }
+
     /**
      * Set new minimum option value
      *
@@ -384,13 +396,13 @@
             printOutputContent(out);
             result = false;
         } else if (valid == true) {
-            if ((exitCode != 0) && (exitCode != 1)) {
+            if (!allowedExitCodes.contains(exitCode)) {
                 failedMessage(name, fullOptionString, valid, "JVM exited with unexpected error code = " + exitCode);
                 printOutputContent(out);
                 result = false;
-            } else if ((exitCode == 1) && (out.getOutput().isEmpty() == true)) {
-                failedMessage(name, fullOptionString, valid, "JVM exited with error(exitcode == 1)"
-                        + ", but with empty stdout and stderr. Description of error is needed!");
+            } else if ((exitCode != 0) && (out.getOutput().isEmpty() == true)) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with error(exitcode == " + exitCode +
+                        "), but with empty stdout and stderr. Description of error is needed!");
                 result = false;
             } else if (out.getOutput().contains("is outside the allowed range")) {
                 failedMessage(name, fullOptionString, valid, "JVM output contains \"is outside the allowed range\"");
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Tue Jan 05 13:08:02 2016 -0800
@@ -161,13 +161,6 @@
             option.addPrepend("-XX:+UseConcMarkSweepGC");
         }
 
-        if (name.startsWith("Shared")) {
-            option.addPrepend("-XX:+UnlockDiagnosticVMOptions");
-            String fileName = "Test" + name + ".jsa";
-            option.addPrepend("-XX:SharedArchiveFile=" + fileName);
-            option.addPrepend("-Xshare:dump");
-        }
-
         if (name.startsWith("NUMA")) {
             option.addPrepend("-XX:+UseNUMA");
         }
@@ -213,6 +206,16 @@
             case "NewSizeThreadIncrease":
                 option.addPrepend("-XX:+UseSerialGC");
                 break;
+            case "SharedReadWriteSize":
+            case "SharedReadOnlySize":
+            case "SharedMiscDataSize":
+            case "SharedMiscCodeSize":
+            case "SharedBaseAddress":
+            case "SharedSymbolTableBucketSize":
+                option.addPrepend("-XX:+UnlockDiagnosticVMOptions");
+                option.addPrepend("-XX:SharedArchiveFile=TestOptionsWithRanges.jsa");
+                option.addPrepend("-Xshare:dump");
+                break;
             default:
                 /* Do nothing */
                 break;
--- a/hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/PrintGCApplicationConcurrentTime.java	Tue Jan 05 13:08:02 2016 -0800
@@ -24,7 +24,7 @@
  /*
  * @test
  * @bug 8026041
- * @run main/othervm -XX:+PrintGCApplicationConcurrentTime -Xcomp PrintGCApplicationConcurrentTime
+ * @run main/othervm -Xlog:safepoint -Xcomp PrintGCApplicationConcurrentTime
  */
 
 public class PrintGCApplicationConcurrentTime {
--- a/hotspot/test/runtime/CommandLine/TestVMOptions.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CommandLine/TestVMOptions.java	Tue Jan 05 13:08:02 2016 -0800
@@ -41,7 +41,7 @@
         "-XX:+IgnoreUnrecognizedVMOptions",
         "-XX:+PrintFlagsInitial");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("bool PrintGCDetails");
+    output.shouldContain("bool UseSerialGC");
 
     pb = ProcessTools.createJavaProcessBuilder(
         "-XX:-PrintVMOptions", "-version");
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Tue Jan 05 13:08:02 2016 -0800
@@ -39,7 +39,7 @@
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedBaseAddress=8g",
             "-Xmx128m",
-            "-XX:+PrintCompressedOopsMode",
+            "-Xlog:gc+metaspace=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Narrow klass base: 0x0000000000000000");
@@ -51,7 +51,7 @@
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:CompressedClassSpaceSize=3g",
             "-Xmx128m",
-            "-XX:+PrintCompressedOopsMode",
+            "-Xlog:gc+metaspace=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Narrow klass base: 0x0000000000000000, Narrow klass shift: 3");
@@ -62,7 +62,7 @@
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
             "-Xmx30g",
-            "-XX:+PrintCompressedOopsMode",
+            "-Xlog:gc+metaspace=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Narrow klass base: 0x0000000000000000");
@@ -75,7 +75,7 @@
             "-XX:+UnlockDiagnosticVMOptions",
             "-Xmx128m",
             "-XX:+UseLargePages",
-            "-XX:+PrintCompressedOopsMode",
+            "-Xlog:gc+metaspace=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Narrow klass base:");
--- a/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java	Tue Jan 05 13:08:02 2016 -0800
@@ -64,7 +64,7 @@
             // Make sure the minimum size is set correctly and printed
             pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockDiagnosticVMOptions",
                                                        "-XX:CompressedClassSpaceSize=1m",
-                                                       "-XX:+PrintCompressedOopsMode",
+                                                       "-Xlog:gc+metaspace=trace",
                                                        "-version");
             output = new OutputAnalyzer(pb.start());
             output.shouldContain("Compressed class space size: 1048576")
@@ -74,7 +74,7 @@
             // Make sure the maximum size is set correctly and printed
             pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockDiagnosticVMOptions",
                                                        "-XX:CompressedClassSpaceSize=3g",
-                                                       "-XX:+PrintCompressedOopsMode",
+                                                       "-Xlog:gc+metaspace=trace",
                                                        "-version");
             output = new OutputAnalyzer(pb.start());
             output.shouldContain("Compressed class space size: 3221225472")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test ReservedStackTest
+ * @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest
+ */
+
+/* The exclusion of java.util.concurrent.locks.AbstractOwnableSynchronizer.setExclusiveOwnerThread()
+ * from the compilable methods is required to ensure that the test will be able
+ * to trigger a StackOverflowError on the right method.
+ */
+
+
+/*
+ * Notes about this test:
+ * This test tries to reproduce a rare but nasty corruption bug that
+ * occurs when a StackOverflowError is thrown in some critical sections
+ * of the ReentrantLock implementation.
+ *
+ * Here's the critical section where a corruption could occur
+ * (from java.util.concurrent.ReentrantLock.java)
+ *
+ * final void lock() {
+ *     if (compareAndSetState(0, 1))
+ *         setExclusiveOwnerThread(Thread.currentThread());
+ *     else
+ *         acquire(1);
+ * }
+ *
+ * The corruption occurs when the compareAndSetState(0, 1)
+ * successfully updates the status of the lock but the method
+ * fails to set the owner because of a stack overflow.
+ * HotSpot checks for stack overflow on method invocations.
+ * The test must trigger a stack overflow either when
+ * Thread.currentThread() or setExclusiveOwnerThread() is
+ * invoked.
+ *
+ * The test starts with a recursive invocation loop until a
+ * first StackOverflowError is thrown, the Error is caught
+ * and a few dozen frames are exited. Now the thread has
+ * little free space on its execution stack and will try
+ * to trigger a stack overflow in the critical section.
+ * The test has a huge array of ReentrantLocks instances.
+ * The thread invokes a recursive method which, at each
+ * of its invocations, tries to acquire the next lock
+ * in the array. The execution continues until a
+ * StackOverflowError is thrown or the end of the array
+ * is reached.
+ * If no StackOverflowError has been thrown, the test
+ * is non conclusive (recommendation: increase the size
+ * of the ReentrantLock array).
+ * The status of all Reentrant locks in the array is checked,
+ * if a corruption is detected, the test failed, otherwise
+ * the test passed.
+ *
+ * To have a chance that the stack overflow occurs on one
+ * of the two targeted method invocations, the test is
+ * repeated in different threads. Each Java thread has a
+ * random size area allocated at the beginning of its
+ * stack to prevent false sharing. The test relies on this
+ * to have different stack alignments when it hits the targeted
+ * methods (the test could have been written with a native
+ * method with alloca, but using different Java threads makes
+ * the test 100% Java).
+ *
+ * One additional trick is required to ensure that the stack
+ * overflow will occur on the Thread.currentThread() getter
+ * or the setExclusiveOwnerThread() setter.
+ *
+ * Potential stack overflows are detected by stack banging,
+ * at method invocation time.
+ * In interpreted code, the stack banging performed for the
+ * lock() method goes further than the stack banging performed
+ * for the getter or the setter method, so the potential stack
+ * overflow is detected before entering the critical section.
+ * In compiled code, the getter and the setter are in-lined,
+ * so the stack banging is only performed before entering the
+ * critical section.
+ * In order to have a stack banging that goes further for the
+ * getter/setter methods than for the lock() method, the test
+ * exploits the property that interpreter frames are (much)
+ * bigger than compiled code frames. When the test is run,
+ * a compiler option disables the compilation of the
+ * setExclusiveOwnerThread() method.
+ *
+ */
+
+import java.util.concurrent.locks.ReentrantLock;
+
+public class ReservedStackTest {
+
+    private static boolean isWindows() {
+        return System.getProperty("os.name").toLowerCase().startsWith("win");
+    }
+
+    static class ReentrantLockTest {
+
+        private ReentrantLock lockArray[];
+        // Frame sizes vary a lot between interpreted code and compiled code
+        // so the lock array has to be big enough to cover all cases.
+        // If test fails with message "Not conclusive test", try to increase
+        // LOCK_ARRAY_SIZE value
+        private static final int LOCK_ARRAY_SIZE = 8192;
+        private boolean stackOverflowErrorReceived;
+        StackOverflowError soe = null;
+        private int index = -1;
+
+        public void initialize() {
+            lockArray = new ReentrantLock[LOCK_ARRAY_SIZE];
+            for (int i = 0; i < LOCK_ARRAY_SIZE; i++) {
+                lockArray[i] = new ReentrantLock();
+            }
+            stackOverflowErrorReceived = false;
+        }
+
+        public String getResult() {
+            if (!stackOverflowErrorReceived) {
+                return "ERROR: Not conclusive test: no StackOverflowError received";
+            }
+            for (int i = 0; i < LOCK_ARRAY_SIZE; i++) {
+                if (lockArray[i].isLocked()) {
+                    if (!lockArray[i].isHeldByCurrentThread()) {
+                        StringBuilder s = new StringBuilder();
+                        s.append("FAILED: ReentrantLock ");
+                        s.append(i);
+                        s.append(" looks corrupted");
+                        return s.toString();
+                    }
+                }
+            }
+            return "PASSED";
+        }
+
+        public void run() {
+            try {
+                lockAndCall(0);
+            } catch (StackOverflowError e) {
+                soe = e;
+                stackOverflowErrorReceived = true;
+            }
+        }
+
+        private void lockAndCall(int i) {
+            index = i;
+            if (i < LOCK_ARRAY_SIZE) {
+                lockArray[i].lock();
+                lockAndCall(i + 1);
+            }
+        }
+    }
+
+    static class RunWithSOEContext implements Runnable {
+
+        int counter;
+        int deframe;
+        int decounter;
+        int setupSOEFrame;
+        int testStartFrame;
+        ReentrantLockTest test;
+
+        public RunWithSOEContext(ReentrantLockTest test, int deframe) {
+            this.test = test;
+            this.deframe = deframe;
+        }
+
+        @Override
+        @jdk.internal.vm.annotation.ReservedStackAccess
+        public void run() {
+            counter = 0;
+            decounter = deframe;
+            test.initialize();
+            recursiveCall();
+            System.out.println("Framework got StackOverflowError at frame = " + counter);
+            System.out.println("Test started execution at frame = " + (counter - deframe));
+            String result = test.getResult();
+            System.out.println(result);
+            // The feature is not fully implemented on Windows platforms,
+            // corruptions are still possible
+            if (!isWindows() && !result.contains("PASSED")) {
+                System.exit(-1);
+            }
+        }
+
+        void recursiveCall() {
+            // Unused local variables to increase the frame size
+            long l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19;
+            long l20, l21, l22, l23, l24, l25, l26, l27, l28, l30, l31, l32, l33, l34, l35, l36, l37;
+            counter++;
+            try {
+                recursiveCall();
+            } catch (StackOverflowError e) {
+            }
+            decounter--;
+            if (decounter == 0) {
+                setupSOEFrame = counter;
+                testStartFrame = counter - deframe;
+                test.run();
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 1000; i++) {
+            // Each iteration has to be executed by a new thread. The test
+            // relies on the random size area pushed by the VM at the beginning
+            // of the stack of each Java thread it creates.
+            Thread thread = new Thread(new RunWithSOEContext(new ReentrantLockTest(), 256));
+            thread.start();
+            try {
+                thread.join();
+            } catch (InterruptedException ex) { }
+        }
+    }
+}
--- a/hotspot/test/runtime/logging/DefaultMethodsTest.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/runtime/logging/DefaultMethodsTest.java	Tue Jan 05 13:08:02 2016 -0800
@@ -26,6 +26,7 @@
  * @bug 8139564
  * @summary defaultmethods=debug should have logging from each of the statements in the code
  * @library /testlibrary
+ * @ignore 8146435
  * @modules java.base/sun.misc
  *          java.management
  * @run driver DefaultMethodsTest
--- a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Tue Jan 05 13:08:02 2016 -0800
@@ -43,7 +43,7 @@
  *          jdk.jvmstat/sun.jvmstat.monitor
  * @build jdk.test.lib.*
  * @build jdk.test.lib.dcmd.*
- * @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog -XX:-ExplicitGCInvokesConcurrent RunGCTest
+ * @run testng/othervm -Xlog:gc=debug:RunGC.gclog -XX:-ExplicitGCInvokesConcurrent RunGCTest
  */
 public class RunGCTest {
     public void run(CommandExecutor executor) {
@@ -59,7 +59,7 @@
         }
 
         OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
-        output.shouldContain("[Full GC (Diagnostic Command)");
+        output.shouldContain("Pause Full (Diagnostic Command)");
     }
 
     @Test
--- a/hotspot/test/serviceability/dcmd/vm/FlagsTest.java	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java	Tue Jan 05 13:08:02 2016 -0800
@@ -36,14 +36,13 @@
  *          jdk.jvmstat/sun.jvmstat.monitor
  * @build jdk.test.lib.*
  * @build jdk.test.lib.dcmd.*
- * @run testng/othervm -Xmx129m -XX:+PrintGC -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
+ * @run testng/othervm -Xmx129m -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
  */
 public class FlagsTest {
     public void run(CommandExecutor executor) {
         OutputAnalyzer output = executor.execute("VM.flags");
 
         /* The following are interpreted by the JVM as actual "flags" */
-        output.shouldContain("-XX:+PrintGC");
         output.shouldContain("-XX:+UnlockDiagnosticVMOptions");
         output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
         output.shouldContain("-XX:-TieredCompilation");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/logging/TestLogRotation.java	Tue Jan 05 13:08:02 2016 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * @test TestLogRotation.java
+ * @summary test flags for log rotation
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ * @run main/othervm/timeout=600 TestLogRotation
+ *
+ */
+import jdk.test.lib.*;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class GCLoggingGenerator {
+
+    public static void main(String[] args) throws Exception {
+
+        long sizeOfLog = Long.parseLong(args[0]);
+        long lines = sizeOfLog / 80;
+        // full.GC generates ad least 1-line which is not shorter then 80 chars
+        // for some GC 2 shorter lines are generated
+        for (long i = 0; i < lines; i++) {
+            System.gc();
+        }
+    }
+}
+
+public class TestLogRotation {
+
+    static final File currentDirectory = new File(".");
+    static final String logFileName = "test.log";
+    static final int logFileSizeK = 16;
+    static FilenameFilter logFilter = new FilenameFilter() {
+        @Override
+        public boolean accept(File dir, String name) {
+            return name.startsWith(logFileName);
+        }
+    };
+
+    public static void cleanLogs() {
+        for (File log : currentDirectory.listFiles(logFilter)) {
+            if (!log.delete()) {
+                throw new Error("Unable to delete " + log.getAbsolutePath());
+            }
+        }
+    }
+
+    public static void runTest(int numberOfFiles) throws Exception {
+
+        ArrayList<String> args = new ArrayList();
+        String[] logOpts = new String[]{
+            "-cp", System.getProperty("java.class.path"),
+            "-Xlog:gc=debug:" + logFileName + "::filesize=" + logFileSizeK + ",filecount=" + numberOfFiles,
+            "-XX:-DisableExplicitGC", // to ensure that System.gc() works
+            "-Xmx128M"};
+        // System.getProperty("test.java.opts") is '' if no options is set
+        // need to skip such empty
+        String[] externalVMopts = System.getProperty("test.java.opts").length() == 0
+                ? new String[0]
+                : System.getProperty("test.java.opts").split(" ");
+        args.addAll(Arrays.asList(externalVMopts));
+        args.addAll(Arrays.asList(logOpts));
+        args.add(GCLoggingGenerator.class.getName());
+        args.add(String.valueOf(numberOfFiles * logFileSizeK * 1024));
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
+        pb.redirectErrorStream(true);
+        pb.redirectOutput(new File(GCLoggingGenerator.class.getName() + ".log"));
+        Process process = pb.start();
+        int result = process.waitFor();
+        if (result != 0) {
+            throw new Error("Unexpected exit code = " + result);
+        }
+        File[] logs = currentDirectory.listFiles(logFilter);
+        int smallFilesNumber = 0;
+        for (File log : logs) {
+            if (log.length() < logFileSizeK * 1024) {
+                smallFilesNumber++;
+            }
+        }
+        if (logs.length != numberOfFiles) {
+            throw new Error("There are only " + logs.length + " logs instead " + numberOfFiles);
+        }
+        if (smallFilesNumber > 1) {
+            throw new Error("There should maximum one log with size < " + logFileSizeK + "K");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        cleanLogs();
+        runTest(1);
+        cleanLogs();
+        runTest(3);
+        cleanLogs();
+    }
+}
--- a/hotspot/test/test_env.sh	Wed Jul 05 21:11:02 2017 +0200
+++ b/hotspot/test/test_env.sh	Tue Jan 05 13:08:02 2016 -0800
@@ -192,6 +192,11 @@
   if [ $VM_BITS = "64" ]
   then
     VM_CPU="ppc64"
+    grep "ppc64le" vm_version.out > ${NULL}
+    if [ $? = 0 ]
+    then
+      VM_CPU="ppc64le"
+    fi
   fi
 fi
 grep "ia64" vm_version.out > ${NULL}