--- 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(¬_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(¤t);
- print_summary_info(&_prev_period_summary, header);
+ G1RemSetSummary current;
+ current.initialize(this);
+ _prev_period_summary.subtract_from(¤t);
- _prev_period_summary.set(¤t);
+ LogHandle(gc, remset) log;
+ log.trace("%s", header);
+ ResourceMark rm;
+ _prev_period_summary.print_on(log.trace_stream());
+
+ _prev_period_summary.set(¤t);
+ }
}
void G1RemSet::print_summary_info() {
- G1RemSetSummary current;
- current.initialize(this);
-
- print_summary_info(¤t, " 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}