--- a/hotspot/make/aix/makefiles/trace.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/aix/makefiles/trace.make Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -57,11 +57,6 @@
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
-
-ifneq ($(INCLUDE_TRACE), false)
-TraceGeneratedNames += traceProducer.cpp
-endif
-
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@@ -100,9 +95,6 @@
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
-$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
- $(GENERATE_CODE)
-
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)
--- a/hotspot/make/bsd/makefiles/trace.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/bsd/makefiles/trace.make Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -57,11 +57,6 @@
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
-
-ifneq ($(INCLUDE_TRACE), false)
-TraceGeneratedNames += traceProducer.cpp
-endif
-
endif
@@ -101,9 +96,6 @@
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
-$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
- $(GENERATE_CODE)
-
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)
--- a/hotspot/make/linux/makefiles/trace.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/linux/makefiles/trace.make Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -57,11 +57,6 @@
TraceGeneratedNames += \
traceRequestables.hpp \
traceEventControl.hpp
-
-ifneq ($(INCLUDE_TRACE), false)
-TraceGeneratedNames += traceProducer.cpp
-endif
-
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@@ -100,9 +95,6 @@
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
-$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
- $(GENERATE_CODE)
-
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)
--- a/hotspot/make/solaris/makefiles/amd64.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/solaris/makefiles/amd64.make Sat Mar 05 10:10:23 2016 +0100
@@ -39,7 +39,7 @@
# of OPT_CFLAGS. Restore it here.
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
OPT_CFLAGS/generateOptoStub.o += -g0 -xs
- OPT_CFLAGS/LinearScan.o += -g0 -xs
+ OPT_CFLAGS/c1_LinearScan.o += -g0 -xs
endif
else
--- a/hotspot/make/solaris/makefiles/trace.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/solaris/makefiles/trace.make Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -56,8 +56,7 @@
ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \
traceRequestables.hpp \
- traceEventControl.hpp \
- traceProducer.cpp
+ traceEventControl.hpp
endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@@ -96,9 +95,6 @@
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE)
-$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
- $(GENERATE_CODE)
-
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE)
--- a/hotspot/make/windows/makefiles/trace.make Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/make/windows/makefiles/trace.make Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,7 @@
!if EXISTS($(TraceAltSrcDir))
TraceGeneratedNames = $(TraceGeneratedNames) \
traceRequestables.hpp \
- traceEventControl.hpp \
- traceProducer.cpp
+ traceEventControl.hpp
!endif
@@ -58,8 +57,7 @@
!if EXISTS($(TraceAltSrcDir))
TraceGeneratedFiles = $(TraceGeneratedFiles) \
$(TraceOutDir)/traceRequestables.hpp \
- $(TraceOutDir)/traceEventControl.hpp \
- $(TraceOutDir)/traceProducer.cpp
+ $(TraceOutDir)/traceEventControl.hpp
!endif
XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
@@ -98,10 +96,6 @@
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
-$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
- @echo Generating AltSrc $@
- @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
-
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/development/Server16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/development/Server24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/About16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/About24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Delete16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Delete24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Find16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Help16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Help24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/History16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/History24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Information16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Information24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/New16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/New24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Open16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Open24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Save24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/development/Server16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/development/Server24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/About16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/About24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Delete16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Delete24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Find16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Help16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Help24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/History16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/History24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Information16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Information24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/New16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/New24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Open16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Open24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Save24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/SaveAs16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/SaveAs24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/Zoom16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/ZoomIn16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/general/ZoomIn24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/navigation/Down16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/navigation/Up16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignCenter16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignCenter24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignLeft16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignLeft24.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignRight16.gif has changed
Binary file hotspot/src/jdk.hotspot.agent/share/classes/toolbarButtonGraphics/text/AlignRight24.gif has changed
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016 SAP SE. 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
@@ -36,6 +36,7 @@
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_aix.h"
+#include "logging/log.hpp"
#include "libo4.hpp"
#include "libperfstat_aix.hpp"
#include "libodm_aix.hpp"
@@ -791,13 +792,8 @@
const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self();
- trcVerbose("newborn Thread : pthread-id %u, ktid " UINT64_FORMAT
- ", stack %p ... %p, stacksize 0x%IX (%IB)",
- pthread_id, kernel_thread_id,
- thread->stack_end(),
- thread->stack_base(),
- thread->stack_size(),
- thread->stack_size());
+ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) kernel_thread_id);
// Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()
// by the pthread library). In rare cases, this may not be the case, e.g. when third-party
@@ -805,7 +801,7 @@
// guard pages on those stacks, because the stacks may reside in memory which is not
// protectable (shmated).
if (thread->stack_base() > ::sbrk(0)) {
- trcVerbose("Thread " UINT64_FORMAT ": stack not in data segment.", (uint64_t) pthread_id);
+ log_warning(os, thread)("Thread stack not in data segment.");
}
// Try to randomize the cache line index of hot stack frames.
@@ -839,8 +835,8 @@
// Call one more level start routine.
thread->run();
- trcVerbose("Thread finished : pthread-id %u, ktid " UINT64_FORMAT ".",
- pthread_id, kernel_thread_id);
+ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) kernel_thread_id);
return 0;
}
@@ -908,20 +904,19 @@
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
- pthread_attr_destroy(&attr);
-
+
+ char buf[64];
if (ret == 0) {
- trcVerbose("Created New Thread : pthread-id %u", tid);
+ log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
+ (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
- if (os::Aix::on_pase()) {
- // QIBM_MULTI_THREADED=Y is needed when the launcher is started on iSeries
- // using QSH. Otherwise pthread_create fails with errno=11.
- trcVerbose("(Please make sure you set the environment variable "
- "QIBM_MULTI_THREADED=Y before running this program.)");
- }
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("pthread_create()");
- }
+ log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
+ strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
+ }
+
+ pthread_attr_destroy(&attr);
+
+ if (ret != 0) {
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@@ -958,13 +953,6 @@
const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self();
- trcVerbose("attaching Thread : pthread-id %u, ktid " UINT64_FORMAT ", stack %p ... %p, stacksize 0x%IX (%IB)",
- pthread_id, kernel_thread_id,
- thread->stack_end(),
- thread->stack_base(),
- thread->stack_size(),
- thread->stack_size());
-
// OSThread::thread_id is the pthread id.
osthread->set_thread_id(pthread_id);
@@ -990,6 +978,9 @@
// and save the caller's signal mask
os::Aix::hotspot_sigmask(thread);
+ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) kernel_thread_id);
+
return true;
}
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -32,6 +32,7 @@
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_bsd.h"
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "mutex_bsd.inline.hpp"
@@ -681,6 +682,9 @@
osthread->set_thread_id(os::Bsd::gettid());
+ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
#ifdef __APPLE__
uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
guarantee(unique_thread_id != 0, "unique thread id was not found");
@@ -716,6 +720,9 @@
// call one more level start routine
thread->run();
+ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
return 0;
}
@@ -776,12 +783,18 @@
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
+ char buf[64];
+ if (ret == 0) {
+ log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
+ (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
+ } else {
+ log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
+ strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
+ }
+
pthread_attr_destroy(&attr);
if (ret != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("pthread_create()");
- }
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@@ -858,6 +871,9 @@
// and save the caller's signal mask
os::Bsd::hotspot_sigmask(thread);
+ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
return true;
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -662,6 +662,9 @@
osthread->set_thread_id(os::current_thread_id());
+ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
@@ -691,6 +694,9 @@
// call one more level start routine
thread->run();
+ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
return 0;
}
@@ -756,12 +762,18 @@
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
+ char buf[64];
+ if (ret == 0) {
+ log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
+ (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
+ } else {
+ log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
+ strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
+ }
+
pthread_attr_destroy(&attr);
if (ret != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("pthread_create()");
- }
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
@@ -858,6 +870,9 @@
// and save the caller's signal mask
os::Linux::hotspot_sigmask(thread);
+ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
+ os::current_thread_id(), (uintx) pthread_self());
+
return true;
}
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1071,6 +1071,19 @@
#endif
}
+char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr) {
+ size_t stack_size = 0;
+ size_t guard_size = 0;
+ int detachstate = 0;
+ pthread_attr_getstacksize(attr, &stack_size);
+ pthread_attr_getguardsize(attr, &guard_size);
+ pthread_attr_getdetachstate(attr, &detachstate);
+ jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s",
+ stack_size / 1024, guard_size / 1024,
+ (detachstate == PTHREAD_CREATE_DETACHED ? "detached" : "joinable"));
+ return buf;
+}
+
os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
--- a/hotspot/src/os/posix/vm/os_posix.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/posix/vm/os_posix.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -76,6 +76,11 @@
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);
+
+ // Helper function; describes pthread attributes as short string. String is written
+ // to buf with len buflen; buf is returned.
+ static char* describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr);
+
};
/*
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_solaris.h"
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "mutex_solaris.inline.hpp"
@@ -68,6 +69,7 @@
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
// put OS-includes here
@@ -736,6 +738,9 @@
osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound
thread->_schedctl = (void *) schedctl_init();
+ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").",
+ os::current_thread_id());
+
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
@@ -781,6 +786,8 @@
Atomic::dec(&os::Solaris::_os_thread_count);
}
+ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
+
if (UseDetachedThreads) {
thr_exit(NULL);
ShouldNotReachHere();
@@ -853,6 +860,9 @@
// and save the caller's signal mask
os::Solaris::hotspot_sigmask(thread);
+ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",
+ os::current_thread_id());
+
return true;
}
@@ -879,6 +889,24 @@
return true;
}
+// Helper function to trace thread attributes, similar to os::Posix::describe_pthread_attr()
+static char* describe_thr_create_attributes(char* buf, size_t buflen,
+ size_t stacksize, long flags) {
+ stringStream ss(buf, buflen);
+ ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);
+ ss.print("flags: ");
+ #define PRINT_FLAG(f) if (flags & f) ss.print( #f " ");
+ #define ALL(X) \
+ X(THR_SUSPENDED) \
+ X(THR_DETACHED) \
+ X(THR_BOUND) \
+ X(THR_NEW_LWP) \
+ X(THR_DAEMON)
+ ALL(PRINT_FLAG)
+ #undef ALL
+ #undef PRINT_FLAG
+ return buf;
+}
bool os::create_thread(Thread* thread, ThreadType thr_type,
size_t stack_size) {
@@ -974,10 +1002,17 @@
osthread->set_thread_id(-1);
status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
+
+ char buf[64];
+ if (status == 0) {
+ log_info(os, thread)("Thread started (tid: " UINTX_FORMAT ", attributes: %s). ",
+ (uintx) tid, describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags));
+ } else {
+ log_warning(os, thread)("Failed to start thread - thr_create failed (%s) for attributes: %s.",
+ strerror(status), describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags));
+ }
+
if (status != 0) {
- if (PrintMiscellaneous && (Verbose || WizardMode)) {
- perror("os::create_thread");
- }
thread->set_osthread(NULL);
// Need to clean up stuff we've allocated so far
delete osthread;
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -35,6 +35,7 @@
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_windows.h"
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "mutex_windows.inline.hpp"
@@ -71,6 +72,7 @@
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
+#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
#ifdef _DEBUG
@@ -436,6 +438,8 @@
res = 20115; // java thread
}
+ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
+
// Install a win32 structured exception handler around every thread created
// by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread).
@@ -446,6 +450,8 @@
// Nothing to do.
}
+ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
+
// One less thread is executing
// When the VMThread gets here, the main thread may have already exited
// which frees the CodeHeap containing the Atomic::add code
@@ -509,6 +515,10 @@
osthread->set_state(RUNNABLE);
thread->set_osthread(osthread);
+
+ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",
+ os::current_thread_id());
+
return true;
}
@@ -530,6 +540,27 @@
return true;
}
+// Helper function to trace _beginthreadex attributes,
+// similar to os::Posix::describe_pthread_attr()
+static char* describe_beginthreadex_attributes(char* buf, size_t buflen,
+ size_t stacksize, unsigned initflag) {
+ stringStream ss(buf, buflen);
+ if (stacksize == 0) {
+ ss.print("stacksize: default, ");
+ } else {
+ ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);
+ }
+ ss.print("flags: ");
+ #define PRINT_FLAG(f) if (initflag & f) ss.print( #f " ");
+ #define ALL(X) \
+ X(CREATE_SUSPENDED) \
+ X(STACK_SIZE_PARAM_IS_A_RESERVATION)
+ ALL(PRINT_FLAG)
+ #undef ALL
+ #undef PRINT_FLAG
+ return buf;
+}
+
// Allocate and initialize a new OSThread
bool os::create_thread(Thread* thread, ThreadType thr_type,
size_t stack_size) {
@@ -596,14 +627,24 @@
// document because JVM uses C runtime library. The good news is that the
// flag appears to work with _beginthredex() as well.
+ const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
HANDLE thread_handle =
(HANDLE)_beginthreadex(NULL,
(unsigned)stack_size,
(unsigned (__stdcall *)(void*)) java_start,
thread,
- CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
+ initflag,
&thread_id);
+ char buf[64];
+ if (thread_handle != NULL) {
+ log_info(os, thread)("Thread started (tid: %u, attributes: %s)",
+ thread_id, describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
+ } else {
+ log_warning(os, thread)("Failed to start thread - _beginthreadex failed (%s) for attributes: %s.",
+ strerror(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
+ }
+
if (thread_handle == NULL) {
// Need to clean up stuff we've allocated so far
CloseHandle(osthread->interrupt_event());
@@ -1668,8 +1709,7 @@
if (is_workstation) {
st->print("10");
} else {
- // The server version name of Windows 10 is not known at this time
- st->print("%d.%d", major_version, minor_version);
+ st->print("Server 2016");
}
break;
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -228,8 +228,6 @@
case vmIntrinsics::_getCharStringU:
case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS
- case vmIntrinsics::_classID:
- case vmIntrinsics::_threadID:
case vmIntrinsics::_counterTime:
#endif
break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -43,6 +43,9 @@
#if INCLUDE_ALL_GCS
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
+#ifdef TRACE_HAVE_INTRINSICS
+#include "trace/traceMacros.hpp"
+#endif
#ifdef ASSERT
#define __ gen()->lir(__FILE__, __LINE__)->
@@ -3067,42 +3070,7 @@
__ move(reg, result);
}
-#ifdef TRACE_HAVE_INTRINSICS
-void LIRGenerator::do_ThreadIDIntrinsic(Intrinsic* x) {
- LIR_Opr thread = getThreadPointer();
- LIR_Opr osthread = new_pointer_register();
- __ move(new LIR_Address(thread, in_bytes(JavaThread::osthread_offset()), osthread->type()), osthread);
- size_t thread_id_size = OSThread::thread_id_size();
- if (thread_id_size == (size_t) BytesPerLong) {
- LIR_Opr id = new_register(T_LONG);
- __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_LONG), id);
- __ convert(Bytecodes::_l2i, id, rlock_result(x));
- } else if (thread_id_size == (size_t) BytesPerInt) {
- __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_INT), rlock_result(x));
- } else {
- ShouldNotReachHere();
- }
-}
-
-void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
- CodeEmitInfo* info = state_for(x);
- CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
- BasicType klass_pointer_type = NOT_LP64(T_INT) LP64_ONLY(T_LONG);
- assert(info != NULL, "must have info");
- LIRItem arg(x->argument_at(1), this);
- arg.load_item();
- LIR_Opr klass = new_pointer_register();
- __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), klass_pointer_type), klass, info);
- LIR_Opr id = new_register(T_LONG);
- ByteSize offset = TRACE_ID_OFFSET;
- LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
- __ move(trace_id_addr, id);
- __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
- __ store(id, trace_id_addr);
- __ logical_and(id, LIR_OprFact::longConst(~0x3l), id);
- __ move(id, rlock_result(x));
-}
-#endif
+
void LIRGenerator::do_Intrinsic(Intrinsic* x) {
switch (x->id()) {
@@ -3115,8 +3083,6 @@
}
#ifdef TRACE_HAVE_INTRINSICS
- case vmIntrinsics::_threadID: do_ThreadIDIntrinsic(x); break;
- case vmIntrinsics::_classID: do_ClassIDIntrinsic(x); break;
case vmIntrinsics::_counterTime:
do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -440,10 +440,7 @@
void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux);
void do_RuntimeCall(address routine, Intrinsic* x);
-#ifdef TRACE_HAVE_INTRINSICS
- void do_ThreadIDIntrinsic(Intrinsic* x);
- void do_ClassIDIntrinsic(Intrinsic* x);
-#endif
+
ciKlass* profile_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k,
Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_at_call_k,
ciKlass* callee_signature_k);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -5380,7 +5380,7 @@
}
}
- TRACE_INIT_ID(ik);
+ TRACE_INIT_KLASS_ID(ik);
// If we reach here, all is well.
// Now remove the InstanceKlass* from the _klass_to_deallocate field
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -37,6 +37,7 @@
#include "gc/shared/generation.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/oopMapCache.hpp"
+#include "logging/logTag.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/oopFactory.hpp"
@@ -417,34 +418,30 @@
#if INCLUDE_CDS
void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
assert(DumpSharedSpaces, "only called at dump time");
- tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
+ tty->print_cr("Hint: enable -Xlog:classpath=info to diagnose the failure");
vm_exit_during_initialization(error, message);
}
#endif
-void ClassLoader::trace_class_path(outputStream* out, const char* msg, const char* name) {
- if (!TraceClassPaths) {
- return;
- }
-
- if (msg) {
- out->print("%s", msg);
- }
- if (name) {
- if (strlen(name) < 256) {
- out->print("%s", name);
- } else {
- // For very long paths, we need to print each character separately,
- // as print_cr() has a length limit
- while (name[0] != '\0') {
- out->print("%c", name[0]);
- name++;
+void ClassLoader::trace_class_path(const char* msg, const char* name) {
+ if (log_is_enabled(Info, classpath)) {
+ ResourceMark rm;
+ outputStream* out = LogHandle(classpath)::info_stream();
+ if (msg) {
+ out->print("%s", msg);
+ }
+ if (name) {
+ if (strlen(name) < 256) {
+ out->print("%s", name);
+ } else {
+ // For very long paths, we need to print each character separately,
+ // as print_cr() has a length limit
+ while (name[0] != '\0') {
+ out->print("%c", name[0]);
+ name++;
+ }
}
}
- }
- if (msg && msg[0] == '[') {
- out->print_cr("]");
- } else {
out->cr();
}
}
@@ -470,11 +467,13 @@
void ClassLoader::setup_bootstrap_search_path() {
assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
const char* sys_class_path = Arguments::get_sysclasspath();
+ const char* java_class_path = Arguments::get_appclasspath();
if (PrintSharedArchiveAndExit) {
// Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
// the same as the bootcp of the shared archive.
} else {
- trace_class_path(tty, "[Bootstrap loader class path=", sys_class_path);
+ trace_class_path("bootstrap loader class path=", sys_class_path);
+ trace_class_path("classpath: ", java_class_path);
}
#if INCLUDE_CDS
if (DumpSharedSpaces) {
@@ -578,9 +577,7 @@
}
}
}
- if (TraceClassPaths) {
- tty->print_cr("[Opened %s]", path);
- }
+ log_info(classpath)("opened: %s", path);
log_info(classload)("opened: %s", path);
} else {
// Directory
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -331,7 +331,7 @@
static void exit_with_path_failure(const char* error, const char* message);
#endif
- static void trace_class_path(outputStream* out, const char* msg, const char* name = NULL);
+ static void trace_class_path(const char* msg, const char* name = NULL);
// VM monitoring and management support
static jlong classloader_time_ms();
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -135,8 +135,10 @@
// via a store to _pd_set.
OrderAccess::release_store_ptr(&_pd_set, new_head);
}
- if (TraceProtectionDomainVerification && WizardMode) {
- print();
+ if (log_is_enabled(Trace, protectiondomain)) {
+ ResourceMark rm;
+ outputStream* log = LogHandle(protectiondomain)::trace_stream();
+ print_count(log);
}
}
--- a/hotspot/src/share/vm/classfile/dictionary.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -29,6 +29,7 @@
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
#include "utilities/hashtable.hpp"
+#include "utilities/ostream.hpp"
class DictionaryEntry;
class PSPromotionManager;
@@ -323,14 +324,14 @@
return (klass->name() == class_name && _loader_data == loader_data);
}
- void print() {
+ void print_count(outputStream *st) {
int count = 0;
for (ProtectionDomainEntry* current = _pd_set;
current != NULL;
current = current->_next) {
count++;
}
- tty->print_cr("pd set = #%d", count);
+ st->print_cr("pd set count = #%d", count);
}
};
--- a/hotspot/src/share/vm/classfile/klassFactory.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/klassFactory.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
#include "classfile/klassFactory.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvmtiEnvBase.hpp"
+#include "trace/traceMacros.hpp"
static ClassFileStream* prologue(ClassFileStream* stream,
Symbol* name,
@@ -136,5 +137,7 @@
result->set_cached_class_file(cached_class_file);
}
+ TRACE_KLASS_CREATION(result, parser, THREAD);
+
return result;
}
--- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,15 +26,15 @@
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/sharedPathsMiscInfo.hpp"
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/metaspaceShared.hpp"
#include "runtime/arguments.hpp"
+#include "utilities/ostream.hpp"
void SharedPathsMiscInfo::add_path(const char* path, int type) {
- if (TraceClassPaths) {
- tty->print("[type=%s] ", type_name(type));
- trace_class_path("[Add misc shared path ", path);
- }
+ log_info(classpath)("type=%s ", type_name(type));
+ ClassLoader::trace_class_path("add misc shared path ", path);
write(path, strlen(path) + 1);
write_jint(jint(type));
}
@@ -67,11 +67,29 @@
}
bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
- ClassLoader::trace_class_path(tty, msg, name);
+ ClassLoader::trace_class_path(msg, name);
MetaspaceShared::set_archive_loading_failed();
return false;
}
+void SharedPathsMiscInfo::print_path(int type, const char* path) {
+ ResourceMark rm;
+ outputStream* out = LogHandle(classpath)::info_stream();
+ switch (type) {
+ case BOOT:
+ out->print("Expecting -Dsun.boot.class.path=%s", path);
+ break;
+ case NON_EXIST:
+ out->print("Expecting that %s does not exist", path);
+ break;
+ case REQUIRED:
+ out->print("Expecting that file %s must exist and is not altered", path);
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+}
+
bool SharedPathsMiscInfo::check() {
// The whole buffer must be 0 terminated so that we can use strlen and strcmp
// without fear.
@@ -90,17 +108,14 @@
if (!read_jint(&type)) {
return fail("Corrupted archive file header");
}
- if (TraceClassPaths) {
- tty->print("[type=%s ", type_name(type));
- print_path(tty, type, path);
- tty->print_cr("]");
- }
+ log_info(classpath)("type=%s ", type_name(type));
+ print_path(type, path);
if (!check(type, path)) {
if (!PrintSharedArchiveAndExit) {
return false;
}
} else {
- trace_class_path("[ok");
+ ClassLoader::trace_class_path("ok");
}
}
--- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -64,9 +64,6 @@
void write(const void* ptr, size_t size);
bool read(void* ptr, size_t size);
- static void trace_class_path(const char* msg, const char* name = NULL) {
- ClassLoader::trace_class_path(tty, msg, name);
- }
protected:
static bool fail(const char* msg, const char* name = NULL);
virtual bool check(jint type, const char* path);
@@ -144,21 +141,7 @@
}
}
- virtual void print_path(outputStream* out, int type, const char* path) {
- switch (type) {
- case BOOT:
- out->print("Expecting -Dsun.boot.class.path=%s", path);
- break;
- case NON_EXIST:
- out->print("Expecting that %s does not exist", path);
- break;
- case REQUIRED:
- out->print("Expecting that file %s must exist and is not altered", path);
- break;
- default:
- ShouldNotReachHere();
- }
- }
+ virtual void print_path(int type, const char* path);
bool check();
bool read_jint(jint *ptr) {
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -430,12 +430,15 @@
// Now we have to call back to java to check if the initating class has access
JavaValue result(T_VOID);
- if (TraceProtectionDomainVerification) {
+ if (log_is_enabled(Debug, protectiondomain)) {
+ ResourceMark rm;
// Print out trace information
- tty->print_cr("Checking package access");
- tty->print(" - class loader: "); class_loader()->print_value_on(tty); tty->cr();
- tty->print(" - protection domain: "); protection_domain()->print_value_on(tty); tty->cr();
- tty->print(" - loading: "); klass()->print_value_on(tty); tty->cr();
+ outputStream* log = LogHandle(protectiondomain)::debug_stream();
+ log->print_cr("Checking package access");
+ log->print("class loader: "); class_loader()->print_value_on(log);
+ log->print(" protection domain: "); protection_domain()->print_value_on(log);
+ log->print(" loading: "); klass()->print_value_on(log);
+ log->cr();
}
KlassHandle system_loader(THREAD, SystemDictionary::ClassLoader_klass());
@@ -448,13 +451,10 @@
protection_domain,
THREAD);
- if (TraceProtectionDomainVerification) {
- if (HAS_PENDING_EXCEPTION) {
- tty->print_cr(" -> DENIED !!!!!!!!!!!!!!!!!!!!!");
- } else {
- tty->print_cr(" -> granted");
- }
- tty->cr();
+ if (HAS_PENDING_EXCEPTION) {
+ log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!");
+ } else {
+ log_debug(protectiondomain)("granted");
}
if (HAS_PENDING_EXCEPTION) return;
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -328,8 +328,6 @@
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
switch(id) {
#ifdef TRACE_HAVE_INTRINSICS
- case vmIntrinsics::_classID:
- case vmIntrinsics::_threadID:
case vmIntrinsics::_counterTime:
#endif
case vmIntrinsics::_currentTimeMillis:
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -615,7 +615,7 @@
: DefNewGeneration(rs, initial_byte_size, "PCopy"),
_overflow_list(NULL),
_is_alive_closure(this),
- _plab_stats(YoungPLABSize, PLABWeight)
+ _plab_stats("Young", YoungPLABSize, PLABWeight)
{
NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
NOT_PRODUCT(_num_par_pushes = 0;)
@@ -1008,9 +1008,7 @@
from()->set_concurrent_iteration_safe_limit(from()->top());
to()->set_concurrent_iteration_safe_limit(to()->top());
- if (ResizePLAB) {
- plab_stats()->adjust_desired_plab_sz();
- }
+ plab_stats()->adjust_desired_plab_sz();
TASKQUEUE_STATS_ONLY(thread_state_set.print_termination_stats());
TASKQUEUE_STATS_ONLY(thread_state_set.print_taskqueue_stats());
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,19 +36,19 @@
{
// Ergonomically select initial concurrent refinement parameters
if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
- FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, (intx)ParallelGCThreads);
+ FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, ParallelGCThreads);
}
set_green_zone(G1ConcRefinementGreenZone);
if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3);
}
- set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone()));
+ set_yellow_zone(MAX2(G1ConcRefinementYellowZone, green_zone()));
if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
}
- set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone()));
+ set_red_zone(MAX2(G1ConcRefinementRedZone, yellow_zone()));
}
ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,11 +61,11 @@
* 2) green = 0. Means no caching. Can be a good way to minimize the
* amount of time spent updating rsets during a collection.
*/
- int _green_zone;
- int _yellow_zone;
- int _red_zone;
+ size_t _green_zone;
+ size_t _yellow_zone;
+ size_t _red_zone;
- int _thread_threshold_step;
+ size_t _thread_threshold_step;
// We delay the refinement of 'hot' cards using the hot card cache.
G1HotCardCache _hot_card_cache;
@@ -100,17 +100,17 @@
void print_worker_threads_on(outputStream* st) const;
- void set_green_zone(int x) { _green_zone = x; }
- void set_yellow_zone(int x) { _yellow_zone = x; }
- void set_red_zone(int x) { _red_zone = x; }
+ void set_green_zone(size_t x) { _green_zone = x; }
+ void set_yellow_zone(size_t x) { _yellow_zone = x; }
+ void set_red_zone(size_t x) { _red_zone = x; }
- int green_zone() const { return _green_zone; }
- int yellow_zone() const { return _yellow_zone; }
- int red_zone() const { return _red_zone; }
+ size_t green_zone() const { return _green_zone; }
+ size_t yellow_zone() const { return _yellow_zone; }
+ size_t red_zone() const { return _red_zone; }
uint worker_thread_num() const { return _n_worker_threads; }
- int thread_threshold_step() const { return _thread_threshold_step; }
+ size_t thread_threshold_step() const { return _thread_threshold_step; }
G1HotCardCache* hot_card_cache() { return &_hot_card_cache; }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -67,10 +67,12 @@
void ConcurrentG1RefineThread::initialize() {
// Current thread activation threshold
- _threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
- cg1r()->yellow_zone());
+ _threshold = MIN2(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
+ cg1r()->yellow_zone());
// A thread deactivates once the number of buffer reached a deactivation threshold
- _deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
+ _deactivation_threshold =
+ MAX2(_threshold - MIN2(_threshold, cg1r()->thread_threshold_step()),
+ cg1r()->green_zone());
}
void ConcurrentG1RefineThread::wait_for_completed_buffers() {
@@ -127,14 +129,14 @@
}
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- log_debug(gc, refine)("Activated %d, on threshold: %d, current: %d",
+ log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
_worker_id, _threshold, dcqs.completed_buffers_num());
{
SuspendibleThreadSetJoiner sts_join;
do {
- int curr_buffer_num = (int)dcqs.completed_buffers_num();
+ size_t curr_buffer_num = dcqs.completed_buffers_num();
// If the number of the buffers falls down into the yellow zone,
// that means that the transition period after the evacuation pause has ended.
if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
@@ -151,7 +153,7 @@
false /* during_pause */));
deactivate();
- log_debug(gc, refine)("Deactivated %d, off threshold: %d, current: %d",
+ log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
_worker_id, _deactivation_threshold,
dcqs.completed_buffers_num());
}
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,11 +53,11 @@
// The closure applied to completed log buffers.
CardTableEntryClosure* _refine_closure;
- int _thread_threshold_step;
+ size_t _thread_threshold_step;
// This thread activation threshold
- int _threshold;
+ size_t _threshold;
// This thread deactivation threshold
- int _deactivation_threshold;
+ size_t _deactivation_threshold;
void wait_for_completed_buffers();
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -207,22 +207,24 @@
}
-BufferNode* DirtyCardQueueSet::get_completed_buffer(int stop_at) {
+BufferNode* DirtyCardQueueSet::get_completed_buffer(size_t stop_at) {
BufferNode* nd = NULL;
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
- if ((int)_n_completed_buffers <= stop_at) {
+ if (_n_completed_buffers <= stop_at) {
_process_completed = false;
return NULL;
}
if (_completed_buffers_head != NULL) {
nd = _completed_buffers_head;
+ assert(_n_completed_buffers > 0, "Invariant");
_completed_buffers_head = nd->next();
- if (_completed_buffers_head == NULL)
+ _n_completed_buffers--;
+ if (_completed_buffers_head == NULL) {
+ assert(_n_completed_buffers == 0, "Invariant");
_completed_buffers_tail = NULL;
- _n_completed_buffers--;
- assert(_n_completed_buffers >= 0, "Invariant");
+ }
}
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
return nd;
@@ -230,7 +232,7 @@
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
uint worker_i,
- int stop_at,
+ size_t stop_at,
bool during_pause) {
assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
BufferNode* nd = get_completed_buffer(stop_at);
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -134,10 +134,10 @@
// is returned to the completed buffer set, and this call returns false.
bool apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
uint worker_i,
- int stop_at,
+ size_t stop_at,
bool during_pause);
- BufferNode* get_completed_buffer(int stop_at);
+ BufferNode* get_completed_buffer(size_t stop_at);
// Applies the current closure to all completed buffers,
// non-consumptively.
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1400,7 +1400,6 @@
JavaThread::dirty_card_queue_set().abandon_logs();
assert(dirty_card_queue_set().completed_buffers_num() == 0, "DCQS should be empty");
- _young_list->reset_sampled_info();
// At this point there should be no regions in the
// entire heap tagged as young.
assert(check_young_list_empty(true /* check_heap */),
@@ -1761,8 +1760,8 @@
_young_list(new YoungList(this)),
_gc_time_stamp(0),
_summary_bytes_used(0),
- _survivor_evac_stats(YoungPLABSize, PLABWeight),
- _old_evac_stats(OldPLABSize, PLABWeight),
+ _survivor_evac_stats("Young", YoungPLABSize, PLABWeight),
+ _old_evac_stats("Old", OldPLABSize, PLABWeight),
_expand_heap_after_alloc_failure(true),
_old_marking_cycles_started(0),
_old_marking_cycles_completed(0),
@@ -1985,8 +1984,8 @@
JavaThread::dirty_card_queue_set().initialize(_refine_cte_cl,
DirtyCardQ_CBL_mon,
DirtyCardQ_FL_lock,
- concurrent_g1_refine()->yellow_zone(),
- concurrent_g1_refine()->red_zone(),
+ (int)concurrent_g1_refine()->yellow_zone(),
+ (int)concurrent_g1_refine()->red_zone(),
Shared_DirtyCardQ_lock,
NULL, // fl_owner
true); // init_free_ids
@@ -3385,13 +3384,15 @@
g1_policy()->clear_collection_set();
+ record_obj_copy_mem_stats();
+ _survivor_evac_stats.adjust_desired_plab_sz();
+ _old_evac_stats.adjust_desired_plab_sz();
+
// Start a new incremental collection set for the next pause.
g1_policy()->start_incremental_cset_building();
clear_cset_fast_test();
- _young_list->reset_sampled_info();
-
// Don't check the whole heap at this point as the
// GC alloc regions from this pause have been tagged
// as survivors and moved on to the survivor list.
@@ -4398,6 +4399,8 @@
{ }
void work(uint worker_id) {
+ G1GCParPhaseTimesTracker x(_g1h->g1_policy()->phase_times(), G1GCPhaseTimes::PreserveCMReferents, worker_id);
+
ResourceMark rm;
HandleMark hm;
@@ -4461,13 +4464,8 @@
g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
}
-// Weak Reference processing during an evacuation pause (part 1).
-void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
- double ref_proc_start = os::elapsedTime();
-
- ReferenceProcessor* rp = _ref_processor_stw;
- assert(rp->discovery_enabled(), "should have been enabled");
-
+void G1CollectedHeap::preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states) {
+ double preserve_cm_referents_start = os::elapsedTime();
// Any reference objects, in the collection set, that were 'discovered'
// by the CM ref processor should have already been copied (either by
// applying the external root copy closure to the discovered lists, or
@@ -4495,9 +4493,18 @@
per_thread_states,
no_of_gc_workers,
_task_queues);
-
workers()->run_task(&keep_cm_referents);
+ g1_policy()->phase_times()->record_preserve_cm_referents_time_ms((os::elapsedTime() - preserve_cm_referents_start) * 1000.0);
+}
+
+// Weak Reference processing during an evacuation pause (part 1).
+void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
+ double ref_proc_start = os::elapsedTime();
+
+ ReferenceProcessor* rp = _ref_processor_stw;
+ assert(rp->discovery_enabled(), "should have been enabled");
+
// Closure to test whether a referent is alive.
G1STWIsAliveClosure is_alive(this);
@@ -4529,6 +4536,8 @@
NULL,
_gc_timer_stw);
} else {
+ uint no_of_gc_workers = workers()->active_workers();
+
// Parallel reference processing
assert(rp->num_q() == no_of_gc_workers, "sanity");
assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
@@ -4586,6 +4595,12 @@
g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
}
+void G1CollectedHeap::merge_per_thread_state_info(G1ParScanThreadStateSet* per_thread_states) {
+ double merge_pss_time_start = os::elapsedTime();
+ per_thread_states->flush();
+ g1_policy()->phase_times()->record_merge_pss_time_ms((os::elapsedTime() - merge_pss_time_start) * 1000.0);
+}
+
void G1CollectedHeap::pre_evacuate_collection_set() {
_expand_heap_after_alloc_failure = true;
_evacuation_failed = false;
@@ -4644,6 +4659,7 @@
// objects (and their reachable sub-graphs) that were
// not copied during the pause.
if (g1_policy()->should_process_references()) {
+ preserve_cm_referents(per_thread_states);
process_discovered_references(per_thread_states);
} else {
ref_processor_stw()->verify_no_references_recorded();
@@ -4687,12 +4703,7 @@
_allocator->release_gc_alloc_regions(evacuation_info);
- per_thread_states->flush();
-
- record_obj_copy_mem_stats();
-
- _survivor_evac_stats.adjust_desired_plab_sz();
- _old_evac_stats.adjust_desired_plab_sz();
+ merge_per_thread_state_info(per_thread_states);
// Reset and re-enable the hot card cache.
// Note the counts for the cards in the regions in the
@@ -5188,8 +5199,8 @@
bool success() { return _success; }
};
-bool G1CollectedHeap::check_young_list_empty(bool check_heap, bool check_sample) {
- bool ret = _young_list->check_list_empty(check_sample);
+bool G1CollectedHeap::check_young_list_empty(bool check_heap) {
+ bool ret = _young_list->check_list_empty();
if (check_heap) {
NoYoungRegionsClosure closure;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -511,6 +511,9 @@
// allocated block, or else "NULL".
HeapWord* expand_and_allocate(size_t word_size, AllocationContext_t context);
+ // Preserve any referents discovered by concurrent marking that have not yet been
+ // copied by the STW pause.
+ void preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states);
// Process any reference objects discovered during
// an incremental evacuation pause.
void process_discovered_references(G1ParScanThreadStateSet* per_thread_states);
@@ -519,6 +522,9 @@
// after processing.
void enqueue_discovered_references(G1ParScanThreadStateSet* per_thread_states);
+ // Merges the information gathered on a per-thread basis for all worker threads
+ // during GC into global variables.
+ void merge_per_thread_state_info(G1ParScanThreadStateSet* per_thread_states);
public:
WorkGang* workers() const { return _workers; }
@@ -1333,8 +1339,7 @@
return _young_list->check_list_well_formed();
}
- bool check_young_list_empty(bool check_heap,
- bool check_sample = true);
+ bool check_young_list_empty(bool check_heap);
// *** Stuff related to concurrent marking. It's not clear to me that so
// many of these need to be public.
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -787,10 +787,9 @@
return survivor_regions_evac_time;
}
-void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
+void G1CollectorPolicy::revise_young_list_target_length_if_necessary(size_t rs_lengths) {
guarantee( adaptive_young_list_length(), "should not call this otherwise" );
- size_t rs_lengths = _g1->young_list()->sampled_rs_lengths();
if (rs_lengths > _rs_lengths_prediction) {
// add 10% to avoid having to recalculate often
size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
@@ -1118,14 +1117,15 @@
_short_lived_surv_rate_group->start_adding_regions();
// Do that for any other surv rate groups
+ double scan_hcc_time_ms = ConcurrentG1Refine::hot_card_cache_enabled() ? average_time_ms(G1GCPhaseTimes::ScanHCC) : 0.0;
+
if (update_stats) {
double cost_per_card_ms = 0.0;
- double cost_scan_hcc = average_time_ms(G1GCPhaseTimes::ScanHCC);
if (_pending_cards > 0) {
- cost_per_card_ms = (average_time_ms(G1GCPhaseTimes::UpdateRS) - cost_scan_hcc) / (double) _pending_cards;
+ cost_per_card_ms = (average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms) / (double) _pending_cards;
_cost_per_card_ms_seq->add(cost_per_card_ms);
}
- _cost_scan_hcc_seq->add(cost_scan_hcc);
+ _cost_scan_hcc_seq->add(scan_hcc_time_ms);
double cost_per_entry_ms = 0.0;
if (cards_scanned > 10) {
@@ -1215,8 +1215,6 @@
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
- double scan_hcc_time_ms = average_time_ms(G1GCPhaseTimes::ScanHCC);
-
if (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",
@@ -1302,12 +1300,12 @@
const int k_gy = 3, k_gr = 6;
const double inc_k = 1.1, dec_k = 0.9;
- int g = cg1r->green_zone();
+ size_t g = cg1r->green_zone();
if (update_rs_time > goal_ms) {
- g = (int)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
+ g = (size_t)(g * dec_k); // Can become 0, that's OK. That would mean a mutator-only processing.
} else {
if (update_rs_time < goal_ms && update_rs_processed_buffers > g) {
- g = (int)MAX2(g * inc_k, g + 1.0);
+ g = (size_t)MAX2(g * inc_k, g + 1.0);
}
}
// Change the refinement threads params
@@ -1316,15 +1314,15 @@
cg1r->set_red_zone(g * k_gr);
cg1r->reinitialize_threads();
- int processing_threshold_delta = MAX2((int)(cg1r->green_zone() * _predictor.sigma()), 1);
- int processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
+ size_t processing_threshold_delta = MAX2<size_t>(cg1r->green_zone() * _predictor.sigma(), 1);
+ size_t processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
cg1r->yellow_zone());
// Change the barrier params
- dcqs.set_process_completed_threshold(processing_threshold);
- dcqs.set_max_completed_queue(cg1r->red_zone());
+ dcqs.set_process_completed_threshold((int)processing_threshold);
+ dcqs.set_max_completed_queue((int)cg1r->red_zone());
}
- int curr_queue_size = dcqs.completed_buffers_num();
+ size_t curr_queue_size = dcqs.completed_buffers_num();
if (curr_queue_size >= cg1r->yellow_zone()) {
dcqs.set_completed_queue_padding(curr_queue_size);
} else {
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -471,7 +471,7 @@
// Check the current value of the young list RSet lengths and
// compare it against the last prediction. If the current value is
// higher, recalculate the young list target length prediction.
- void revise_young_list_target_length_if_necessary();
+ void revise_young_list_target_length_if_necessary(size_t rs_lengths);
// This should be called after the heap is resized.
void record_new_heap_size(uint new_number_of_regions);
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1097,7 +1097,7 @@
reset_marking_state();
} else {
{
- GCTraceTime(Debug, gc) trace("GC Aggregate Data", g1h->gc_timer_cm());
+ GCTraceTime(Debug, gc) trace("Aggregate Data", g1h->gc_timer_cm());
// Aggregate the per-task counting data that we have accumulated
// while marking.
@@ -2018,7 +2018,7 @@
// Inner scope to exclude the cleaning of the string and symbol
// tables from the displayed time.
{
- GCTraceTime(Debug, gc) trace("GC Ref Proc", g1h->gc_timer_cm());
+ GCTraceTime(Debug, gc) trace("Reference Processing", g1h->gc_timer_cm());
ReferenceProcessor* rp = g1h->ref_processor_cm();
@@ -2271,7 +2271,7 @@
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
guarantee(has_overflown() ||
satb_mq_set.completed_buffers_num() == 0,
- "Invariant: has_overflown = %s, num buffers = %d",
+ "Invariant: has_overflown = %s, num buffers = " SIZE_FORMAT,
BOOL_TO_STR(has_overflown()),
satb_mq_set.completed_buffers_num());
@@ -2702,11 +2702,8 @@
};
static ReferenceProcessor* get_cm_oop_closure_ref_processor(G1CollectedHeap* g1h) {
- ReferenceProcessor* result = NULL;
- if (G1UseConcMarkReferenceProcessing) {
- result = g1h->ref_processor_cm();
- assert(result != NULL, "should not be NULL");
- }
+ ReferenceProcessor* result = g1h->ref_processor_cm();
+ assert(result != NULL, "CM reference processor should not be NULL");
return result;
}
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,15 +29,26 @@
#include "logging/log.hpp"
#include "trace/tracing.hpp"
+void G1EvacStats::log_plab_allocation() {
+ PLABStats::log_plab_allocation();
+ log_debug(gc, plab)("%s other allocation: "
+ "region end waste: " SIZE_FORMAT "B, "
+ "regions filled: %u, "
+ "direct allocated: " SIZE_FORMAT "B, "
+ "failure used: " SIZE_FORMAT "B, "
+ "failure wasted: " SIZE_FORMAT "B",
+ _description,
+ _region_end_waste * HeapWordSize,
+ _regions_filled,
+ _direct_allocated * HeapWordSize,
+ _failure_used * HeapWordSize,
+ _failure_waste * HeapWordSize);
+}
+
void G1EvacStats::adjust_desired_plab_sz() {
+ log_plab_allocation();
+
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;
@@ -107,18 +118,19 @@
// 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);
-
+ log_sizing(cur_plab_sz, plab_sz);
// Clear accumulators for next round.
reset();
}
+G1EvacStats::G1EvacStats(const char* description, size_t desired_plab_sz_, unsigned wt) :
+ PLABStats(description, desired_plab_sz_, wt),
+ _region_end_waste(0),
+ _regions_filled(0),
+ _direct_allocated(0),
+ _failure_used(0),
+ _failure_waste(0) {
+}
+
+
G1EvacStats::~G1EvacStats() { }
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,20 +51,15 @@
_failure_waste = 0;
}
+ virtual void log_plab_allocation();
+
public:
- G1EvacStats(size_t desired_plab_sz_, unsigned wt) : PLABStats(desired_plab_sz_, wt),
- _region_end_waste(0), _regions_filled(0), _direct_allocated(0),
- _failure_used(0), _failure_waste(0) {
- }
+ G1EvacStats(const char* description, size_t desired_plab_sz_, unsigned wt);
+
+ ~G1EvacStats();
virtual void adjust_desired_plab_sz();
- size_t allocated() const { return _allocated; }
- size_t wasted() const { return _wasted; }
- size_t unused() const { return _unused; }
- size_t used() const { return allocated() - (wasted() + unused()); }
- size_t undo_wasted() const { return _undo_wasted; }
-
uint regions_filled() const { return _regions_filled; }
size_t region_end_waste() const { return _region_end_waste; }
size_t direct_allocated() const { return _direct_allocated; }
@@ -77,8 +72,6 @@
inline void add_direct_allocated(size_t value);
inline void add_region_end_waste(size_t value);
inline void add_failure_used_and_waste(size_t used, size_t waste);
-
- ~G1EvacStats();
};
#endif // SHARE_VM_GC_G1_G1EVACSTATS_HPP
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,107 +28,70 @@
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/workerDataArray.inline.hpp"
-#include "memory/allocation.hpp"
+#include "memory/resourceArea.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp"
#include "runtime/os.hpp"
-// Helper class for avoiding interleaved logging
-class LineBuffer: public StackObj {
-
-private:
- static const int BUFFER_LEN = 1024;
- static const int INDENT_CHARS = 3;
- char _buffer[BUFFER_LEN];
- int _indent_level;
- int _cur;
-
- void vappend(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0) {
- int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
- if (res != -1) {
- _cur += res;
- } else {
- DEBUG_ONLY(warning("buffer too small in LineBuffer");)
- _buffer[BUFFER_LEN -1] = 0;
- _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
- }
- }
-
-public:
- explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
- for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
- _buffer[_cur] = ' ';
- }
- }
-
-#ifndef PRODUCT
- ~LineBuffer() {
- assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
- }
-#endif
-
- void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {
- va_list ap;
- va_start(ap, format);
- vappend(format, ap);
- va_end(ap);
- }
-
- const char* to_string() {
- _cur = _indent_level * INDENT_CHARS;
- return _buffer;
- }
-};
-
-static const char* Indents[4] = {"", " ", " ", " "};
+static const char* Indents[5] = {"", " ", " ", " ", " "};
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:", false, 2);
- _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning:", true, 2);
+ _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms):");
+ _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms):");
// Root scanning phases
- _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[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms):");
+ _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms):");
+ _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms):");
+ _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms):");
+ _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms):");
+ _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms):");
+ _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms):");
+ _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms):");
+ _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms):");
+ _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms):");
+ _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms):");
+ _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
+ _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
+ _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms):");
- _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:", 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);
+ _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms):");
+ if (ConcurrentG1Refine::hot_card_cache_enabled()) {
+ _gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC (ms):");
+ } else {
+ _gc_par_phases[ScanHCC] = NULL;
+ }
+ _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms):");
+ _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms):");
+ _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms):");
+ _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms):");
+ _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms):");
+ _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms):");
+ _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms):");
- _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:", true, 3);
+ _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:");
_gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers);
- _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts:", true, 3);
+ _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts:");
_gc_par_phases[Termination]->link_thread_work_items(_termination_attempts);
- _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);
+ if (UseStringDeduplication) {
+ _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms):");
+ _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms):");
+ } else {
+ _gc_par_phases[StringDedupQueueFixup] = NULL;
+ _gc_par_phases[StringDedupTableFixup] = NULL;
+ }
- _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] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty (ms):");
+ _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:");
_gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
+
+ _gc_par_phases[PreserveCMReferents] = new WorkerDataArray<double>(max_gc_threads, "Parallel Preserve CM Refs (ms):");
}
void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
@@ -140,11 +103,10 @@
_external_accounted_time_ms = 0.0;
for (int i = 0; i < GCParPhasesSentinel; i++) {
- _gc_par_phases[i]->reset();
+ if (_gc_par_phases[i] != NULL) {
+ _gc_par_phases[i]->reset();
+ }
}
-
- _gc_par_phases[StringDedupQueueFixup]->set_enabled(G1StringDedup::is_enabled());
- _gc_par_phases[StringDedupTableFixup]->set_enabled(G1StringDedup::is_enabled());
}
void G1GCPhaseTimes::note_gc_end() {
@@ -166,45 +128,12 @@
}
for (int i = 0; i < GCParPhasesSentinel; i++) {
- _gc_par_phases[i]->verify(_active_gc_threads);
+ if (_gc_par_phases[i] != NULL) {
+ _gc_par_phases[i]->verify(_active_gc_threads);
+ }
}
}
-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() {
- // First subtract any externally accounted time
- double misc_time_ms = _external_accounted_time_ms;
-
- // Subtract the root region scanning wait time. It's initialized to
- // zero at the start of the pause.
- misc_time_ms += _root_region_scan_wait_time_ms;
-
- misc_time_ms += _cur_collection_par_time_ms;
-
- // Now subtract the time taken to fix up roots in generated code
- misc_time_ms += _cur_collection_code_root_fixup_time_ms;
-
- // Strong code root purge time
- misc_time_ms += _cur_strong_code_root_purge_time_ms;
-
- if (G1StringDedup::is_enabled()) {
- // String dedup fixup time
- misc_time_ms += _cur_string_dedup_fixup_time_ms;
- }
-
- // Subtract the time taken to clean the card table from the
- // current value of "other time"
- misc_time_ms += _cur_clear_ct_time_ms;
-
- // Remove expand heap time from "other time"
- misc_time_ms += _cur_expand_heap_time_ms;
-
- return misc_time_ms;
-}
-
// record the time a phase took in seconds
void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) {
_gc_par_phases[phase]->set(worker_i, secs);
@@ -224,193 +153,144 @@
return _gc_par_phases[phase]->average(_active_gc_threads) * 1000.0;
}
-double G1GCPhaseTimes::get_time_ms(GCParPhases phase, uint worker_i) {
- return _gc_par_phases[phase]->get(worker_i) * 1000.0;
-}
-
-double G1GCPhaseTimes::sum_time_ms(GCParPhases phase) {
- return _gc_par_phases[phase]->sum(_active_gc_threads) * 1000.0;
-}
-
-double G1GCPhaseTimes::min_time_ms(GCParPhases phase) {
- return _gc_par_phases[phase]->minimum(_active_gc_threads) * 1000.0;
-}
-
-double G1GCPhaseTimes::max_time_ms(GCParPhases phase) {
- return _gc_par_phases[phase]->maximum(_active_gc_threads) * 1000.0;
-}
-
-size_t G1GCPhaseTimes::get_thread_work_item(GCParPhases phase, uint worker_i) {
- assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
- return _gc_par_phases[phase]->thread_work_items()->get(worker_i);
-}
-
size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) {
assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
return _gc_par_phases[phase]->thread_work_items()->sum(_active_gc_threads);
}
-double G1GCPhaseTimes::average_thread_work_items(GCParPhases phase) {
- assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
- return _gc_par_phases[phase]->thread_work_items()->average(_active_gc_threads);
+template <class T>
+void G1GCPhaseTimes::details(T* phase, const char* indent) {
+ LogHandle(gc, phases, task) log;
+ if (log.is_level(LogLevel::Trace)) {
+ outputStream* trace_out = log.trace_stream();
+ trace_out->print("%s", indent);
+ phase->print_details_on(trace_out, _active_gc_threads);
+ }
}
-size_t G1GCPhaseTimes::min_thread_work_items(GCParPhases phase) {
- assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
- return _gc_par_phases[phase]->thread_work_items()->minimum(_active_gc_threads);
-}
+void G1GCPhaseTimes::log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) {
+ out->print("%s", Indents[indent]);
+ phase->print_summary_on(out, _active_gc_threads, print_sum);
+ details(phase, Indents[indent]);
-size_t G1GCPhaseTimes::max_thread_work_items(GCParPhases phase) {
- assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
- return _gc_par_phases[phase]->thread_work_items()->maximum(_active_gc_threads);
+ WorkerDataArray<size_t>* work_items = phase->thread_work_items();
+ if (work_items != NULL) {
+ out->print("%s", Indents[indent + 1]);
+ work_items->print_summary_on(out, _active_gc_threads, true);
+ details(work_items, Indents[indent + 1]);
+ }
}
-class G1GCParPhasePrinter : public StackObj {
- G1GCPhaseTimes* _phase_times;
- public:
- G1GCParPhasePrinter(G1GCPhaseTimes* phase_times) : _phase_times(phase_times) {}
-
- void print(G1GCPhaseTimes::GCParPhases phase_id) {
- WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id];
-
- if (phase->_length == 1) {
- print_single_length(phase_id, phase);
- } else {
- print_multi_length(phase_id, phase);
- }
+void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase) {
+ LogHandle(gc, phases) log;
+ if (log.is_level(LogLevel::Debug)) {
+ ResourceMark rm;
+ log_phase(phase, 2, log.debug_stream(), true);
}
-
+}
- private:
- void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
- // No need for min, max, average and sum for only one worker
- log_debug(gc, phases)("%s%s: %.1lf", Indents[phase->_indent_level], phase->_title, _phase_times->get_time_ms(phase_id, 0));
-
- 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 G1GCPhaseTimes::trace_phase(WorkerDataArray<double>* phase, bool print_sum) {
+ LogHandle(gc, phases) log;
+ if (log.is_level(LogLevel::Trace)) {
+ ResourceMark rm;
+ log_phase(phase, 3, log.trace_stream(), print_sum);
}
+}
- 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);
- }
- }
+#define PHASE_DOUBLE_FORMAT "%s%s: %.1lfms"
+#define PHASE_SIZE_FORMAT "%s%s: " SIZE_FORMAT
- 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);
- }
- }
+#define info_line(str, value) \
+ log_info(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[1], str, value);
- void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* 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);
+#define debug_line(str, value) \
+ log_debug(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[2], str, value);
- 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));
+#define trace_line(str, value) \
+ log_trace(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[3], str, value);
- print_count_values(indent, phase_id, thread_work_items);
- }
-
- void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
- const char* indent = Indents[phase->_indent_level];
+#define trace_line_sz(str, value) \
+ log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value);
- 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));
- }
+#define trace_line_ms(str, value) \
+ log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value);
- print_time_values(indent, phase_id);
-
- if (phase->_thread_work_items != NULL) {
- print_thread_work_items(phase_id, phase->_thread_work_items);
- }
- }
-};
+#define info_line_and_account(str, value) \
+ info_line(str, value); \
+ accounted_time_ms += value;
void G1GCPhaseTimes::print() {
note_gc_end();
- G1GCParPhasePrinter par_phase_printer(this);
-
+ double accounted_time_ms = _external_accounted_time_ms;
if (_root_region_scan_wait_time_ms > 0.0) {
- print_stats(Indents[1], "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
- }
-
- print_stats(Indents[1], "Parallel Time", _cur_collection_par_time_ms);
- for (int i = 0; i <= GCMainParPhasesLast; i++) {
- par_phase_printer.print((GCParPhases) i);
+ info_line_and_account("Root Region Scan Waiting", _root_region_scan_wait_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);
+ info_line_and_account("Evacuate Collection Set", _cur_collection_par_time_ms);
+ trace_phase(_gc_par_phases[GCWorkerStart], false);
+ debug_phase(_gc_par_phases[ExtRootScan]);
+ for (int i = ThreadRoots; i <= SATBFiltering; i++) {
+ trace_phase(_gc_par_phases[i]);
+ }
+ debug_phase(_gc_par_phases[UpdateRS]);
+ if (ConcurrentG1Refine::hot_card_cache_enabled()) {
+ trace_phase(_gc_par_phases[ScanHCC]);
+ }
+ debug_phase(_gc_par_phases[ScanRS]);
+ debug_phase(_gc_par_phases[CodeRoots]);
+ debug_phase(_gc_par_phases[ObjCopy]);
+ debug_phase(_gc_par_phases[Termination]);
+ debug_phase(_gc_par_phases[Other]);
+ debug_phase(_gc_par_phases[GCWorkerTotal]);
+ trace_phase(_gc_par_phases[GCWorkerEnd], false);
+
+ info_line_and_account("Code Roots", _cur_collection_code_root_fixup_time_ms + _cur_strong_code_root_purge_time_ms);
+ debug_line("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms);
+ debug_line("Code Roots Purge", _cur_strong_code_root_purge_time_ms);
+
if (G1StringDedup::is_enabled()) {
- 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);
- }
+ info_line_and_account("String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
+ debug_phase(_gc_par_phases[StringDedupQueueFixup]);
+ debug_phase(_gc_par_phases[StringDedupTableFixup]);
}
- 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 = _gc_pause_time_ms - accounted_time_ms();
- print_stats(Indents[1], "Other", misc_time_ms);
+ info_line_and_account("Clear Card Table", _cur_clear_ct_time_ms);
+ info_line_and_account("Expand Heap After Collection", _cur_expand_heap_time_ms);
+
+ double free_cset_time = _recorded_young_free_cset_time_ms + _recorded_non_young_free_cset_time_ms;
+ info_line_and_account("Free Collection Set", free_cset_time);
+ debug_line("Young Free Collection Set", _recorded_young_free_cset_time_ms);
+ debug_line("Non-Young Free Collection Set", _recorded_non_young_free_cset_time_ms);
+ info_line_and_account("Merge Per-Thread State", _recorded_merge_pss_time_ms);
+
+ info_line("Other", _gc_pause_time_ms - accounted_time_ms);
if (_cur_verify_before_time_ms > 0.0) {
- print_stats(Indents[2], "Verify Before", _cur_verify_before_time_ms);
+ debug_line("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(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);
+ debug_line("Evacuation Failure", evac_fail_handling);
+ trace_line("Recalculate Used", _cur_evac_fail_recalc_used);
+ trace_line("Remove Self Forwards",_cur_evac_fail_remove_self_forwards);
+ trace_line("Restore RemSet", _cur_evac_fail_restore_remsets);
}
- print_stats(Indents[2], "Choose CSet",
- (_recorded_young_cset_choice_time_ms +
- _recorded_non_young_cset_choice_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);
+ debug_line("Choose CSet", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms));
+ debug_line("Preserve CM Refs", _recorded_preserve_cm_referents_time_ms);
+ debug_line("Reference Processing", _cur_ref_proc_time_ms);
+ debug_line("Reference Enqueuing", _cur_ref_enq_time_ms);
+ debug_line("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
+ trace_phase(_gc_par_phases[RedirtyCards]);
+ trace_phase(_gc_par_phases[PreserveCMReferents]);
if (G1EagerReclaimHumongousObjects) {
- 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);
+ debug_line("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
+ trace_line_sz("Humongous Total", _cur_fast_reclaim_humongous_total);
+ trace_line_sz("Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
+ debug_line("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
+ trace_line_sz("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
}
- print_stats(Indents[2], "Free CSet",
- (_recorded_young_free_cset_time_ms +
- _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(Indents[2], "Verify After", _cur_verify_after_time_ms);
+ debug_line("Verify After", _cur_verify_after_time_ms);
}
}
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,6 @@
template <class T> class WorkerDataArray;
class G1GCPhaseTimes : public CHeapObj<mtGC> {
- friend class G1GCParPhasePrinter;
-
uint _active_gc_threads;
uint _max_gc_threads;
jlong _gc_start_counter;
@@ -69,6 +67,7 @@
StringDedupQueueFixup,
StringDedupTableFixup,
RedirtyCards,
+ PreserveCMReferents,
GCParPhasesSentinel
};
@@ -108,6 +107,10 @@
double _recorded_redirty_logged_cards_time_ms;
+ double _recorded_preserve_cm_referents_time_ms;
+
+ double _recorded_merge_pss_time_ms;
+
double _recorded_young_free_cset_time_ms;
double _recorded_non_young_free_cset_time_ms;
@@ -120,10 +123,13 @@
double _cur_verify_before_time_ms;
double _cur_verify_after_time_ms;
- // Helper methods for detailed logging
- void print_stats(const char*, const char* str, double value);
+ void note_gc_end();
- void note_gc_end();
+ template <class T>
+ void details(T* phase, const char* indent);
+ void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum);
+ void debug_phase(WorkerDataArray<double>* phase);
+ void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true);
public:
G1GCPhaseTimes(uint max_gc_threads);
@@ -143,16 +149,6 @@
size_t sum_thread_work_items(GCParPhases phase);
- private:
- double get_time_ms(GCParPhases phase, uint worker_i);
- double sum_time_ms(GCParPhases phase);
- double min_time_ms(GCParPhases phase);
- double max_time_ms(GCParPhases phase);
- size_t get_thread_work_item(GCParPhases phase, uint worker_i);
- double average_thread_work_items(GCParPhases phase);
- size_t min_thread_work_items(GCParPhases phase);
- size_t max_thread_work_items(GCParPhases phase);
-
public:
void record_clear_ct_time(double ms) {
@@ -234,6 +230,14 @@
_recorded_redirty_logged_cards_time_ms = time_ms;
}
+ void record_preserve_cm_referents_time_ms(double time_ms) {
+ _recorded_preserve_cm_referents_time_ms = time_ms;
+ }
+
+ void record_merge_pss_time_ms(double time_ms) {
+ _recorded_merge_pss_time_ms = time_ms;
+ }
+
void record_cur_collection_start_sec(double time_ms) {
_cur_collection_start_sec = time_ms;
}
@@ -250,8 +254,6 @@
_external_accounted_time_ms += time_ms;
}
- double accounted_time_ms();
-
double cur_collection_start_sec() {
return _cur_collection_start_sec;
}
--- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -81,10 +81,7 @@
}
void G1HotCardCache::drain(CardTableEntryClosure* cl, uint worker_i) {
- if (!default_use_cache()) {
- assert(_hot_cache == NULL, "Logic");
- return;
- }
+ assert(default_use_cache(), "Drain only necessary if we use the hot card cache.");
assert(_hot_cache != NULL, "Logic");
assert(!use_cache(), "cache should be disabled");
--- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,14 +47,16 @@
void G1IHOPControl::print() {
size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold();
- 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",
+ 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 allocation size: " SIZE_FORMAT "B, recent allocation duration: %1.2fms, recent old gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms",
cur_conc_mark_start_threshold,
cur_conc_mark_start_threshold * 100.0 / _target_occupancy,
_target_occupancy,
G1CollectedHeap::heap()->used(),
+ _last_allocated_bytes,
+ _last_allocation_time_s * 1000.0,
_last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
- last_marking_length_s());
+ last_marking_length_s() * 1000.0);
}
void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
@@ -191,13 +193,16 @@
void G1AdaptiveIHOPControl::print() {
G1IHOPControl::print();
size_t actual_target = actual_target_threshold();
- 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",
+ log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: " SIZE_FORMAT "B (%1.2f), internal target occupancy: " SIZE_FORMAT "B, "
+ "occupancy: " SIZE_FORMAT "B, additional buffer size: " SIZE_FORMAT "B, predicted old gen allocation rate: %1.2fB/s, "
+ "predicted marking phase length: %1.2fms, prediction active: %s",
get_conc_mark_start_threshold(),
percent_of(get_conc_mark_start_threshold(), actual_target),
actual_target,
+ G1CollectedHeap::heap()->used(),
+ _last_unrestrained_young_size,
_predictor->get_new_prediction(&_allocation_rate_s),
- _predictor->get_new_prediction(&_marking_times_s),
+ _predictor->get_new_prediction(&_marking_times_s) * 1000.0,
have_enough_data_for_prediction() ? "true" : "false");
}
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -327,6 +327,9 @@
G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) {
assert(worker_id < _n_workers, "out of bounds access");
+ if (_states[worker_id] == NULL) {
+ _states[worker_id] = new_par_scan_state(worker_id, _young_cset_length);
+ }
return _states[worker_id];
}
@@ -352,6 +355,10 @@
for (uint worker_index = 0; worker_index < _n_workers; ++worker_index) {
G1ParScanThreadState* pss = _states[worker_index];
+ if (pss == NULL) {
+ continue;
+ }
+
_total_cards_scanned += _cards_scanned[worker_index];
pss->flush(_surviving_young_words_total);
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -200,6 +200,7 @@
size_t* _surviving_young_words_total;
size_t* _cards_scanned;
size_t _total_cards_scanned;
+ size_t _young_cset_length;
uint _n_workers;
bool _flushed;
@@ -210,10 +211,11 @@
_surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
_cards_scanned(NEW_C_HEAP_ARRAY(size_t, n_workers, mtGC)),
_total_cards_scanned(0),
+ _young_cset_length(young_cset_length),
_n_workers(n_workers),
_flushed(false) {
for (uint i = 0; i < n_workers; ++i) {
- _states[i] = new_par_scan_state(i, young_cset_length);
+ _states[i] = NULL;
}
memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
memset(_cards_scanned, 0, n_workers * sizeof(size_t));
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -238,7 +238,7 @@
RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
- {
+ if (ConcurrentG1Refine::hot_card_cache_enabled()) {
// Apply the closure to the entries of the hot card cache.
G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
_g1->iterate_hcc_closure(&into_cset_update_rs_cl, worker_i);
@@ -291,7 +291,6 @@
_g1->cleanUpCardTable();
DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
- int into_cset_n_buffers = into_cset_dcqs.completed_buffers_num();
if (_g1->evacuation_failed()) {
double restore_remembered_set_start = os::elapsedTime();
--- a/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -26,6 +26,8 @@
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/suspendibleThreadSet.hpp"
#include "runtime/mutexLocker.hpp"
@@ -55,21 +57,21 @@
}
}
-G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() : ConcurrentGCThread() {
- _monitor = new Monitor(Mutex::nonleaf,
- "G1YoungRemSetSamplingThread monitor",
- true,
- Monitor::_safepoint_check_never);
-
+G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() :
+ ConcurrentGCThread(),
+ _monitor(Mutex::nonleaf,
+ "G1YoungRemSetSamplingThread monitor",
+ true,
+ Monitor::_safepoint_check_never) {
set_name("G1 Young RemSet Sampling");
create_and_start();
}
void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
- MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
if (!_should_terminate) {
- intx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
- _monitor->wait(Mutex::_no_safepoint_check_flag, waitms);
+ uintx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
+ _monitor.wait(Mutex::_no_safepoint_check_flag, waitms);
}
}
@@ -90,8 +92,8 @@
}
void G1YoungRemSetSamplingThread::stop_service() {
- MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
- _monitor->notify();
+ MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
+ _monitor.notify();
}
void G1YoungRemSetSamplingThread::sample_young_list_rs_lengths() {
@@ -100,22 +102,35 @@
G1CollectorPolicy* g1p = g1h->g1_policy();
if (g1p->adaptive_young_list_length()) {
int regions_visited = 0;
- g1h->young_list()->rs_length_sampling_init();
- while (g1h->young_list()->rs_length_sampling_more()) {
- g1h->young_list()->rs_length_sampling_next();
+ HeapRegion* hr = g1h->young_list()->first_region();
+ size_t sampled_rs_lengths = 0;
+
+ while (hr != NULL) {
+ size_t rs_length = hr->rem_set()->occupied();
+ sampled_rs_lengths += rs_length;
+
+ // The current region may not yet have been added to the
+ // incremental collection set (it gets added when it is
+ // retired as the current allocation region).
+ if (hr->in_collection_set()) {
+ // Update the collection set policy information for this region
+ g1p->update_incremental_cset_info(hr, rs_length);
+ }
+
++regions_visited;
// we try to yield every time we visit 10 regions
if (regions_visited == 10) {
if (sts.should_yield()) {
sts.yield();
- // we just abandon the iteration
- break;
+ // A gc may have occurred and our sampling data is stale and further
+ // traversal of the young list is unsafe
+ return;
}
regions_visited = 0;
}
+ hr = hr->get_next_young_region();
}
-
- g1p->revise_young_list_target_length_if_necessary();
+ g1p->revise_young_list_target_length_if_necessary(sampled_rs_lengths);
}
}
--- a/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
// increase the young gen size to keep pause time length goal.
class G1YoungRemSetSamplingThread: public ConcurrentGCThread {
private:
- Monitor* _monitor;
+ Monitor _monitor;
void sample_young_list_rs_lengths();
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,10 +71,6 @@
"draining concurrent marking work queues.") \
range(1, max_intx) \
\
- experimental(bool, G1UseConcMarkReferenceProcessing, true, \
- "If true, enable reference discovery during concurrent " \
- "marking and reference processing at the end of remark.") \
- \
experimental(double, G1LastPLABAverageOccupancy, 50.0, \
"The expected average occupancy of the last PLAB in " \
"percent.") \
@@ -107,35 +103,35 @@
"Size of an update buffer") \
range(1, NOT_LP64(32*M) LP64_ONLY(1*G)) \
\
- product(intx, G1ConcRefinementYellowZone, 0, \
+ product(size_t, G1ConcRefinementYellowZone, 0, \
"Number of enqueued update buffers that will " \
"trigger concurrent processing. Will be selected ergonomically " \
"by default.") \
range(0, max_intx) \
\
- product(intx, G1ConcRefinementRedZone, 0, \
+ product(size_t, G1ConcRefinementRedZone, 0, \
"Maximum number of enqueued update buffers before mutator " \
"threads start processing new ones instead of enqueueing them. " \
"Will be selected ergonomically by default. Zero will disable " \
"concurrent processing.") \
range(0, max_intx) \
\
- product(intx, G1ConcRefinementGreenZone, 0, \
+ product(size_t, G1ConcRefinementGreenZone, 0, \
"The number of update buffers that are left in the queue by the " \
"concurrent processing threads. Will be selected ergonomically " \
"by default.") \
range(0, max_intx) \
\
- product(intx, G1ConcRefinementServiceIntervalMillis, 300, \
+ product(uintx, G1ConcRefinementServiceIntervalMillis, 300, \
"The last concurrent refinement thread wakes up every " \
"specified number of milliseconds to do miscellaneous work.") \
range(0, max_jint) \
\
- product(intx, G1ConcRefinementThresholdStep, 0, \
+ product(size_t, G1ConcRefinementThresholdStep, 0, \
"Each time the rset update queue increases by this amount " \
"activate the next refinement thread if available. " \
"Will be selected ergonomically by default.") \
- range(0, max_jint) \
+ range(0, SIZE_MAX) \
\
product(intx, G1RSetUpdatingPauseTimePercent, 10, \
"A target percentage of time that is allowed to be spend on " \
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -781,7 +781,9 @@
ResourceMark rm;
_containing_obj->print_on(log.error_stream());
log.error("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
- obj->print_on(log.error_stream());
+ if (obj->is_oop()) {
+ obj->print_on(log.error_stream());
+ }
log.error("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field);
log.error("----------");
_failures = true;
--- a/hotspot/src/share/vm/gc/g1/ptrQueue.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/ptrQueue.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,8 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.inline.hpp"
+#include <new>
+
PtrQueue::PtrQueue(PtrQueueSet* qset, bool permanent, bool active) :
_qset(qset), _buf(NULL), _index(0), _sz(0), _active(active),
_permanent(permanent), _lock(NULL)
@@ -87,6 +89,19 @@
}
+BufferNode* BufferNode::allocate(size_t byte_size) {
+ assert(byte_size > 0, "precondition");
+ assert(is_size_aligned(byte_size, sizeof(void**)),
+ "Invalid buffer size " SIZE_FORMAT, byte_size);
+ void* data = NEW_C_HEAP_ARRAY(char, buffer_offset() + byte_size, mtGC);
+ return new (data) BufferNode;
+}
+
+void BufferNode::deallocate(BufferNode* node) {
+ node->~BufferNode();
+ FREE_C_HEAP_ARRAY(char, node);
+}
+
PtrQueueSet::PtrQueueSet(bool notify_when_complete) :
_max_completed_queue(0),
_cbl_mon(NULL), _fl_lock(NULL),
@@ -123,17 +138,23 @@
void** PtrQueueSet::allocate_buffer() {
assert(_sz > 0, "Didn't set a buffer size.");
- MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
- if (_fl_owner->_buf_free_list != NULL) {
- void** res = BufferNode::make_buffer_from_node(_fl_owner->_buf_free_list);
- _fl_owner->_buf_free_list = _fl_owner->_buf_free_list->next();
- _fl_owner->_buf_free_list_sz--;
- return res;
+ BufferNode* node = NULL;
+ {
+ MutexLockerEx x(_fl_owner->_fl_lock, Mutex::_no_safepoint_check_flag);
+ node = _fl_owner->_buf_free_list;
+ if (node != NULL) {
+ _fl_owner->_buf_free_list = node->next();
+ _fl_owner->_buf_free_list_sz--;
+ }
+ }
+ if (node == NULL) {
+ node = BufferNode::allocate(_sz);
} else {
- // Allocate space for the BufferNode in front of the buffer.
- char *b = NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size(), mtGC);
- return BufferNode::make_buffer_from_block(b);
+ // Reinitialize buffer obtained from free list.
+ node->set_index(0);
+ node->set_next(NULL);
}
+ return BufferNode::make_buffer_from_node(node);
}
void PtrQueueSet::deallocate_buffer(void** buf) {
@@ -150,13 +171,13 @@
// For now we'll adopt the strategy of deleting half.
MutexLockerEx x(_fl_lock, Mutex::_no_safepoint_check_flag);
size_t n = _buf_free_list_sz / 2;
- while (n > 0) {
- assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
- void* b = BufferNode::make_block_from_node(_buf_free_list);
- _buf_free_list = _buf_free_list->next();
- FREE_C_HEAP_ARRAY(char, b);
- _buf_free_list_sz --;
- n--;
+ for (size_t i = 0; i < n; ++i) {
+ assert(_buf_free_list != NULL,
+ "_buf_free_list_sz is wrong: " SIZE_FORMAT, _buf_free_list_sz);
+ BufferNode* node = _buf_free_list;
+ _buf_free_list = node->next();
+ _buf_free_list_sz--;
+ BufferNode::deallocate(node);
}
}
@@ -236,8 +257,9 @@
void PtrQueueSet::enqueue_complete_buffer(void** buf, size_t index) {
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
- BufferNode* cbn = BufferNode::new_from_buffer(buf);
+ BufferNode* cbn = BufferNode::make_node_from_buffer(buf);
cbn->set_index(index);
+ cbn->set_next(NULL);
if (_completed_buffers_tail == NULL) {
assert(_completed_buffers_head == NULL, "Well-formedness");
_completed_buffers_head = cbn;
@@ -249,16 +271,17 @@
_n_completed_buffers++;
if (!_process_completed && _process_completed_threshold >= 0 &&
- _n_completed_buffers >= _process_completed_threshold) {
+ _n_completed_buffers >= (size_t)_process_completed_threshold) {
_process_completed = true;
- if (_notify_when_complete)
+ if (_notify_when_complete) {
_cbl_mon->notify();
+ }
}
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
}
-int PtrQueueSet::completed_buffers_list_length() {
- int n = 0;
+size_t PtrQueueSet::completed_buffers_list_length() {
+ size_t n = 0;
BufferNode* cbn = _completed_buffers_head;
while (cbn != NULL) {
n++;
@@ -312,7 +335,8 @@
void PtrQueueSet::notify_if_necessary() {
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
- if (_n_completed_buffers >= _process_completed_threshold || _max_completed_queue == 0) {
+ assert(_process_completed_threshold >= 0, "_process_completed is negative");
+ if (_n_completed_buffers >= (size_t)_process_completed_threshold || _max_completed_queue == 0) {
_process_completed = true;
if (_notify_when_complete)
_cbl_mon->notify();
--- a/hotspot/src/share/vm/gc/g1/ptrQueue.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/ptrQueue.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,6 @@
// the addresses of modified old-generation objects. This type supports
// this operation.
-// The definition of placement operator new(size_t, void*) in the <new>.
-#include <new>
-
class PtrQueueSet;
class PtrQueue VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
@@ -168,42 +165,38 @@
class BufferNode {
size_t _index;
BufferNode* _next;
+ void* _buffer[1]; // Pseudo flexible array member.
+
+ BufferNode() : _index(0), _next(NULL) { }
+ ~BufferNode() { }
+
+ static size_t buffer_offset() {
+ return offset_of(BufferNode, _buffer);
+ }
+
public:
- BufferNode() : _index(0), _next(NULL) { }
BufferNode* next() const { return _next; }
void set_next(BufferNode* n) { _next = n; }
size_t index() const { return _index; }
void set_index(size_t i) { _index = i; }
- // Align the size of the structure to the size of the pointer
- static size_t aligned_size() {
- static const size_t alignment = round_to(sizeof(BufferNode), sizeof(void*));
- return alignment;
- }
+ // Allocate a new BufferNode with the "buffer" having size bytes.
+ static BufferNode* allocate(size_t byte_size);
- // BufferNode is allocated before the buffer.
- // The chunk of memory that holds both of them is a block.
+ // Free a BufferNode.
+ static void deallocate(BufferNode* node);
- // Produce a new BufferNode given a buffer.
- static BufferNode* new_from_buffer(void** buf) {
- return new (make_block_from_buffer(buf)) BufferNode;
+ // Return the BufferNode containing the buffer.
+ static BufferNode* make_node_from_buffer(void** buffer) {
+ return reinterpret_cast<BufferNode*>(
+ reinterpret_cast<char*>(buffer) - buffer_offset());
}
- // The following are the required conversion routines:
- static BufferNode* make_node_from_buffer(void** buf) {
- return (BufferNode*)make_block_from_buffer(buf);
- }
+ // Return the buffer for node.
static void** make_buffer_from_node(BufferNode *node) {
- return make_buffer_from_block(node);
- }
- static void* make_block_from_node(BufferNode *node) {
- return (void*)node;
- }
- static void** make_buffer_from_block(void* p) {
- return (void**)((char*)p + aligned_size());
- }
- static void* make_block_from_buffer(void** p) {
- return (void*)((char*)p - aligned_size());
+ // &_buffer[0] might lead to index out of bounds warnings.
+ return reinterpret_cast<void**>(
+ reinterpret_cast<char*>(node) + buffer_offset());
}
};
@@ -216,7 +209,7 @@
Monitor* _cbl_mon; // Protects the fields below.
BufferNode* _completed_buffers_head;
BufferNode* _completed_buffers_tail;
- int _n_completed_buffers;
+ size_t _n_completed_buffers;
int _process_completed_threshold;
volatile bool _process_completed;
@@ -240,9 +233,9 @@
// Maximum number of elements allowed on completed queue: after that,
// enqueuer does the work itself. Zero indicates no maximum.
int _max_completed_queue;
- int _completed_queue_padding;
+ size_t _completed_queue_padding;
- int completed_buffers_list_length();
+ size_t completed_buffers_list_length();
void assert_completed_buffer_list_len_correct_locked();
void assert_completed_buffer_list_len_correct();
@@ -306,15 +299,15 @@
// list size may be reduced, if that is deemed desirable.
void reduce_free_list();
- int completed_buffers_num() { return _n_completed_buffers; }
+ size_t completed_buffers_num() { return _n_completed_buffers; }
void merge_bufferlists(PtrQueueSet* src);
void set_max_completed_queue(int m) { _max_completed_queue = m; }
int max_completed_queue() { return _max_completed_queue; }
- void set_completed_queue_padding(int padding) { _completed_queue_padding = padding; }
- int completed_queue_padding() { return _completed_queue_padding; }
+ void set_completed_queue_padding(size_t padding) { _completed_queue_padding = padding; }
+ size_t completed_queue_padding() { return _completed_queue_padding; }
// Notify the consumer if the number of buffers crossed the threshold
void notify_if_necessary();
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -24,18 +24,53 @@
#include "precompiled.hpp"
#include "gc/g1/workerDataArray.inline.hpp"
+#include "utilities/ostream.hpp"
+
+template <>
+void WorkerDataArray<double>::WDAPrinter::summary(outputStream* out, const char* title, double min, double avg, double max, double diff, double sum, bool print_sum) {
+ out->print("%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf", title, min * MILLIUNITS, avg * MILLIUNITS, max * MILLIUNITS, diff* MILLIUNITS);
+ if (print_sum) {
+ out->print_cr(", Sum: %4.1lf", sum * MILLIUNITS);
+ } else {
+ out->cr();
+ }
+}
+
+template <>
+void WorkerDataArray<size_t>::WDAPrinter::summary(outputStream* out, const char* title, size_t min, double avg, size_t max, size_t diff, size_t sum, bool print_sum) {
+ out->print("%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT, title, min, avg, max, diff);
+ if (print_sum) {
+ out->print_cr(", Sum: " SIZE_FORMAT, sum);
+ } else {
+ out->cr();
+ }
+}
+
+template <>
+void WorkerDataArray<double>::WDAPrinter::details(const WorkerDataArray<double>* phase, outputStream* out, uint active_threads) {
+ out->print("%-25s", "");
+ for (uint i = 0; i < active_threads; ++i) {
+ out->print(" %4.1lf", phase->get(i) * 1000.0);
+ }
+ out->cr();
+}
+
+template <>
+void WorkerDataArray<size_t>::WDAPrinter::details(const WorkerDataArray<size_t>* phase, outputStream* out, uint active_threads) {
+ out->print("%-25s", "");
+ for (uint i = 0; i < active_threads; ++i) {
+ out->print(" " SIZE_FORMAT, phase->get(i));
+ }
+ out->cr();
+}
#ifndef PRODUCT
void WorkerDataArray_test() {
const uint length = 3;
const char* title = "Test array";
- const bool print_sum = false;
- const uint indent_level = 2;
- WorkerDataArray<size_t> array(length, title, print_sum, indent_level);
+ WorkerDataArray<size_t> array(length, title);
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.indentation() == indent_level, "Expected indentation to match");
const size_t expected[length] = {5, 3, 7};
for (uint i = 0; i < length; i++) {
@@ -46,10 +81,7 @@
}
assert(array.sum(length) == (5 + 3 + 7), "Expected sums to match");
- assert(array.minimum(length) == 3, "Expected mininum to match");
- assert(array.maximum(length) == 7, "Expected maximum to match");
- assert(array.diff(length) == (7 - 3), "Expected diffs to match");
- assert(array.average(length) == 5, "Expected averages to match");
+ assert(array.average(length) == 5.0, "Expected averages to match");
for (uint i = 0; i < length; i++) {
array.add(i, 1);
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -22,18 +22,19 @@
*
*/
+#ifndef SHARE_VM_GC_G1_WORKERDATAARRAY_HPP
+#define SHARE_VM_GC_G1_WORKERDATAARRAY_HPP
+
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
+class outputStream;
+
template <class T>
class WorkerDataArray : public CHeapObj<mtGC> {
- friend class G1GCParPhasePrinter;
T* _data;
uint _length;
const char* _title;
- bool _print_sum;
- uint _indent_level;
- bool _enabled;
WorkerDataArray<size_t>* _thread_work_items;
@@ -42,11 +43,7 @@
void set_all(T value);
public:
- WorkerDataArray(uint length,
- const char* title,
- bool print_sum,
- uint indent_level);
-
+ WorkerDataArray(uint length, const char* title);
~WorkerDataArray();
void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items);
@@ -62,27 +59,30 @@
double average(uint active_threads) const;
T sum(uint active_threads) const;
- T minimum(uint active_threads) const;
- T maximum(uint active_threads) const;
- T diff(uint active_threads) const;
-
- uint indentation() const {
- return _indent_level;
- }
const char* title() const {
return _title;
}
- bool should_print_sum() const {
- return _print_sum;
- }
-
void clear();
- void set_enabled(bool enabled) {
- _enabled = enabled;
- }
void reset() PRODUCT_RETURN;
void verify(uint active_threads) const PRODUCT_RETURN;
+
+
+ private:
+ class WDAPrinter {
+ public:
+ static void summary(outputStream* out, const char* title, double min, double avg, double max, double diff, double sum, bool print_sum);
+ static void summary(outputStream* out, const char* title, size_t min, double avg, size_t max, size_t diff, size_t sum, bool print_sum);
+
+ static void details(const WorkerDataArray<double>* phase, outputStream* out, uint active_threads);
+ static void details(const WorkerDataArray<size_t>* phase, outputStream* out, uint active_threads);
+ };
+
+ public:
+ void print_summary_on(outputStream* out, uint active_threads, bool print_sum = true) const;
+ void print_details_on(outputStream* out, uint active_threads) const;
};
+
+#endif // SHARE_VM_GC_G1_WORKERDATAARRAY_HPP
--- a/hotspot/src/share/vm/gc/g1/workerDataArray.inline.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.inline.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -22,20 +22,18 @@
*
*/
+#ifndef SHARE_VM_GC_G1_WORKERDATAARRAY_INLINE_HPP
+#define SHARE_VM_GC_G1_WORKERDATAARRAY_INLINE_HPP
+
#include "gc/g1/workerDataArray.hpp"
#include "memory/allocation.inline.hpp"
+#include "utilities/ostream.hpp"
template <typename T>
-WorkerDataArray<T>::WorkerDataArray(uint length,
- const char* title,
- bool print_sum,
- uint indent_level) :
+WorkerDataArray<T>::WorkerDataArray(uint length, const char* title) :
_title(title),
_length(0),
- _print_sum(print_sum),
- _indent_level(indent_level),
- _thread_work_items(NULL),
- _enabled(true) {
+ _thread_work_items(NULL) {
assert(length > 0, "Must have some workers to store data for");
_length = length;
_data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
@@ -94,29 +92,6 @@
}
template <typename T>
-T WorkerDataArray<T>::minimum(uint active_threads) const {
- T min = get(0);
- for (uint i = 1; i < active_threads; ++i) {
- min = MIN2(min, get(i));
- }
- return min;
-}
-
-template <typename T>
-T WorkerDataArray<T>::maximum(uint active_threads) const {
- T max = get(0);
- for (uint i = 1; i < active_threads; ++i) {
- max = MAX2(max, get(i));
- }
- return max;
-}
-
-template <typename T>
-T WorkerDataArray<T>::diff(uint active_threads) const {
- return maximum(active_threads) - minimum(active_threads);
-}
-
-template <typename T>
void WorkerDataArray<T>::clear() {
set_all(0);
}
@@ -128,6 +103,27 @@
}
}
+template <class T>
+void WorkerDataArray<T>::print_summary_on(outputStream* out, uint active_threads, bool print_sum) const {
+ T max = get(0);
+ T min = max;
+ T sum = 0;
+ for (uint i = 1; i < active_threads; ++i) {
+ T value = get(i);
+ max = MAX2(max, value);
+ min = MIN2(min, value);
+ sum += value;
+ }
+ T diff = max - min;
+ double avg = sum / (double) active_threads;
+ WDAPrinter::summary(out, title(), min, avg, max, diff, sum, print_sum);
+}
+
+template <class T>
+void WorkerDataArray<T>::print_details_on(outputStream* out, uint active_threads) const {
+ WDAPrinter::details(this, out, active_threads);
+}
+
#ifndef PRODUCT
template <typename T>
void WorkerDataArray<T>::reset() {
@@ -139,10 +135,6 @@
template <typename T>
void WorkerDataArray<T>::verify(uint active_threads) const {
- if (!_enabled) {
- return;
- }
-
assert(active_threads <= _length, "Wrong number of active threads");
for (uint i = 0; i < active_threads; i++) {
assert(_data[i] != uninitialized(),
@@ -163,3 +155,5 @@
return -1.0;
}
#endif
+
+#endif // SHARE_VM_GC_G1_WORKERDATAARRAY_INLINE_HPP
--- a/hotspot/src/share/vm/gc/g1/youngList.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/youngList.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -33,9 +33,9 @@
#include "utilities/ostream.hpp"
YoungList::YoungList(G1CollectedHeap* g1h) :
- _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0),
+ _g1h(g1h), _head(NULL), _length(0),
_survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
- guarantee(check_list_empty(false), "just making sure...");
+ guarantee(check_list_empty(), "just making sure...");
}
void YoungList::push_region(HeapRegion *hr) {
@@ -86,9 +86,7 @@
_survivor_tail = NULL;
_survivor_length = 0;
- _last_sampled_rs_lengths = 0;
-
- assert(check_list_empty(false), "just making sure...");
+ assert(check_list_empty(), "just making sure...");
}
bool YoungList::check_list_well_formed() {
@@ -119,17 +117,13 @@
return ret;
}
-bool YoungList::check_list_empty(bool check_sample) {
+bool YoungList::check_list_empty() {
bool ret = true;
if (_length != 0) {
log_error(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
ret = false;
}
- if (check_sample && _last_sampled_rs_lengths != 0) {
- log_error(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
- ret = false;
- }
if (_head != NULL) {
log_error(gc, verify)("### YOUNG LIST does not have a NULL head");
ret = false;
@@ -142,38 +136,6 @@
}
void
-YoungList::rs_length_sampling_init() {
- _sampled_rs_lengths = 0;
- _curr = _head;
-}
-
-bool
-YoungList::rs_length_sampling_more() {
- return _curr != NULL;
-}
-
-void
-YoungList::rs_length_sampling_next() {
- assert( _curr != NULL, "invariant" );
- size_t rs_length = _curr->rem_set()->occupied();
-
- _sampled_rs_lengths += rs_length;
-
- // The current region may not yet have been added to the
- // incremental collection set (it gets added when it is
- // retired as the current allocation region).
- if (_curr->in_collection_set()) {
- // Update the collection set policy information for this region
- _g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length);
- }
-
- _curr = _curr->get_next_young_region();
- if (_curr == NULL) {
- _last_sampled_rs_lengths = _sampled_rs_lengths;
- }
-}
-
-void
YoungList::reset_auxilary_lists() {
guarantee( is_empty(), "young list should be empty" );
assert(check_list_well_formed(), "young list should be well formed");
--- a/hotspot/src/share/vm/gc/g1/youngList.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/youngList.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -37,14 +37,9 @@
HeapRegion* _survivor_head;
HeapRegion* _survivor_tail;
- HeapRegion* _curr;
-
uint _length;
uint _survivor_length;
- size_t _last_sampled_rs_lengths;
- size_t _sampled_rs_lengths;
-
void empty_list(HeapRegion* list);
public:
@@ -72,15 +67,6 @@
return (size_t) survivor_length() * HeapRegion::GrainBytes;
}
- void rs_length_sampling_init();
- bool rs_length_sampling_more();
- void rs_length_sampling_next();
-
- void reset_sampled_info() {
- _last_sampled_rs_lengths = 0;
- }
- size_t sampled_rs_lengths() { return _last_sampled_rs_lengths; }
-
// for development purposes
void reset_auxilary_lists();
void clear() { _head = NULL; _length = 0; }
@@ -97,7 +83,7 @@
// debugging
bool check_list_well_formed();
- bool check_list_empty(bool check_sample = true);
+ bool check_list_empty();
void print();
};
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -405,7 +405,9 @@
oop CollectedHeap::new_store_pre_barrier(JavaThread* thread, oop new_obj) {
// If a previous card-mark was deferred, flush it now.
flush_deferred_store_barrier(thread);
- if (can_elide_initializing_store_barrier(new_obj)) {
+ if (can_elide_initializing_store_barrier(new_obj) ||
+ new_obj->is_typeArray()) {
+ // Arrays of non-references don't need a pre-barrier.
// The deferred_card_mark region should be empty
// following the flush above.
assert(thread->deferred_card_mark().is_empty(), "Error");
--- a/hotspot/src/share/vm/gc/shared/copyFailedInfo.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/copyFailedInfo.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_SHARED_COPYFAILEDINFO_HPP
#include "runtime/thread.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/globalDefinitions.hpp"
class CopyFailedInfo : public CHeapObj<mtGC> {
@@ -63,26 +64,28 @@
};
class PromotionFailedInfo : public CopyFailedInfo {
- OSThread* _thread;
+ traceid _thread_trace_id;
public:
- PromotionFailedInfo() : CopyFailedInfo(), _thread(NULL) {}
+ PromotionFailedInfo() : CopyFailedInfo(), _thread_trace_id(0) {}
void register_copy_failure(size_t size) {
CopyFailedInfo::register_copy_failure(size);
- if (_thread == NULL) {
- _thread = Thread::current()->osthread();
+ if (_thread_trace_id == 0) {
+ _thread_trace_id = THREAD_TRACE_ID(Thread::current());
} else {
- assert(_thread == Thread::current()->osthread(), "The PromotionFailedInfo should be thread local.");
+ assert(THREAD_TRACE_ID(Thread::current()) == _thread_trace_id,
+ "The PromotionFailedInfo should be thread local.");
}
}
void reset() {
CopyFailedInfo::reset();
- _thread = NULL;
+ _thread_trace_id = 0;
}
- OSThread* thread() const { return _thread; }
+ traceid thread_trace_id() const { return _thread_trace_id; }
+
};
class EvacuationFailedInfo : public CopyFailedInfo {};
--- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -174,7 +174,7 @@
if (e.should_commit()) {
e.set_gcId(GCId::current());
e.set_data(to_trace_struct(pf_info));
- e.set_thread(pf_info.thread()->thread_id());
+ e.set_thread(pf_info.thread_trace_id());
e.commit();
}
}
--- a/hotspot/src/share/vm/gc/shared/plab.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/plab.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -110,6 +110,30 @@
}
}
+void PLABStats::log_plab_allocation() {
+ log_debug(gc, plab)("%s PLAB allocation: "
+ "allocated: " SIZE_FORMAT "B, "
+ "wasted: " SIZE_FORMAT "B, "
+ "unused: " SIZE_FORMAT "B, "
+ "used: " SIZE_FORMAT "B, "
+ "undo waste: " SIZE_FORMAT "B, ",
+ _description,
+ _allocated * HeapWordSize,
+ _wasted * HeapWordSize,
+ _unused * HeapWordSize,
+ used() * HeapWordSize,
+ _undo_wasted * HeapWordSize);
+}
+
+void PLABStats::log_sizing(size_t calculated_words, size_t net_desired_words) {
+ log_debug(gc, plab)("%s sizing: "
+ "calculated: " SIZE_FORMAT "B, "
+ "actual: " SIZE_FORMAT "B",
+ _description,
+ calculated_words * HeapWordSize,
+ net_desired_words * HeapWordSize);
+}
+
// Calculates plab size for current number of gc worker threads.
size_t PLABStats::desired_plab_sz(uint no_of_gc_workers) {
return MAX2(min_size(), (size_t)align_object_size(_desired_net_plab_sz / no_of_gc_workers));
@@ -119,7 +143,13 @@
// use. This should be called once at the end of parallel
// scavenge; it clears the sensor accumulators.
void PLABStats::adjust_desired_plab_sz() {
- assert(ResizePLAB, "Not set");
+ log_plab_allocation();
+
+ if (!ResizePLAB) {
+ // Clear accumulators for next round.
+ reset();
+ return;
+ }
assert(is_object_aligned(max_size()) && min_size() <= max_size(),
"PLAB clipping computation may be incorrect");
@@ -150,8 +180,9 @@
new_plab_sz = MIN2(max_size(), new_plab_sz);
new_plab_sz = align_object_size(new_plab_sz);
// Latch the result
- 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;
+ log_sizing(recent_plab_sz, new_plab_sz);
+
reset();
}
--- a/hotspot/src/share/vm/gc/shared/plab.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/gc/shared/plab.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -146,6 +146,8 @@
// PLAB book-keeping.
class PLABStats : public CHeapObj<mtGC> {
protected:
+ const char* _description; // Identifying string.
+
size_t _allocated; // Total allocated
size_t _wasted; // of which wasted (internal fragmentation)
size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size)
@@ -160,8 +162,12 @@
_undo_wasted = 0;
_unused = 0;
}
+
+ virtual void log_plab_allocation();
+ virtual void log_sizing(size_t calculated, size_t net_desired);
public:
- PLABStats(size_t desired_net_plab_sz_, unsigned wt) :
+ PLABStats(const char* description, size_t desired_net_plab_sz_, unsigned wt) :
+ _description(description),
_allocated(0),
_wasted(0),
_undo_wasted(0),
@@ -172,6 +178,12 @@
virtual ~PLABStats() { }
+ size_t allocated() const { return _allocated; }
+ size_t wasted() const { return _wasted; }
+ size_t unused() const { return _unused; }
+ size_t used() const { return allocated() - (wasted() + unused()); }
+ size_t undo_wasted() const { return _undo_wasted; }
+
static const size_t min_size() {
return PLAB::min_size();
}
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -762,14 +762,6 @@
ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
if (cp_cache_entry->is_resolved(bytecode)) return;
- if (bytecode == Bytecodes::_invokeinterface) {
- if (log_develop_is_enabled(Trace, itables)) {
- ResourceMark rm(thread);
- log_develop_trace(itables)("Resolving: klass: %s to method: %s",
- info.resolved_klass()->name()->as_C_string(),
- info.resolved_method()->name()->as_C_string());
- }
- }
#ifdef ASSERT
if (bytecode == Bytecodes::_invokeinterface) {
if (info.resolved_method()->method_holder() ==
--- a/hotspot/src/share/vm/logging/logPrefix.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -58,6 +58,7 @@
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, phases, task)) \
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)) \
--- a/hotspot/src/share/vm/logging/logTag.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/logging/logTag.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -43,6 +43,7 @@
LOG_TAG(classload) /* Trace all classes loaded */ \
LOG_TAG(classloaderdata) /* class loader loader_data lifetime */ \
LOG_TAG(classunload) /* Trace unloading of classes */ \
+ LOG_TAG(classpath) \
LOG_TAG(compaction) \
LOG_TAG(cpu) \
LOG_TAG(cset) \
@@ -66,6 +67,7 @@
LOG_TAG(phases) \
LOG_TAG(plab) \
LOG_TAG(promotion) \
+ LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \
LOG_TAG(ref) \
LOG_TAG(refine) \
LOG_TAG(region) \
@@ -81,6 +83,7 @@
LOG_TAG(survivor) \
LOG_TAG(sweep) \
LOG_TAG(task) \
+ LOG_TAG(thread) \
LOG_TAG(tlab) \
LOG_TAG(time) \
LOG_TAG(verify) \
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/memory/filemap.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -208,9 +208,7 @@
count ++;
bytes += (int)entry_size;
bytes += name_bytes;
- if (TraceClassPaths) {
- tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name);
- }
+ log_info(classpath)("add main shared path (%s) %s", (cpe->is_jar_file() ? "jar" : "dir"), name);
} else {
SharedClassPathEntry* ent = shared_classpath(cur_entry);
if (cpe->is_jar_file()) {
@@ -275,9 +273,7 @@
struct stat st;
const char* name = ent->_name;
bool ok = true;
- if (TraceClassPaths) {
- tty->print_cr("[Checking shared classpath entry: %s]", name);
- }
+ log_info(classpath)("checking shared classpath entry: %s", name);
if (os::stat(name, &st) != 0) {
fail_continue("Required classpath entry does not exist: %s", name);
ok = false;
@@ -301,9 +297,7 @@
}
}
if (ok) {
- if (TraceClassPaths) {
- tty->print_cr("[ok]");
- }
+ log_info(classpath)("ok");
} else if (!PrintSharedArchiveAndExit) {
_validating_classpath_entry_table = false;
return false;
@@ -888,10 +882,8 @@
char header_version[JVM_IDENT_MAX];
get_header_version(header_version);
if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
- if (TraceClassPaths) {
- tty->print_cr("Expected: %s", header_version);
- tty->print_cr("Actual: %s", _jvm_ident);
- }
+ log_info(classpath)("expected: %s", header_version);
+ log_info(classpath)("actual: %s", _jvm_ident);
FileMapInfo::fail_continue("The shared archive file was created by a different"
" version or build of HotSpot");
return false;
@@ -919,7 +911,7 @@
if (status) {
if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) {
if (!PrintSharedArchiveAndExit) {
- fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)");
+ fail_continue("shared class paths mismatch (hint: enable -Xlog:classpath=info to diagnose the failure)");
status = false;
}
}
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -89,7 +89,7 @@
set_super(Universe::is_bootstrapping() ? (Klass*)NULL : SystemDictionary::Object_klass());
set_layout_helper(Klass::_lh_neutral_value);
set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5)
- TRACE_INIT_ID(this);
+ TRACE_INIT_KLASS_ID(this);
}
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -839,7 +839,7 @@
// support for stub routines
static ByteSize init_state_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_state)); }
- TRACE_DEFINE_OFFSET;
+ TRACE_DEFINE_KLASS_TRACE_ID_OFFSET;
static ByteSize init_thread_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_thread)); }
// subclass/subinterface checks
--- a/hotspot/src/share/vm/oops/klass.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/oops/klass.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -494,7 +494,7 @@
}
void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
- TRACE_INIT_ID(this);
+ TRACE_INIT_KLASS_ID(this);
// If an exception happened during CDS restore, some of these fields may already be
// set. We leave the class on the CLD list, even if incomplete so that we don't
// modify the CLD list outside a safepoint.
--- a/hotspot/src/share/vm/oops/klass.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/oops/klass.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -132,7 +132,7 @@
jint _modifier_flags; // Processed access flags, for use by Class.getModifiers.
AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here.
- TRACE_DEFINE_KLASS_TRACE_ID;
+ TRACE_DEFINE_TRACE_ID_FIELD;
// Biased locking implementation and statistics
// (the 64-bit chunk goes first, to avoid some fragmentation)
@@ -569,7 +569,7 @@
jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; }
void set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; }
- TRACE_DEFINE_KLASS_METHODS;
+ TRACE_DEFINE_TRACE_ID_METHODS;
// garbage collection support
void oops_do(OopClosure* cl);
--- a/hotspot/src/share/vm/oops/typeArrayOop.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/oops/typeArrayOop.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -129,7 +129,7 @@
Metadata* metadata_at(int which) const {
return (Metadata*)*long_at_addr(which); }
void metadata_at_put(int which, Metadata* contents) {
- *long_at_addr(which) = (long)contents;
+ *long_at_addr(which) = (jlong)contents;
}
#else
Metadata* metadata_at(int which) const {
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -493,8 +493,6 @@
case vmIntrinsics::_currentThread:
case vmIntrinsics::_isInterrupted:
#ifdef TRACE_HAVE_INTRINSICS
- case vmIntrinsics::_classID:
- case vmIntrinsics::_threadID:
case vmIntrinsics::_counterTime:
#endif
case vmIntrinsics::_currentTimeMillis:
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/opto/library_call.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -49,7 +49,9 @@
#include "opto/subnode.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/sharedRuntime.hpp"
+#ifdef TRACE_HAVE_INTRINSICS
#include "trace/traceMacros.hpp"
+#endif
class LibraryIntrinsic : public InlineCallGenerator {
// Extend the set of intrinsics known to the runtime:
@@ -248,10 +250,7 @@
bool inline_unsafe_allocate();
bool inline_unsafe_copyMemory();
bool inline_native_currentThread();
-#ifdef TRACE_HAVE_INTRINSICS
- bool inline_native_classID();
- bool inline_native_threadID();
-#endif
+
bool inline_native_time_funcs(address method, const char* funcName);
bool inline_native_isInterrupted();
bool inline_native_Class_query(vmIntrinsics::ID id);
@@ -706,8 +705,6 @@
case vmIntrinsics::_isInterrupted: return inline_native_isInterrupted();
#ifdef TRACE_HAVE_INTRINSICS
- case vmIntrinsics::_classID: return inline_native_classID();
- case vmIntrinsics::_threadID: return inline_native_threadID();
case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
#endif
case vmIntrinsics::_currentTimeMillis: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
@@ -3184,52 +3181,6 @@
return true;
}
-#ifdef TRACE_HAVE_INTRINSICS
-/*
- * oop -> myklass
- * myklass->trace_id |= USED
- * return myklass->trace_id & ~0x3
- */
-bool LibraryCallKit::inline_native_classID() {
- null_check_receiver(); // null-check, then ignore
- Node* cls = null_check(argument(1), T_OBJECT);
- Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
- kls = null_check(kls, T_OBJECT);
- ByteSize offset = TRACE_ID_OFFSET;
- Node* insp = basic_plus_adr(kls, in_bytes(offset));
- Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
- Node* bits = longcon(~0x03l); // ignore bit 0 & 1
- Node* andl = _gvn.transform(new AndLNode(tvalue, bits));
- Node* clsused = longcon(0x01l); // set the class bit
- Node* orl = _gvn.transform(new OrLNode(tvalue, clsused));
-
- const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
- store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered);
- set_result(andl);
- return true;
-}
-
-bool LibraryCallKit::inline_native_threadID() {
- Node* tls_ptr = NULL;
- Node* cur_thr = generate_current_thread(tls_ptr);
- Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
- Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
- p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::thread_id_offset()));
-
- Node* threadid = NULL;
- size_t thread_id_size = OSThread::thread_id_size();
- if (thread_id_size == (size_t) BytesPerLong) {
- threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG, MemNode::unordered));
- } else if (thread_id_size == (size_t) BytesPerInt) {
- threadid = make_load(control(), p, TypeInt::INT, T_INT, MemNode::unordered);
- } else {
- ShouldNotReachHere();
- }
- set_result(threadid);
- return true;
-}
-#endif
-
//------------------------inline_native_time_funcs--------------
// inline code for System.currentTimeMillis() and System.nanoTime()
// these have the same type and signature
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/prims/jni.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -73,6 +73,7 @@
#include "runtime/vm_operations.hpp"
#include "services/memTracker.hpp"
#include "services/runtimeService.hpp"
+#include "trace/traceMacros.hpp"
#include "trace/tracing.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
@@ -88,7 +89,7 @@
#include "jvmci/jvmciRuntime.hpp"
#endif
-static jint CurrentVersion = JNI_VERSION_1_8;
+static jint CurrentVersion = JNI_VERSION_9;
#ifdef _WIN32
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
@@ -3929,7 +3930,7 @@
EventThreadStart event;
if (event.should_commit()) {
- event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.set_thread(THREAD_TRACE_ID(thread));
event.commit();
}
@@ -4149,7 +4150,7 @@
EventThreadStart event;
if (event.should_commit()) {
- event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.set_thread(THREAD_TRACE_ID(thread));
event.commit();
}
--- a/hotspot/src/share/vm/prims/jni.h Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/prims/jni.h Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1952,6 +1952,7 @@
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006
#define JNI_VERSION_1_8 0x00010008
+#define JNI_VERSION_9 0x00090000
#ifdef __cplusplus
} /* extern "C" */
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3940,6 +3940,10 @@
scratch_class->set_methods(_old_methods); // To prevent potential GCing of the old methods,
// and to be able to undo operation easily.
+ Array<int>* old_ordering = the_class->method_ordering();
+ the_class->set_method_ordering(scratch_class->method_ordering());
+ scratch_class->set_method_ordering(old_ordering);
+
ConstantPool* old_constants = the_class->constants();
the_class->set_constants(scratch_class->constants());
scratch_class->set_constants(old_constants); // See the previous comment.
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -372,6 +372,7 @@
{ "PreInflateSpin", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "JNIDetachReleasesMonitors", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "UseAltSigs", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "SegmentedHeapDumpThreshold", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -405,8 +406,9 @@
static AliasedLoggingFlag const aliased_logging_flags[] = {
{ "TraceClassLoading", LogLevel::Info, true, LogTag::_classload },
+ { "TraceClassPaths", LogLevel::Info, true, LogTag::_classpath },
+ { "TraceClassResolution", LogLevel::Info, true, LogTag::_classresolve },
{ "TraceClassUnloading", LogLevel::Info, true, LogTag::_classunload },
- { "TraceClassResolution", LogLevel::Info, true, LogTag::_classresolve },
{ "TraceExceptions", LogLevel::Info, true, LogTag::_exceptions },
{ "TraceMonitorInflation", LogLevel::Debug, true, LogTag::_monitorinflation },
{ "TraceBiasedLocking", LogLevel::Info, true, LogTag::_biasedlocking },
@@ -3269,7 +3271,7 @@
// PrintSharedArchiveAndExit will turn on
// -Xshare:on
- // -XX:+TraceClassPaths
+ // -Xlog:classpath=info
if (PrintSharedArchiveAndExit) {
if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
return JNI_EINVAL;
@@ -3277,9 +3279,7 @@
if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
return JNI_EINVAL;
}
- if (FLAG_SET_CMDLINE(bool, TraceClassPaths, true) != Flag::SUCCESS) {
- return JNI_EINVAL;
- }
+ LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(classpath));
}
// Change the default value for flags which have different default values
@@ -3332,10 +3332,6 @@
_java_class_path->set_value(copy);
FreeHeap(copy); // a copy was made by set_value, so don't need this anymore
}
-
- if (!PrintSharedArchiveAndExit) {
- ClassLoader::trace_class_path(tty, "[classpath: ", _java_class_path->value());
- }
}
static bool has_jar_files(const char* directory) {
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -836,8 +836,7 @@
vm_thread_profiler->inc_thread_ticks();
// Get a snapshot of a current VMThread pc (and leave it running!)
- // The call may fail if, for instance the VM thread is interrupted while
- // holding the Interrupt_lock or for other reasons.
+ // The call may fail in some circumstances
epc = os::get_thread_pc(VMThread::vm_thread());
if(epc.pc() != NULL) {
if (os::dll_address_to_function_name(epc.pc(), buf, sizeof(buf), NULL)) {
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1055,10 +1055,6 @@
"directory) of the dump file (defaults to java_pid<pid>.hprof " \
"in the working directory)") \
\
- develop(size_t, SegmentedHeapDumpThreshold, 2*G, \
- "Generate a segmented heap dump (JAVA PROFILE 1.0.2 format) " \
- "when the heap usage is larger than this") \
- \
develop(size_t, HeapDumpSegmentSize, 1*G, \
"Approximate segment size when generating a segmented heap dump") \
\
@@ -1437,9 +1433,6 @@
product(bool, VerifyMergedCPBytecodes, true, \
"Verify bytecodes after RedefineClasses constant pool merging") \
\
- develop(bool, TraceJNIHandleAllocation, false, \
- "Trace allocation/deallocation of JNI handle blocks") \
- \
develop(bool, TraceBytecodes, false, \
"Trace bytecode execution") \
\
@@ -1482,9 +1475,6 @@
develop(bool, TraceCompiledIC, false, \
"Trace changes of compiled IC") \
\
- develop(bool, TraceProtectionDomainVerification, false, \
- "Trace protection domain verification") \
- \
develop(bool, TraceClearedExceptions, false, \
"Print when an exception is forcibly cleared") \
\
@@ -2403,9 +2393,6 @@
product(bool, IgnoreEmptyClassPaths, false, \
"Ignore empty path elements in -classpath") \
\
- product(bool, TraceClassPaths, false, \
- "Trace processing of class paths") \
- \
product(bool, TraceClassLoadingPreorder, false, \
"Trace all classes loaded in order referenced (not loaded)") \
\
--- a/hotspot/src/share/vm/runtime/java.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/java.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -64,6 +64,7 @@
#include "runtime/timer.hpp"
#include "runtime/vm_operations.hpp"
#include "services/memTracker.hpp"
+#include "trace/traceMacros.hpp"
#include "trace/tracing.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -485,7 +486,7 @@
EventThreadEnd event;
if (event.should_commit()) {
- event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.set_thread(THREAD_TRACE_ID(thread));
event.commit();
}
--- a/hotspot/src/share/vm/runtime/jniHandles.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/jniHandles.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -278,10 +278,6 @@
// Allocate new block
block = new JNIHandleBlock();
_blocks_allocated++;
- if (TraceJNIHandleAllocation) {
- tty->print_cr("JNIHandleBlock " INTPTR_FORMAT " allocated (%d total blocks)",
- p2i(block), _blocks_allocated);
- }
if (ZapJNIHandleArea) block->zap();
#ifndef PRODUCT
// Link new block to list of all allocated blocks
@@ -499,10 +495,6 @@
// Not as many free handles as we would like - compute number of new blocks to append
_allocate_before_rebuild = (extra + block_size_in_oops - 1) / block_size_in_oops;
}
- if (TraceJNIHandleAllocation) {
- tty->print_cr("Rebuild free list JNIHandleBlock " INTPTR_FORMAT " blocks=%d used=%d free=%d add=%d",
- p2i(this), blocks, total-free, free, _allocate_before_rebuild);
- }
}
--- a/hotspot/src/share/vm/runtime/mutex.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/mutex.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1320,15 +1320,12 @@
// The rank Mutex::native is an exception in that it is not subject
// to the verification rules.
// Here are some further notes relating to mutex acquisition anomalies:
- // . under Solaris, the interrupt lock gets acquired when doing
- // profiling, so any lock could be held.
// . it is also ok to acquire Safepoint_lock at the very end while we
// already hold Terminator_lock - may happen because of periodic safepoints
if (this->rank() != Mutex::native &&
this->rank() != Mutex::suspend_resume &&
locks != NULL && locks->rank() <= this->rank() &&
!SafepointSynchronize::is_at_safepoint() &&
- this != Interrupt_lock && this != ProfileVM_lock &&
!(this == Safepoint_lock && contains(locks, Terminator_lock) &&
SafepointSynchronize::is_synchronizing())) {
new_owner->print_owned_locks();
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,6 @@
Mutex* JfieldIdCreation_lock = NULL;
Monitor* JNICritical_lock = NULL;
Mutex* JvmtiThreadState_lock = NULL;
-Monitor* JvmtiPendingEvent_lock = NULL;
Monitor* Heap_lock = NULL;
Mutex* ExpandHeap_lock = NULL;
Mutex* AdapterHandlerLibrary_lock = NULL;
@@ -73,8 +72,6 @@
Monitor* STS_lock = NULL;
Monitor* SLT_lock = NULL;
Monitor* FullGCCount_lock = NULL;
-Monitor* CMark_lock = NULL;
-Mutex* CMRegionStack_lock = NULL;
Mutex* SATB_Q_FL_lock = NULL;
Monitor* SATB_Q_CBL_mon = NULL;
Mutex* Shared_SATB_Q_lock = NULL;
@@ -94,11 +91,8 @@
Monitor* Terminator_lock = NULL;
Monitor* BeforeExit_lock = NULL;
Monitor* Notify_lock = NULL;
-Monitor* Interrupt_lock = NULL;
-Monitor* ProfileVM_lock = NULL;
Mutex* ProfilePrint_lock = NULL;
Mutex* ExceptionCache_lock = NULL;
-Monitor* ObjAllocPost_lock = NULL;
Mutex* OsrList_lock = NULL;
#ifndef PRODUCT
@@ -184,8 +178,6 @@
}
if (UseG1GC) {
- def(CMark_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_never); // coordinate concurrent mark thread
- def(CMRegionStack_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
def(SATB_Q_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never);
def(SATB_Q_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never);
def(Shared_SATB_Q_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never);
@@ -206,12 +198,10 @@
def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes);
def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
def(CodeCache_lock , Mutex , special, true, Monitor::_safepoint_check_never);
- def(Interrupt_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for interrupt processing
def(RawMonitor_lock , Mutex, special, true, Monitor::_safepoint_check_never);
def(OopMapCacheAlloc_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation.
def(Patching_lock , Mutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching.
- def(ObjAllocPost_lock , Monitor, special, false, Monitor::_safepoint_check_never);
def(Service_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations
def(JmethodIdCreation_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs.
@@ -267,7 +257,6 @@
def(MultiArray_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock
def(JvmtiThreadState_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController
- def(JvmtiPendingEvent_lock , Monitor, nonleaf, false, Monitor::_safepoint_check_never); // Used by JvmtiCodeBlobEvents
def(Management_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management
def(Compile_lock , Mutex , nonleaf+3, true, Monitor::_safepoint_check_sometimes);
@@ -277,7 +266,6 @@
def(MethodCompileQueue_lock , Monitor, nonleaf+4, true, Monitor::_safepoint_check_always);
def(Debug2_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never);
def(Debug3_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never);
- def(ProfileVM_lock , Monitor, special, false, Monitor::_safepoint_check_never); // used for profiling of the VMThread
def(CompileThread_lock , Monitor, nonleaf+5, false, Monitor::_safepoint_check_always);
def(PeriodicTask_lock , Monitor, nonleaf+5, true, Monitor::_safepoint_check_sometimes);
if (WhiteBoxAPI) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,6 @@
extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers
extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
extern Mutex* JvmtiThreadState_lock; // a lock on modification of JVMTI thread data
-extern Monitor* JvmtiPendingEvent_lock; // a lock on the JVMTI pending events list
extern Monitor* Heap_lock; // a lock on the heap
extern Mutex* ExpandHeap_lock; // a lock on expanding the heap
extern Mutex* AdapterHandlerLibrary_lock; // a lock on the AdapterHandlerLibrary
@@ -68,8 +67,6 @@
extern Monitor* STS_lock; // used for joining/leaving SuspendibleThreadSet.
extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL
extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc
-extern Monitor* CMark_lock; // used for concurrent mark thread coordination
-extern Mutex* CMRegionStack_lock; // used for protecting accesses to the CM region stack
extern Mutex* SATB_Q_FL_lock; // Protects SATB Q
// buffer free list.
extern Monitor* SATB_Q_CBL_mon; // Protects SATB Q
@@ -98,8 +95,6 @@
extern Monitor* Terminator_lock; // a lock used to guard termination of the vm
extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks
extern Monitor* Notify_lock; // a lock used to synchronize the start-up of the vm
-extern Monitor* Interrupt_lock; // a lock used for condition variable mediated interrupt processing
-extern Monitor* ProfileVM_lock; // a lock used for profiling the VMThread
extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles
extern Mutex* ExceptionCache_lock; // a lock used to synchronize exception cache updates
extern Mutex* OsrList_lock; // a lock used to serialize access to OSR queues
--- a/hotspot/src/share/vm/runtime/objectMonitor.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -401,7 +401,7 @@
if (event.should_commit()) {
event.set_klass(((oop)this->object())->klass());
- event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid);
+ event.set_previousOwner((TYPE_THREAD)_previous_owner_tid);
event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
event.commit();
}
@@ -937,7 +937,7 @@
// get the owner's thread id for the MonitorEnter event
// if it is enabled and the thread isn't suspended
if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) {
- _previous_owner_tid = SharedRuntime::get_java_tid(Self);
+ _previous_owner_tid = THREAD_TRACE_ID(Self);
}
#endif
@@ -1391,11 +1391,12 @@
jlong notifier_tid,
jlong timeout,
bool timedout) {
+ assert(event != NULL, "invariant");
event->set_klass(((oop)this->object())->klass());
- event->set_timeout((TYPE_ULONG)timeout);
- event->set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
- event->set_notifier((TYPE_OSTHREAD)notifier_tid);
- event->set_timedOut((TYPE_BOOLEAN)timedout);
+ event->set_timeout(timeout);
+ event->set_address((TYPE_ADDRESS)this->object_addr());
+ event->set_notifier(notifier_tid);
+ event->set_timedOut(timedout);
event->commit();
}
@@ -1655,7 +1656,7 @@
iterator->TState = ObjectWaiter::TS_ENTER;
}
iterator->_notified = 1;
- iterator->_notifier_tid = Self->osthread()->thread_id();
+ iterator->_notifier_tid = THREAD_TRACE_ID(Self);
ObjectWaiter * list = _EntryList;
if (list != NULL) {
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -324,6 +324,10 @@
// record thread's native stack, stack grows downward
MemTracker::record_thread_stack(stack_end(), stack_size());
#endif // INCLUDE_NMT
+ log_debug(os, thread)("Thread " UINTX_FORMAT " stack dimensions: "
+ PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT "k).",
+ os::current_thread_id(), p2i(stack_base() - stack_size()),
+ p2i(stack_base()), stack_size()/1024);
}
@@ -1690,7 +1694,7 @@
EventThreadStart event;
if (event.should_commit()) {
- event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+ event.set_thread(THREAD_TRACE_ID(this));
event.commit();
}
@@ -1795,7 +1799,7 @@
// from java_lang_Thread object
EventThreadEnd event;
if (event.should_commit()) {
- event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+ event.set_thread(THREAD_TRACE_ID(this));
event.commit();
}
@@ -1924,6 +1928,10 @@
}
#endif // INCLUDE_ALL_GCS
+ log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
+ exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
+ os::current_thread_id());
+
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
Threads::remove(this);
}
@@ -2491,18 +2499,25 @@
// warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
- warning("Attempt to allocate stack guard pages failed.");
+ log_warning(os, thread)("Attempt to allocate stack guard pages failed.");
return;
}
if (os::guard_memory((char *) low_addr, len)) {
_stack_guard_state = stack_guard_enabled;
} else {
- warning("Attempt to protect stack guard pages failed.");
+ log_warning(os, thread)("Attempt to protect stack guard pages failed ("
+ PTR_FORMAT "-" PTR_FORMAT ").", p2i(low_addr), p2i(low_addr + len));
if (os::uncommit_memory((char *) low_addr, len)) {
- warning("Attempt to deallocate stack guard pages failed.");
+ log_warning(os, thread)("Attempt to deallocate stack guard pages failed.");
}
+ return;
}
+
+ log_debug(os, thread)("Thread " UINTX_FORMAT " stack guard pages activated: "
+ PTR_FORMAT "-" PTR_FORMAT ".",
+ os::current_thread_id(), p2i(low_addr), p2i(low_addr + len));
+
}
void JavaThread::remove_stack_guard_pages() {
@@ -2515,16 +2530,25 @@
if (os::remove_stack_guard_pages((char *) low_addr, len)) {
_stack_guard_state = stack_guard_unused;
} else {
- warning("Attempt to deallocate stack guard pages failed.");
+ log_warning(os, thread)("Attempt to deallocate stack guard pages failed ("
+ PTR_FORMAT "-" PTR_FORMAT ").", p2i(low_addr), p2i(low_addr + len));
+ return;
}
} else {
if (_stack_guard_state == stack_guard_unused) return;
if (os::unguard_memory((char *) low_addr, len)) {
_stack_guard_state = stack_guard_unused;
} else {
- warning("Attempt to unprotect stack guard pages failed.");
+ log_warning(os, thread)("Attempt to unprotect stack guard pages failed ("
+ PTR_FORMAT "-" PTR_FORMAT ").", p2i(low_addr), p2i(low_addr + len));
+ return;
}
}
+
+ log_debug(os, thread)("Thread " UINTX_FORMAT " stack guard pages removed: "
+ PTR_FORMAT "-" PTR_FORMAT ".",
+ os::current_thread_id(), p2i(low_addr), p2i(low_addr + len));
+
}
void JavaThread::enable_stack_reserved_zone() {
@@ -3530,6 +3554,10 @@
return status;
}
+ if (TRACE_INITIALIZE() != JNI_OK) {
+ vm_exit_during_initialization("Failed to initialize tracing backend");
+ }
+
// Should be done after the heap is fully created
main_thread->cache_global_variables();
@@ -3598,11 +3626,6 @@
quicken_jni_functions();
- // Must be run after init_ft which initializes ft_enabled
- if (TRACE_INITIALIZE() != JNI_OK) {
- vm_exit_during_initialization("Failed to initialize tracing backend");
- }
-
// No more stub generation allowed after that point.
StubCodeDesc::freeze();
@@ -4110,6 +4133,7 @@
if (version == JNI_VERSION_1_4) return JNI_TRUE;
if (version == JNI_VERSION_1_6) return JNI_TRUE;
if (version == JNI_VERSION_1_8) return JNI_TRUE;
+ if (version == JNI_VERSION_9) return JNI_TRUE;
return JNI_FALSE;
}
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/thread.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -448,7 +448,8 @@
void incr_allocated_bytes(jlong size) { _allocated_bytes += size; }
inline jlong cooked_allocated_bytes();
- TRACE_DATA* trace_data() { return &_trace_data; }
+ TRACE_DEFINE_THREAD_TRACE_DATA_OFFSET;
+ TRACE_DATA* trace_data() const { return &_trace_data; }
const ThreadExt& ext() const { return _ext; }
ThreadExt& ext() { return _ext; }
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -359,7 +359,7 @@
// Only write caller thread information for non-concurrent vm operations.
// For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
// This is because the caller thread could have exited already.
- event.set_caller(is_concurrent ? 0 : op->calling_thread()->osthread()->thread_id());
+ event.set_caller(is_concurrent ? 0 : THREAD_TRACE_ID(op->calling_thread()));
event.commit();
}
--- a/hotspot/src/share/vm/services/heapDumper.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/services/heapDumper.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,8 +53,7 @@
* src/share/demo/jvmti/hprof/hprof_io.c
*
*
- * header "JAVA PROFILE 1.0.1" or "JAVA PROFILE 1.0.2"
- * (0-terminated)
+ * header "JAVA PROFILE 1.0.2" (0-terminated)
*
* u4 size of identifiers. Identifiers are used to represent
* UTF8 strings, objects, stack traces, etc. They usually
@@ -385,6 +384,8 @@
size_t _size;
size_t _pos;
+ jlong _dump_start;
+
char* _error; // error message when I/O fails
void set_file_descriptor(int fd) { _fd = fd; }
@@ -408,6 +409,10 @@
bool is_open() const { return file_descriptor() >= 0; }
void flush();
+ jlong dump_start() const { return _dump_start; }
+ void set_dump_start(jlong pos);
+ julong current_record_length();
+
// total number of bytes written to the disk
julong bytes_written() const { return _bytes_written; }
@@ -449,6 +454,7 @@
_pos = 0;
_error = NULL;
_bytes_written = 0L;
+ _dump_start = (jlong)-1;
_fd = os::create_binary_file(path, false); // don't replace existing file
// if the open failed we record the error
@@ -476,6 +482,22 @@
}
}
+// sets the dump starting position
+void DumpWriter::set_dump_start(jlong pos) {
+ _dump_start = pos;
+}
+
+julong DumpWriter::current_record_length() {
+ if (is_open()) {
+ // calculate the size of the dump record
+ julong dump_end = bytes_written() + bytes_unwritten();
+ assert(dump_end == (size_t)current_offset(), "checking");
+ julong dump_len = dump_end - dump_start() - 4;
+ return dump_len;
+ }
+ return 0;
+}
+
// write directly to the file
void DumpWriter::write_internal(void* s, size_t len) {
if (is_open()) {
@@ -645,6 +667,18 @@
static void dump_prim_array(DumpWriter* writer, typeArrayOop array);
// create HPROF_FRAME record for the given method and bci
static void dump_stack_frame(DumpWriter* writer, int frame_serial_num, int class_serial_num, Method* m, int bci);
+
+ // check if we need to truncate an array
+ static int calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size);
+
+ // writes a HPROF_HEAP_DUMP_SEGMENT record
+ static void write_dump_header(DumpWriter* writer);
+
+ // fixes up the length of the current dump record
+ static void write_current_dump_record_length(DumpWriter* writer);
+
+ // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
+ static void end_of_dump(DumpWriter* writer);
};
// write a header of the given type
@@ -1005,50 +1039,102 @@
}
}
+// Hprof uses an u4 as record length field,
+// which means we need to truncate arrays that are too long.
+int DumperSupport::calculate_array_max_length(DumpWriter* writer, arrayOop array, short header_size) {
+ BasicType type = ArrayKlass::cast(array->klass())->element_type();
+ assert(type >= T_BOOLEAN && type <= T_OBJECT, "invalid array element type");
+
+ int length = array->length();
+
+ int type_size;
+ if (type == T_OBJECT) {
+ type_size = sizeof(address);
+ } else {
+ type_size = type2aelembytes(type);
+ }
+
+ size_t length_in_bytes = (size_t)length * type_size;
+
+ // Create a new record if the current record is non-empty and the array can't fit.
+ julong current_record_length = writer->current_record_length();
+ if (current_record_length > 0 &&
+ (current_record_length + header_size + length_in_bytes) > max_juint) {
+ write_current_dump_record_length(writer);
+ write_dump_header(writer);
+
+ // We now have an empty record.
+ current_record_length = 0;
+ }
+
+ // Calculate max bytes we can use.
+ uint max_bytes = max_juint - (header_size + current_record_length);
+
+ // Array too long for the record?
+ // Calculate max length and return it.
+ if (length_in_bytes > max_bytes) {
+ length = max_bytes / type_size;
+ length_in_bytes = (size_t)length * type_size;
+
+ warning("cannot dump array of type %s[] with length %d; truncating to length %d",
+ type2name_tab[type], array->length(), length);
+ }
+ return length;
+}
+
// creates HPROF_GC_OBJ_ARRAY_DUMP record for the given object array
void DumperSupport::dump_object_array(DumpWriter* writer, objArrayOop array) {
+ // sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID) + sizeof(classID)
+ short header_size = 1 + 2 * 4 + 2 * sizeof(address);
+
+ int length = calculate_array_max_length(writer, array, header_size);
writer->write_u1(HPROF_GC_OBJ_ARRAY_DUMP);
writer->write_objectID(array);
writer->write_u4(STACK_TRACE_ID);
- writer->write_u4((u4)array->length());
+ writer->write_u4(length);
// array class ID
writer->write_classID(array->klass());
// [id]* elements
- for (int index=0; index<array->length(); index++) {
+ for (int index = 0; index < length; index++) {
oop o = array->obj_at(index);
writer->write_objectID(o);
}
}
-#define WRITE_ARRAY(Array, Type, Size) \
- for (int i=0; i<Array->length(); i++) { writer->write_##Size((Size)array->Type##_at(i)); }
-
+#define WRITE_ARRAY(Array, Type, Size, Length) \
+ for (int i = 0; i < Length; i++) { writer->write_##Size((Size)Array->Type##_at(i)); }
// creates HPROF_GC_PRIM_ARRAY_DUMP record for the given type array
void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) {
BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
+ // 2 * sizeof(u1) + 2 * sizeof(u4) + sizeof(objectID)
+ short header_size = 2 * 1 + 2 * 4 + sizeof(address);
+
+ int length = calculate_array_max_length(writer, array, header_size);
+ int type_size = type2aelembytes(type);
+ u4 length_in_bytes = (u4)length * type_size;
+
writer->write_u1(HPROF_GC_PRIM_ARRAY_DUMP);
writer->write_objectID(array);
writer->write_u4(STACK_TRACE_ID);
- writer->write_u4((u4)array->length());
+ writer->write_u4(length);
writer->write_u1(type2tag(type));
// nothing to copy
- if (array->length() == 0) {
+ if (length == 0) {
return;
}
// If the byte ordering is big endian then we can copy most types directly
- u4 length_in_bytes = (u4)array->length() * type2aelembytes(type);
switch (type) {
case T_INT : {
if (Bytes::is_Java_byte_ordering_different()) {
- WRITE_ARRAY(array, int, u4);
+ WRITE_ARRAY(array, int, u4, length);
} else {
writer->write_raw((void*)(array->int_at_addr(0)), length_in_bytes);
}
@@ -1060,7 +1146,7 @@
}
case T_CHAR : {
if (Bytes::is_Java_byte_ordering_different()) {
- WRITE_ARRAY(array, char, u2);
+ WRITE_ARRAY(array, char, u2, length);
} else {
writer->write_raw((void*)(array->char_at_addr(0)), length_in_bytes);
}
@@ -1068,7 +1154,7 @@
}
case T_SHORT : {
if (Bytes::is_Java_byte_ordering_different()) {
- WRITE_ARRAY(array, short, u2);
+ WRITE_ARRAY(array, short, u2, length);
} else {
writer->write_raw((void*)(array->short_at_addr(0)), length_in_bytes);
}
@@ -1076,7 +1162,7 @@
}
case T_BOOLEAN : {
if (Bytes::is_Java_byte_ordering_different()) {
- WRITE_ARRAY(array, bool, u1);
+ WRITE_ARRAY(array, bool, u1, length);
} else {
writer->write_raw((void*)(array->bool_at_addr(0)), length_in_bytes);
}
@@ -1084,7 +1170,7 @@
}
case T_LONG : {
if (Bytes::is_Java_byte_ordering_different()) {
- WRITE_ARRAY(array, long, u8);
+ WRITE_ARRAY(array, long, u8, length);
} else {
writer->write_raw((void*)(array->long_at_addr(0)), length_in_bytes);
}
@@ -1096,14 +1182,14 @@
// use IEEE 754.
case T_FLOAT : {
- for (int i=0; i<array->length(); i++) {
- dump_float( writer, array->float_at(i) );
+ for (int i = 0; i < length; i++) {
+ dump_float(writer, array->float_at(i));
}
break;
}
case T_DOUBLE : {
- for (int i=0; i<array->length(); i++) {
- dump_double( writer, array->double_at(i) );
+ for (int i = 0; i < length; i++) {
+ dump_double(writer, array->double_at(i));
}
break;
}
@@ -1320,8 +1406,6 @@
JavaThread* _oome_thread;
Method* _oome_constructor;
bool _gc_before_heap_dump;
- bool _is_segmented_dump;
- jlong _dump_start;
GrowableArray<Klass*>* _klass_map;
ThreadStackTrace** _stack_traces;
int _num_threads;
@@ -1340,11 +1424,6 @@
void clear_global_dumper() { _global_dumper = NULL; }
void clear_global_writer() { _global_writer = NULL; }
- bool is_segmented_dump() const { return _is_segmented_dump; }
- void set_segmented_dump() { _is_segmented_dump = true; }
- jlong dump_start() const { return _dump_start; }
- void set_dump_start(jlong pos);
-
bool skip_operation() const;
// writes a HPROF_LOAD_CLASS record
@@ -1369,16 +1448,6 @@
// HPROF_TRACE and HPROF_FRAME records
void dump_stack_traces();
- // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
- void write_dump_header();
-
- // fixes up the length of the current dump record
- void write_current_dump_record_length();
-
- // fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
- // record in the case of a segmented heap dump)
- void end_of_dump();
-
public:
VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :
VM_GC_Operation(0 /* total collections, dummy, ignored */,
@@ -1387,8 +1456,6 @@
gc_before_heap_dump) {
_local_writer = writer;
_gc_before_heap_dump = gc_before_heap_dump;
- _is_segmented_dump = false;
- _dump_start = (jlong)-1;
_klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
_stack_traces = NULL;
_num_threads = 0;
@@ -1428,35 +1495,23 @@
return false;
}
-// sets the dump starting position
-void VM_HeapDumper::set_dump_start(jlong pos) {
- _dump_start = pos;
-}
-
- // writes a HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT record
-void VM_HeapDumper::write_dump_header() {
- if (writer()->is_open()) {
- if (is_segmented_dump()) {
- writer()->write_u1(HPROF_HEAP_DUMP_SEGMENT);
- } else {
- writer()->write_u1(HPROF_HEAP_DUMP);
- }
- writer()->write_u4(0); // current ticks
+ // writes a HPROF_HEAP_DUMP_SEGMENT record
+void DumperSupport::write_dump_header(DumpWriter* writer) {
+ if (writer->is_open()) {
+ writer->write_u1(HPROF_HEAP_DUMP_SEGMENT);
+ writer->write_u4(0); // current ticks
// record the starting position for the dump (its length will be fixed up later)
- set_dump_start(writer()->current_offset());
- writer()->write_u4(0);
+ writer->set_dump_start(writer->current_offset());
+ writer->write_u4(0);
}
}
// fixes up the length of the current dump record
-void VM_HeapDumper::write_current_dump_record_length() {
- if (writer()->is_open()) {
- assert(dump_start() >= 0, "no dump start recorded");
-
- // calculate the size of the dump record
- julong dump_end = writer()->current_offset();
- julong dump_len = (dump_end - dump_start() - 4);
+void DumperSupport::write_current_dump_record_length(DumpWriter* writer) {
+ if (writer->is_open()) {
+ julong dump_end = writer->bytes_written() + writer->bytes_unwritten();
+ julong dump_len = writer->current_record_length();
// record length must fit in a u4
if (dump_len > max_juint) {
@@ -1464,17 +1519,18 @@
}
// seek to the dump start and fix-up the length
- writer()->seek_to_offset(dump_start());
- writer()->write_u4((u4)dump_len);
+ assert(writer->dump_start() >= 0, "no dump start recorded");
+ writer->seek_to_offset(writer->dump_start());
+ writer->write_u4((u4)dump_len);
// adjust the total size written to keep the bytes written correct.
- writer()->adjust_bytes_written(-((jlong) sizeof(u4)));
+ writer->adjust_bytes_written(-((jlong) sizeof(u4)));
// seek to dump end so we can continue
- writer()->seek_to_offset(dump_end);
+ writer->seek_to_offset(dump_end);
// no current dump record
- set_dump_start((jlong)-1);
+ writer->set_dump_start((jlong)-1);
}
}
@@ -1482,33 +1538,23 @@
// new segment.
void VM_HeapDumper::check_segment_length() {
if (writer()->is_open()) {
- if (is_segmented_dump()) {
- // don't use current_offset that would be too expensive on a per record basis
- julong dump_end = writer()->bytes_written() + writer()->bytes_unwritten();
- assert(dump_end == (julong)writer()->current_offset(), "checking");
- julong dump_len = (dump_end - dump_start() - 4);
- assert(dump_len <= max_juint, "bad dump length");
+ julong dump_len = writer()->current_record_length();
- if (dump_len > HeapDumpSegmentSize) {
- write_current_dump_record_length();
- write_dump_header();
- }
+ if (dump_len > 2UL*G) {
+ DumperSupport::write_current_dump_record_length(writer());
+ DumperSupport::write_dump_header(writer());
}
}
}
-// fixes up the current dump record )and writes HPROF_HEAP_DUMP_END
-// record in the case of a segmented heap dump)
-void VM_HeapDumper::end_of_dump() {
- if (writer()->is_open()) {
- write_current_dump_record_length();
+// fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
+void DumperSupport::end_of_dump(DumpWriter* writer) {
+ if (writer->is_open()) {
+ write_current_dump_record_length(writer);
- // for segmented dump we write the end record
- if (is_segmented_dump()) {
- writer()->write_u1(HPROF_HEAP_DUMP_END);
- writer()->write_u4(0);
- writer()->write_u4(0);
- }
+ writer->write_u1(HPROF_HEAP_DUMP_END);
+ writer->write_u4(0);
+ writer->write_u4(0);
}
}
@@ -1686,16 +1732,17 @@
// [HPROF_LOAD_CLASS]*
// [[HPROF_FRAME]*|HPROF_TRACE]*
// [HPROF_GC_CLASS_DUMP]*
-// HPROF_HEAP_DUMP
+// [HPROF_HEAP_DUMP_SEGMENT]*
+// HPROF_HEAP_DUMP_END
//
// The HPROF_TRACE records represent the stack traces where the heap dump
// is generated and a "dummy trace" record which does not include
// any frames. The dummy trace record is used to be referenced as the
// unknown object alloc site.
//
-// The HPROF_HEAP_DUMP record has a length following by sub-records. To allow
-// the heap dump be generated in a single pass we remember the position of
-// the dump length and fix it up after all sub-records have been written.
+// Each HPROF_HEAP_DUMP_SEGMENT record has a length followed by sub-records.
+// To allow the heap dump be generated in a single pass we remember the position
+// of the dump length and fix it up after all sub-records have been written.
// To generate the sub-records we iterate over the heap, writing
// HPROF_GC_INSTANCE_DUMP, HPROF_GC_OBJ_ARRAY_DUMP, and HPROF_GC_PRIM_ARRAY_DUMP
// records as we go. Once that is done we write records for some of the GC
@@ -1722,15 +1769,9 @@
set_global_dumper();
set_global_writer();
- // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
+ // Write the file header - we always use 1.0.2
size_t used = ch->used();
- const char* header;
- if (used > SegmentedHeapDumpThreshold) {
- set_segmented_dump();
- header = "JAVA PROFILE 1.0.2";
- } else {
- header = "JAVA PROFILE 1.0.1";
- }
+ const char* header = "JAVA PROFILE 1.0.2";
// header is few bytes long - no chance to overflow int
writer()->write_raw((void*)header, (int)strlen(header));
@@ -1750,8 +1791,8 @@
// this must be called after _klass_map is built when iterating the classes above.
dump_stack_traces();
- // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT
- write_dump_header();
+ // write HPROF_HEAP_DUMP_SEGMENT
+ DumperSupport::write_dump_header(writer());
// Writes HPROF_GC_CLASS_DUMP records
ClassLoaderDataGraph::classes_do(&do_class_dump);
@@ -1759,9 +1800,9 @@
check_segment_length();
// writes HPROF_GC_INSTANCE_DUMP records.
- // After each sub-record is written check_segment_length will be invoked. When
- // generated a segmented heap dump this allows us to check if the current
- // segment exceeds a threshold and if so, then a new segment is started.
+ // After each sub-record is written check_segment_length will be invoked
+ // to check if the current segment exceeds a threshold. If so, a new
+ // segment is started.
// The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk
// of the heap dump.
HeapObjectDumper obj_dumper(this, writer());
@@ -1785,9 +1826,8 @@
StickyClassDumper class_dumper(writer());
SystemDictionary::always_strong_classes_do(&class_dumper);
- // fixes up the length of the dump record. In the case of a segmented
- // heap then the HPROF_HEAP_DUMP_END record is also written.
- end_of_dump();
+ // fixes up the length of the dump record and writes the HPROF_HEAP_DUMP_END record.
+ DumperSupport::end_of_dump(writer());
// Now we clear the global variables, so that a future dumper might run.
clear_global_dumper();
--- a/hotspot/src/share/vm/trace/trace.xml Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/trace.xml Sat Mar 05 10:10:23 2016 +0100
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -73,12 +73,12 @@
<events>
<event id="ThreadStart" path="java/thread_start" label="Java Thread Start"
has_thread="true" is_instant="true">
- <value type="JAVALANGTHREAD" field="javalangthread" label="Java Thread"/>
+ <value type="THREAD" field="thread" label="Java Thread"/>
</event>
<event id="ThreadEnd" path="java/thread_end" label="Java Thread End"
has_thread="true" is_instant="true">
- <value type="JAVALANGTHREAD" field="javalangthread" label="Java Thread"/>
+ <value type="THREAD" field="thread" label="Java Thread"/>
</event>
<event id="ThreadSleep" path="java/thread_sleep" label="Java Thread Sleep"
@@ -96,14 +96,14 @@
<event id="JavaMonitorEnter" path="java/monitor_enter" label="Java Monitor Blocked"
has_thread="true" has_stacktrace="true" is_instant="false">
<value type="CLASS" field="klass" label="Monitor Class"/>
- <value type="JAVALANGTHREAD" field="previousOwner" label="Previous Monitor Owner"/>
+ <value type="THREAD" field="previousOwner" label="Previous Monitor Owner"/>
<value type="ADDRESS" field="address" label="Monitor Address" relation="JAVA_MONITOR_ADDRESS"/>
</event>
<event id="JavaMonitorWait" path="java/monitor_wait" label="Java Monitor Wait" description="Waiting on a Java monitor"
has_thread="true" has_stacktrace="true" is_instant="false">
<value type="CLASS" field="klass" label="Monitor Class" description="Class of object waited on"/>
- <value type="OSTHREAD" field="notifier" label="Notifier Thread" description="Notifying Thread"/>
+ <value type="THREAD" field="notifier" label="Notifier Thread" description="Notifying Thread"/>
<value type="MILLIS" field="timeout" label="Timeout" description="Maximum wait time"/>
<value type="BOOLEAN" field="timedOut" label="Timed Out" description="Wait has been timed out"/>
<value type="ADDRESS" field="address" label="Monitor Address" description="Address of object waited on" relation="JAVA_MONITOR_ADDRESS"/>
@@ -434,7 +434,7 @@
description="Promotion of an object failed">
<value type="UINT" field="gcId" label="GC ID" relation="GC_ID"/>
<structvalue type="CopyFailed" field="data" label="Data"/>
- <value type="OSTHREAD" field="thread" label="Running thread"/>
+ <value type="THREAD" field="thread" label="Running thread"/>
</event>
<event id="EvacuationFailed" path="vm/gc/detailed/evacuation_failed" label="Evacuation Failed" is_instant="true"
@@ -496,6 +496,11 @@
<value type="UINT" field="allocContext" label="Allocation Context" />
</event>
+ <event id="VMError" path="vm/runtime/vm_error" label="VM Error"
+ description="VM shutdown due to an error" has_stacktrace="true" has_thread="true">
+ <value type="BOOLEAN" field="out_of_java_memory" label="Java Out Of Memory"/>
+ </event>
+
<!-- Compiler events -->
<event id="Compilation" path="vm/compiler/compilation" label="Compilation"
@@ -569,7 +574,7 @@
<value type="VMOPERATIONTYPE" field="operation" label="Operation" />
<value type="BOOLEAN" field="safepoint" label="At Safepoint" description="If the operation occured at a safepoint."/>
<value type="BOOLEAN" field="blocking" label="Caller Blocked" description="If the calling thread was blocked until the operation was complete."/>
- <value type="OSTHREAD" field="caller" label="Caller" transition="FROM" description="Thread requesting operation. If non-blocking, will be set to 0 indicating thread is unknown."/>
+ <value type="THREAD" field="caller" label="Caller" transition="FROM" description="Thread requesting operation. If non-blocking, will be set to 0 indicating thread is unknown."/>
</event>
<!-- Allocation events -->
--- a/hotspot/src/share/vm/trace/traceBackend.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceBackend.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,10 @@
static void on_unloading_classes(void) {
}
+
+ static void on_vm_error(bool) {
+ }
+
};
class TraceThreadData {
--- a/hotspot/src/share/vm/trace/traceDataTypes.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceDataTypes.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,39 +31,32 @@
enum {
CONTENT_TYPE_NONE = 0,
- CONTENT_TYPE_BYTES = 1,
- CONTENT_TYPE_EPOCHMILLIS = 2,
- CONTENT_TYPE_MILLIS = 3,
- CONTENT_TYPE_NANOS = 4,
- CONTENT_TYPE_TICKS = 5,
- CONTENT_TYPE_ADDRESS = 6,
+ CONTENT_TYPE_CLASS = 20,
+ CONTENT_TYPE_UTF8 = 21,
+ CONTENT_TYPE_THREAD = 22,
+ CONTENT_TYPE_STACKTRACE = 23,
+ CONTENT_TYPE_BYTES = 24,
+ CONTENT_TYPE_EPOCHMILLIS = 25,
+ CONTENT_TYPE_MILLIS = 26,
+ CONTENT_TYPE_NANOS = 27,
+ CONTENT_TYPE_TICKS = 28,
+ CONTENT_TYPE_ADDRESS = 29,
+ CONTENT_TYPE_PERCENTAGE = 30,
- CONTENT_TYPE_OSTHREAD,
- CONTENT_TYPE_JAVALANGTHREAD,
- CONTENT_TYPE_STACKTRACE,
- CONTENT_TYPE_CLASS,
- CONTENT_TYPE_PERCENTAGE,
-
- JVM_CONTENT_TYPES_START = 30,
- JVM_CONTENT_TYPES_END = 100
+ JVM_CONTENT_TYPES_START = 33,
+ JVM_CONTENT_TYPES_END = 255
};
enum ReservedEvent {
- EVENT_PRODUCERS,
+ EVENT_METADATA,
EVENT_CHECKPOINT,
EVENT_BUFFERLOST,
- NUM_RESERVED_EVENTS
+ NUM_RESERVED_EVENTS = JVM_CONTENT_TYPES_END
};
typedef enum ReservedEvent ReservedEvent;
-typedef u8 classid;
-typedef u8 stacktraceid;
-typedef u8 methodid;
-typedef u8 fieldid;
-
-class TraceUnicodeString;
+class Symbol;
#endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
-
--- a/hotspot/src/share/vm/trace/traceEvent.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceEvent.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,6 @@
_endTime = time;
}
- public:
TraceEvent(EventStartTime timing=TIMED) :
_startTime(0),
_endTime(0),
@@ -76,12 +75,21 @@
{
if (T::is_enabled()) {
_started = true;
- if (timing == TIMED && !T::isInstant) {
- static_cast<T *>(this)->set_starttime(Tracing::time());
+ if (TIMED == timing && !T::isInstant) {
+ static_cast<T*>(this)->set_starttime(Tracing::time());
}
}
}
+ public:
+ void set_starttime(const Ticks& time) {
+ _startTime = time.value();
+ }
+
+ void set_endtime(const Ticks& time) {
+ _endTime = time.value();
+ }
+
static bool is_enabled() {
return Tracing::is_event_enabled(T::eventId);
}
@@ -90,67 +98,68 @@
return _started;
}
- void ignoreCheck() {
- DEBUG_ONLY(_ignore_check = true);
- }
-
void commit() {
if (!should_commit()) {
- cancel();
- return;
+ DEBUG_ONLY(cancel());
+ return;
}
- if (_endTime == 0) {
+ assert(!_cancelled, "Committing an event that has already been cancelled");
+ if (_startTime == 0) {
+ static_cast<T*>(this)->set_starttime(Tracing::time());
+ } else if (_endTime == 0) {
static_cast<T*>(this)->set_endtime(Tracing::time());
}
if (static_cast<T*>(this)->should_write()) {
static_cast<T*>(this)->writeEvent();
}
- set_commited();
+ DEBUG_ONLY(set_commited());
}
- void set_starttime(const Ticks& time) {
- _startTime = time.value();
- }
-
- void set_endtime(const Ticks& time) {
- _endTime = time.value();
- }
-
- TraceEventId id() const {
+ static TraceEventId id() {
return T::eventId;
}
- bool is_instant() const {
+ static bool is_instant() {
return T::isInstant;
}
- bool is_requestable() const {
+ static bool is_requestable() {
return T::isRequestable;
}
- bool has_thread() const {
+ static bool has_thread() {
return T::hasThread;
}
- bool has_stacktrace() const {
+ static bool has_stacktrace() {
return T::hasStackTrace;
}
void cancel() {
- assert(!_committed && !_cancelled, "event was already committed/cancelled");
+ assert(!_committed && !_cancelled,
+ "event was already committed/cancelled");
DEBUG_ONLY(_cancelled = true);
}
- void set_commited() {
- assert(!_committed, "event has already been committed");
- DEBUG_ONLY(_committed = true);
- }
-
~TraceEvent() {
if (_started) {
- assert(_ignore_check || _committed || _cancelled, "event was not committed/cancelled");
+ assert(_ignore_check || _committed || _cancelled,
+ "event was not committed/cancelled");
}
}
+
+#ifdef ASSERT
+ protected:
+ void ignoreCheck() {
+ _ignore_check = true;
+ }
+
+ private:
+ void set_commited() {
+ assert(!_committed, "event has already been committed");
+ _committed = true;
+ }
+#endif // ASSERT
};
#endif // INCLUDE_TRACE
--- a/hotspot/src/share/vm/trace/traceEventClasses.xsl Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceEventClasses.xsl Sat Mar 05 10:10:23 2016 +0100
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -52,8 +52,8 @@
class TraceEvent {
public:
TraceEvent() {}
- void set_starttime(const Ticks& time) {}
- void set_endtime(const Ticks& time) {}
+ void set_starttime(const Ticks& ignore) {}
+ void set_endtime(const Ticks& ignore) {}
bool should_commit() const { return false; }
static bool is_enabled() { return false; }
void commit() {}
--- a/hotspot/src/share/vm/trace/traceEventIds.xsl Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceEventIds.xsl Sat Mar 05 10:10:23 2016 +0100
@@ -43,7 +43,7 @@
_traceeventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index.
// Events -> enum entry
-<xsl:for-each select="trace/events/event">
+<xsl:for-each select="trace/events/*">
<xsl:value-of select="concat(' Trace', @id, 'Event,', $newline)"/>
</xsl:for-each>
MaxTraceEventId
--- a/hotspot/src/share/vm/trace/traceMacros.hpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,19 +25,29 @@
#ifndef SHARE_VM_TRACE_TRACEMACROS_HPP
#define SHARE_VM_TRACE_TRACEMACROS_HPP
+typedef u8 traceid;
+
#define EVENT_THREAD_EXIT(thread)
#define EVENT_THREAD_DESTRUCT(thread)
+#define TRACE_KLASS_CREATION(k, p, t)
-#define TRACE_INIT_ID(k)
+#define TRACE_INIT_KLASS_ID(k)
+#define TRACE_INIT_THREAD_ID(td)
#define TRACE_DATA TraceThreadData
+#define THREAD_TRACE_ID(thread) ((traceid)thread->osthread()->thread_id())
#define TRACE_START() JNI_OK
#define TRACE_INITIALIZE() JNI_OK
-#define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1
-#define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2
-#define TRACE_DEFINE_OFFSET typedef int ___IGNORED_hs_trace_type3
-#define TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_TRACE_ID_METHODS typedef int ___IGNORED_hs_trace_type1
+#define TRACE_DEFINE_TRACE_ID_FIELD typedef int ___IGNORED_hs_trace_type2
+#define TRACE_DEFINE_KLASS_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type3
+#define TRACE_KLASS_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_THREAD_TRACE_DATA_OFFSET typedef int ___IGNORED_hs_trace_type4
+#define TRACE_THREAD_TRACE_DATA_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_THREAD_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type5
+#define TRACE_THREAD_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_THREAD_ID_SIZE typedef int ___IGNORED_hs_trace_type6
#define TRACE_TEMPLATES(template)
#define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
--- a/hotspot/src/share/vm/trace/tracetypes.xml Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/trace/tracetypes.xml Sat Mar 05 10:10:23 2016 +0100
@@ -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, 2016, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -60,27 +60,16 @@
<types>
<content_types>
<content_type id="Thread" hr_name="Thread"
- type="U4" builtin_type="OSTHREAD">
- <value type="UTF8" field="name" label="Thread name"/>
- </content_type>
-
- <content_type id="VMThread" hr_name="VM Thread"
- type="U8" jvm_type="VMTHREAD">
- <value type="OSTHREAD" field="thread" label="VM Thread"/>
- </content_type>
-
- <content_type id="JavaThread" hr_name="Java thread"
- type="U8" builtin_type="JAVALANGTHREAD">
- <value type="OSTHREAD" field="thread" label="OS Thread ID"/>
- <value type="BYTES64" field="allocInsideTla"
- label="Allocated bytes inside TLAs"/>
- <value type="BYTES64" field="allocOutsideTla"
- label="Allocated bytes outside TLAs"/>
+ type="U8" builtin_type="THREAD">
+ <value type="UTF8" field="osName" label="OS Thread Name"/>
+ <value type="LONG" field="osThreadID" label="OS Thread ID"/>
+ <value type="UTF8" field="javaName" label="Java Lang Thread Name"/>
+ <value type="LONG" field="javaThreadID" label="Java Lang Thread ID"/>
<value type="THREADGROUP" field="group" label="Java Thread Group"/>
</content_type>
<content_type id="ThreadGroup" hr_name="Thread group"
- type="U4" jvm_type="THREADGROUP">
+ type="U8" jvm_type="THREADGROUP">
<value type="THREADGROUP" field="parent" label="Parent"/>
<value type="UTF8" field="name" label="Name"/>
</content_type>
@@ -107,82 +96,82 @@
</content_type>
<content_type id="ThreadState" hr_name="Java Thread State"
- type="U2" jvm_type="THREADSTATE">
+ type="U8" jvm_type="THREADSTATE">
<value type="UTF8" field="name" label="Name"/>
</content_type>
<content_type id="GCName" hr_name="GC Name"
- type="U1" jvm_type="GCNAME">
+ type="U8" jvm_type="GCNAME">
<value type="UTF8" field="name" label="name" />
</content_type>
<content_type id="GCCause" hr_name="GC Cause"
- type="U2" jvm_type="GCCAUSE">
+ type="U8" jvm_type="GCCAUSE">
<value type="UTF8" field="cause" label="cause" />
</content_type>
<content_type id="GCWhen" hr_name="GC When"
- type="U1" jvm_type="GCWHEN">
+ type="U8" jvm_type="GCWHEN">
<value type="UTF8" field="when" label="when" />
</content_type>
<content_type id="G1HeapRegionType" hr_name="G1 Heap Region Type"
- type="U1" jvm_type="G1HEAPREGIONTYPE">
+ type="U8" jvm_type="G1HEAPREGIONTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="G1YCType" hr_name="G1 YC Type"
- type="U1" jvm_type="G1YCTYPE">
+ type="U8" jvm_type="G1YCTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="GCThresholdUpdater" hr_name="GC Treshold Updater"
- type="U1" jvm_type="GCTHRESHOLDUPDATER">
+ type="U8" jvm_type="GCTHRESHOLDUPDATER">
<value type="UTF8" field="updater" label="updater" />
</content_type>
<content_type id="ReferenceType" hr_name="Reference Type"
- type="U1" jvm_type="REFERENCETYPE">
+ type="U8" jvm_type="REFERENCETYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="MetadataType" hr_name="Metadata Type"
- type="U1" jvm_type="METADATATYPE">
+ type="U8" jvm_type="METADATATYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="MetaspaceObjectType" hr_name="Metaspace Object Type"
- type="U1" jvm_type="METASPACEOBJTYPE">
+ type="U8" jvm_type="METASPACEOBJTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="NARROW_OOP_MODE" hr_name="Narrow Oop Mode"
- type="U1" jvm_type="NARROWOOPMODE">
+ type="U8" jvm_type="NARROWOOPMODE">
<value type="UTF8" field="mode" label="mode" />
</content_type>
<content_type id="VMOperationType" hr_name="VM Operation Type"
- type="U2" jvm_type="VMOPERATIONTYPE">
+ type="U8" jvm_type="VMOPERATIONTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="CompilerPhaseType" hr_name="Compiler Phase Type"
- type="U1" jvm_type="COMPILERPHASETYPE">
+ type="U8" jvm_type="COMPILERPHASETYPE">
<value type="UTF8" field="phase" label="phase" />
</content_type>
<content_type id="FlagValueOrigin" hr_name="Flag Value Origin"
- type="U1" jvm_type="FLAGVALUEORIGIN">
+ type="U8" jvm_type="FLAGVALUEORIGIN">
<value type="UTF8" field="origin" label="origin" />
</content_type>
<content_type id="CodeBlobType" hr_name="Code Blob Type"
- type="U1" jvm_type="CODEBLOBTYPE">
+ type="U8" jvm_type="CODEBLOBTYPE">
<value type="UTF8" field="type" label="type" />
</content_type>
<content_type id="InflateCause" hr_name="Inflation Cause"
- type="U1" jvm_type="INFLATECAUSE">
+ type="U8" jvm_type="INFLATECAUSE">
<value type="UTF8" field="cause" label="cause" />
</content_type>
</content_types>
@@ -245,11 +234,11 @@
type="bool" sizeop="1"/>
<!-- 32-bit unsigned integer, SEMANTIC value BYTES -->
- <primary_type symbol="BYTES" datatype="U4" contenttype="BYTES"
- type="u4" sizeop="sizeof(u4)"/>
+ <primary_type symbol="BYTES" datatype="U8" contenttype="BYTES"
+ type="u8" sizeop="sizeof(u8)"/>
- <primary_type symbol="IOBYTES" datatype="U4" contenttype="BYTES"
- type="u4" sizeop="sizeof(u4)"/>
+ <primary_type symbol="IOBYTES" datatype="U8" contenttype="BYTES"
+ type="u8" sizeop="sizeof(u8)"/>
<!-- 64-bit unsigned integer, SEMANTIC value BYTES -->
<primary_type symbol="BYTES64" datatype="U8" contenttype="BYTES"
@@ -280,122 +269,109 @@
type="u8" sizeop="sizeof(u8)"/>
<!-- 32-bit float, SEMANTIC value PERCENTAGE (0.0-1.0) -->
- <primary_type symbol="PERCENT" datatype="FLOAT" contenttype="PERCENTAGE"
+ <primary_type symbol="PERCENTAGE" datatype="FLOAT" contenttype="PERCENTAGE"
type="float" sizeop="sizeof(float)"/>
- <!-- UTF-encoded string, max length 64k -->
+ <!-- UTF8-encoded string, max length Integer.MAX_VALUE -->
<primary_type symbol="UTF8" datatype="UTF8" contenttype="NONE"
- type="const char *" sizeop="sizeof_utf(%)"/>
-
- <!-- UTF-16 encoded (Unicode) string, max length maxjuint -->
- <primary_type symbol="STRING" datatype="STRING" contenttype="NONE"
- type="TraceUnicodeString*" sizeop="sizeof_unicode(%)"/>
+ type="const char*" sizeop="sizeof_utf(%)"/>
<!-- Symbol* constant. Note that this may currently ONLY be used by
classes, methods fields. This restriction might be lifted. -->
<primary_type symbol="SYMBOL" datatype="U8" contenttype="SYMBOL"
- type="Symbol *" sizeop="sizeof(u8)"/>
+ type="const Symbol*" sizeop="sizeof(u8)"/>
<!-- A Klass *. The actual class is marked as "used" and will
eventually be written into the recording constant pool -->
<primary_type symbol="CLASS" datatype="U8" contenttype="CLASS"
- type="Klass *" sizeop="sizeof(u8)"/>
+ type="const Klass*" sizeop="sizeof(u8)"/>
<!-- A Method *. The method is marked as "used" and will eventually be
written into the recording constant pool. -->
<primary_type symbol="METHOD" datatype="U8" contenttype="METHOD"
- type="Method *" sizeop="sizeof(u8)"/>
+ type="const Method*" sizeop="sizeof(u8)"/>
<!-- The type for stacktraces in the recording. Shoudl not be used by
events explicitly -->
<primary_type symbol="STACKTRACE" datatype="U8" contenttype="STACKTRACE"
type="u8" sizeop="sizeof(u8)"/>
- <!-- OS Thread ID -->
- <primary_type symbol="OSTHREAD" datatype="U4" contenttype="OSTHREAD"
- type="u4" sizeop="sizeof(u4)"/>
-
- <!-- VM Thread ID Note: changed from U2 to U8 for hotspot -->
- <primary_type symbol="VMTHREAD" datatype="U8" contenttype="VMTHREAD"
- type="u8" sizeop="sizeof(u8)"/>
-
- <!-- Java Thread ID -->
- <primary_type symbol="JAVALANGTHREAD" datatype="LONG"
- contenttype="JAVALANGTHREAD" type="s8"
- sizeop="sizeof(s8)"/>
+ <!-- Thread ID -->
+ <primary_type symbol="THREAD" datatype="U8" contenttype="THREAD"
+ type="u8" sizeop="sizeof(u8)"/>
<!-- Threadgroup THIS TYPE MAY NOT BE USED IN NORMAL EVENTS (ATM). Only
for thread constant pool // KK TODO: u8 should be ObjectP -->
- <primary_type symbol="THREADGROUP" datatype="U4" contenttype="THREADGROUP"
+ <primary_type symbol="THREADGROUP" datatype="U8" contenttype="THREADGROUP"
type="u8"
- sizeop="sizeof(u4)"/>
+ sizeop="sizeof(u8)"/>
<!-- FRAMETYPE enum -->
- <primary_type symbol="FRAMETYPE" datatype="U1" contenttype="FRAMETYPE"
- type="u1" sizeop="sizeof(u1)"/>
+ <primary_type symbol="FRAMETYPE" datatype="U8" contenttype="FRAMETYPE"
+ type="u8" sizeop="sizeof(u8)"/>
<!-- THREADSTATE enum -->
- <primary_type symbol="THREADSTATE" datatype="U2" contenttype="THREADSTATE"
- type="u2" sizeop="sizeof(u2)"/>
+ <primary_type symbol="THREADSTATE" datatype="U8" contenttype="THREADSTATE"
+ type="u8" sizeop="sizeof(u8)"/>
<!-- GCName -->
- <primary_type symbol="GCNAME" datatype="U1" contenttype="GCNAME"
- type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="GCNAME" datatype="U8" contenttype="GCNAME"
+ type="u8" sizeop="sizeof(u8)" />
<!-- GCCAUSE -->
- <primary_type symbol="GCCAUSE" datatype="U2" contenttype="GCCAUSE"
- type="u2" sizeop="sizeof(u2)" />
+ <primary_type symbol="GCCAUSE" datatype="U8" contenttype="GCCAUSE"
+ type="u8" sizeop="sizeof(u8)" />
<!-- GCWHEN -->
- <primary_type symbol="GCWHEN" datatype="U1" contenttype="GCWHEN"
- type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="GCWHEN" datatype="U8" contenttype="GCWHEN"
+ type="u8" sizeop="sizeof(u8)" />
<!-- G1HEAPREGIONTYPE -->
- <primary_type symbol="G1HEAPREGIONTYPE" datatype="U1" contenttype="G1HEAPREGIONTYPE"
- type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="G1HEAPREGIONTYPE" datatype="U8" contenttype="G1HEAPREGIONTYPE"
+ type="u8" sizeop="sizeof(u8)" />
<!-- G1YCType -->
- <primary_type symbol="G1YCTYPE" datatype="U1" contenttype="G1YCTYPE"
- type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="G1YCTYPE" datatype="U8" contenttype="G1YCTYPE"
+ type="u8" sizeop="sizeof(u8)" />
<!-- GCTHRESHOLDUPDATER -->
- <primary_type symbol="GCTHRESHOLDUPDATER" datatype="U1" contenttype="GCTHRESHOLDUPDATER"
- type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="GCTHRESHOLDUPDATER" datatype="U8" contenttype="GCTHRESHOLDUPDATER"
+ type="u8" sizeop="sizeof(u8)" />
<!-- REFERENCETYPE -->
- <primary_type symbol="REFERENCETYPE" datatype="U1"
- contenttype="REFERENCETYPE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="REFERENCETYPE" datatype="U8"
+ contenttype="REFERENCETYPE" type="u8" sizeop="sizeof(u8)" />
<!-- METADATATYPE -->
- <primary_type symbol="METADATATYPE" datatype="U1"
- contenttype="METADATATYPE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="METADATATYPE" datatype="U8"
+ contenttype="METADATATYPE" type="u8" sizeop="sizeof(u8)" />
<!-- METADATAOBJTYPE -->
- <primary_type symbol="METASPACEOBJTYPE" datatype="U1"
- contenttype="METASPACEOBJTYPE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="METASPACEOBJTYPE" datatype="U8"
+ contenttype="METASPACEOBJTYPE" type="u8" sizeop="sizeof(u8)" />
<!-- NARROWOOPMODE -->
- <primary_type symbol="NARROWOOPMODE" datatype="U1"
- contenttype="NARROWOOPMODE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="NARROWOOPMODE" datatype="U8"
+ contenttype="NARROWOOPMODE" type="u8" sizeop="sizeof(u8)" />
<!-- COMPILERPHASETYPE -->
- <primary_type symbol="COMPILERPHASETYPE" datatype="U1"
- contenttype="COMPILERPHASETYPE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="COMPILERPHASETYPE" datatype="U8"
+ contenttype="COMPILERPHASETYPE" type="u8" sizeop="sizeof(u8)" />
<!-- VMOPERATIONTYPE -->
- <primary_type symbol="VMOPERATIONTYPE" datatype="U2" contenttype="VMOPERATIONTYPE"
- type="u2" sizeop="sizeof(u2)" />
+ <primary_type symbol="VMOPERATIONTYPE" datatype="U8" contenttype="VMOPERATIONTYPE"
+ type="u8" sizeop="sizeof(u8)" />
<!-- FLAGVALUEORIGIN -->
- <primary_type symbol="FLAGVALUEORIGIN" datatype="U1"
- contenttype="FLAGVALUEORIGIN" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="FLAGVALUEORIGIN" datatype="U8"
+ contenttype="FLAGVALUEORIGIN" type="u8" sizeop="sizeof(u8)" />
<!-- CODEBLOBTYPE -->
- <primary_type symbol="CODEBLOBTYPE" datatype="U1"
- contenttype="CODEBLOBTYPE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="CODEBLOBTYPE" datatype="U8"
+ contenttype="CODEBLOBTYPE" type="u8" sizeop="sizeof(u8)" />
<!-- INFLATECAUSE -->
- <primary_type symbol="INFLATECAUSE" datatype="U1"
- contenttype="INFLATECAUSE" type="u1" sizeop="sizeof(u1)" />
+ <primary_type symbol="INFLATECAUSE" datatype="U8"
+ contenttype="INFLATECAUSE" type="u8" sizeop="sizeof(u8)" />
</primary_types>
</types>
--- a/hotspot/src/share/vm/utilities/debug.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/utilities/debug.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -51,9 +51,14 @@
#include "services/heapDumper.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
+#include "utilities/macros.hpp"
#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
+#if INCLUDE_TRACE
+#include "trace/tracing.hpp"
+#endif
+
#ifndef ASSERT
# ifdef _DEBUG
// NOTE: don't turn the lines below into a comment -- if you're getting
@@ -280,6 +285,12 @@
exit(2);
}
+static void notify_tracing() {
+#if INCLUDE_TRACE
+ Tracing::on_vm_error(true);
+#endif
+}
+
void report_insufficient_metaspace(size_t required_size) {
warning("\nThe MaxMetaspaceSize of " SIZE_FORMAT " bytes is not large enough.\n"
"Either don't specify the -XX:MaxMetaspaceSize=<size>\n"
@@ -302,6 +313,8 @@
HeapDumper::dump_heap_from_oome();
}
+ notify_tracing();
+
if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
VMError::report_java_out_of_memory(message);
}
--- a/hotspot/src/share/vm/utilities/hashtable.cpp Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp Sat Mar 05 10:10:23 2016 +0100
@@ -383,4 +383,9 @@
template class BasicHashtable<mtSymbol>;
template class BasicHashtable<mtCode>;
template class BasicHashtable<mtInternal>;
+#if INCLUDE_TRACE
+template class Hashtable<Symbol*, mtTracing>;
+template class HashtableEntry<Symbol*, mtTracing>;
+template class BasicHashtable<mtTracing>;
+#endif
template class BasicHashtable<mtCompiler>;
--- a/hotspot/test/gc/g1/TestGCLogMessages.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test TestGCLogMessages
- * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330
+ * @bug 8035406 8027295 8035398 8019342 8027959 8048179 8027962 8069330 8076463 8150630
* @summary Ensure the output for a minor GC with G1
* includes the expected necessary messages.
* @key gc
@@ -38,10 +38,24 @@
public class TestGCLogMessages {
private enum Level {
- OFF, DEBUG, TRACE;
- public boolean lessOrEqualTo(Level other) {
+ OFF(""),
+ INFO("info"),
+ DEBUG("debug"),
+ TRACE("trace");
+
+ private String logName;
+
+ Level(String logName) {
+ this.logName = logName;
+ }
+
+ public boolean lessThan(Level other) {
return this.compareTo(other) < 0;
}
+
+ public String toString() {
+ return logName;
+ }
}
private class LogMessageWithLevel {
@@ -56,44 +70,48 @@
private LogMessageWithLevel allLogMessages[] = new LogMessageWithLevel[] {
// Update RS
- new LogMessageWithLevel("Scan HCC", Level.DEBUG),
+ new LogMessageWithLevel("Scan HCC", Level.TRACE),
// Ext Root Scan
- 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),
+ new LogMessageWithLevel("Thread Roots", Level.TRACE),
+ new LogMessageWithLevel("StringTable Roots", Level.TRACE),
+ new LogMessageWithLevel("Universe Roots", Level.TRACE),
+ new LogMessageWithLevel("JNI Handles Roots", Level.TRACE),
+ new LogMessageWithLevel("ObjectSynchronizer Roots", Level.TRACE),
+ new LogMessageWithLevel("FlatProfiler Roots", Level.TRACE),
+ new LogMessageWithLevel("Management Roots", Level.TRACE),
+ new LogMessageWithLevel("SystemDictionary Roots", Level.TRACE),
+ new LogMessageWithLevel("CLDG Roots", Level.TRACE),
+ new LogMessageWithLevel("JVMTI Roots", Level.TRACE),
+ new LogMessageWithLevel("SATB Filtering", Level.TRACE),
+ new LogMessageWithLevel("CM RefProcessor Roots", Level.TRACE),
+ new LogMessageWithLevel("Wait For Strong CLD", Level.TRACE),
+ new LogMessageWithLevel("Weak CLD Roots", Level.TRACE),
// Redirty Cards
new LogMessageWithLevel("Redirty Cards", Level.DEBUG),
- new LogMessageWithLevel("Parallel Redirty", Level.DEBUG),
- new LogMessageWithLevel("Redirtied Cards", Level.DEBUG),
+ new LogMessageWithLevel("Parallel Redirty", Level.TRACE),
+ new LogMessageWithLevel("Redirtied Cards", Level.TRACE),
// Misc Top-level
- new LogMessageWithLevel("Code Root Purge", Level.DEBUG),
- new LogMessageWithLevel("String Dedup Fixup", Level.DEBUG),
- new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG),
+ new LogMessageWithLevel("Code Roots Purge", Level.DEBUG),
+ new LogMessageWithLevel("String Dedup Fixup", Level.INFO),
+ new LogMessageWithLevel("Expand Heap After Collection", Level.INFO),
// Free CSet
- new LogMessageWithLevel("Young Free CSet", Level.TRACE),
- new LogMessageWithLevel("Non-Young Free CSet", Level.TRACE),
+ new LogMessageWithLevel("Young Free Collection Set", Level.DEBUG),
+ new LogMessageWithLevel("Non-Young Free Collection Set", Level.DEBUG),
// Humongous Eager Reclaim
new LogMessageWithLevel("Humongous Reclaim", Level.DEBUG),
new LogMessageWithLevel("Humongous Register", Level.DEBUG),
+ // Preserve CM Referents
+ new LogMessageWithLevel("Preserve CM Refs", Level.DEBUG),
+ // Merge PSS
+ new LogMessageWithLevel("Merge Per-Thread State", Level.INFO),
};
void checkMessagesAtLevel(OutputAnalyzer output, LogMessageWithLevel messages[], Level level) throws Exception {
for (LogMessageWithLevel l : messages) {
- if (level.lessOrEqualTo(l.level)) {
+ if (level.lessThan(l.level)) {
output.shouldNotContain(l.message);
} else {
- output.shouldContain(l.message);
+ output.shouldMatch("\\[" + l.level + ".*" + l.message);
}
}
}
--- a/hotspot/test/gc/g1/TestPLABOutput.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/gc/g1/TestPLABOutput.java Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,7 @@
System.out.println(output.getStdout());
- String pattern = ".*GC\\(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/plab/TestPLABPromotion.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/gc/g1/plab/TestPLABPromotion.java Sat Mar 05 10:10:23 2016 +0100
@@ -23,7 +23,7 @@
/*
* @test TestPLABPromotion
- * @bug 8141278
+ * @bug 8141278 8141141
* @summary Test PLAB promotion
* @requires vm.gc=="G1" | vm.gc=="null"
* @requires vm.opt.FlightRecorder != true
@@ -130,16 +130,15 @@
long plabAllocatedOld;
long directAllocatedOld;
long memAllocated = testCase.getMemToFill();
- long wordSize = Platform.is32bit() ? 4l : 8l;
LogParser logParser = new LogParser(output);
Map<String, Long> survivorStats = getPlabStats(logParser, LogParser.ReportType.SURVIVOR_STATS, GC_ID_SURVIVOR_STATS);
Map<String, Long> oldStats = getPlabStats(logParser, LogParser.ReportType.OLD_STATS, GC_ID_OLD_STATS);
- plabAllocatedSurvivor = wordSize * survivorStats.get("used");
- directAllocatedSurvivor = wordSize * survivorStats.get("direct_allocated");
- plabAllocatedOld = wordSize * oldStats.get("used");
- directAllocatedOld = wordSize * oldStats.get("direct_allocated");
+ plabAllocatedSurvivor = survivorStats.get("used");
+ directAllocatedSurvivor = survivorStats.get("direct allocated");
+ plabAllocatedOld = oldStats.get("used");
+ directAllocatedOld = oldStats.get("direct allocated");
System.out.printf("Survivor PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedSurvivor, directAllocatedSurvivor, memAllocated);
System.out.printf("Old PLAB allocated:%17d Direct allocated: %17d Mem consumed:%17d%n", plabAllocatedOld, directAllocatedOld, memAllocated);
--- a/hotspot/test/gc/g1/plab/TestPLABResize.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/gc/g1/plab/TestPLABResize.java Sat Mar 05 10:10:23 2016 +0100
@@ -23,7 +23,7 @@
/*
* @test TestPLABResize
- * @bug 8141278
+ * @bug 8141278 8141141
* @summary Test for PLAB resizing
* @requires vm.gc=="G1" | vm.gc=="null"
* @requires vm.opt.FlightRecorder != true
@@ -117,7 +117,7 @@
.map(item -> {
return item.getValue()
.get(LogParser.ReportType.SURVIVOR_STATS)
- .get("desired_plab_sz");
+ .get("actual");
})
.collect(Collectors.toCollection(ArrayList::new));
--- a/hotspot/test/gc/g1/plab/lib/LogParser.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/gc/g1/plab/lib/LogParser.java Sat Mar 05 10:10:23 2016 +0100
@@ -35,14 +35,12 @@
*
* Typical GC log with PLAB statistics (options - -Xlog:gc=debug,gc+plab=debug) looks like:
*
- * [2,244s][info ][gc ] GC(30) Concurrent Mark abort
- * [2,245s][debug ][gc,plab] GC(33) (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0) (plab_sz = 0 desired_plab_sz = 258)
- * [2,245s][debug ][gc,plab] GC(33) (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0) (plab_sz = 0 desired_plab_sz = 258)
- * [2,245s][info ][gc ] GC(33) Pause Young (G1 Evacuation Pause) 127M->127M(128M) (2,244s, 2,245s) 0,899ms
- * [2,246s][debug ][gc,plab] GC(34) (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0) (plab_sz = 0 desired_plab_sz = 258)
- * [2,246s][debug ][gc,plab] GC(34) (allocated = 1 wasted = 0 unused = 0 used = 1 undo_waste = 0 region_end_waste = 0 regions filled = 0 direct_allocated = 0 failure_used = 0 failure_waste = 0) (plab_sz = 0 desired_plab_sz = 258)
- * [2,246s][info ][gc ] GC(34) Pause Initial Mark (G1 Evacuation Pause) 127M->127M(128M) (2,245s, 2,246s) 0,907ms
-
+ * [0.330s][debug][gc,plab ] GC(0) Young PLAB allocation: allocated: 1825632B, wasted: 29424B, unused: 2320B, used: 1793888B, undo waste: 0B,
+ * [0.330s][debug][gc,plab ] GC(0) Young other allocation: region end waste: 0B, regions filled: 2, direct allocated: 271520B, failure used: 0B, failure wasted: 0B
+ * [0.330s][debug][gc,plab ] GC(0) Young sizing: calculated: 358776B, actual: 358776B
+ * [0.330s][debug][gc,plab ] GC(0) Old PLAB allocation: allocated: 427248B, wasted: 592B, unused: 368584B, used: 58072B, undo waste: 0B,
+ * [0.330s][debug][gc,plab ] GC(0) Old other allocation: region end waste: 0B, regions filled: 1, direct allocated: 41704B, failure used: 0B, failure wasted: 0B
+ * [0.330s][debug][gc,plab ] GC(0) Old sizing: calculated: 11608B, actual: 11608B
*/
final public class LogParser {
@@ -53,7 +51,6 @@
* Type of parsed log element.
*/
public static enum ReportType {
-
SURVIVOR_STATS,
OLD_STATS
}
@@ -64,8 +61,8 @@
// GC ID
private static final Pattern GC_ID_PATTERN = Pattern.compile("\\[gc,plab\\s*\\] GC\\((\\d+)\\)");
- // Pattern for extraction pair <name>=<numeric value>
- private static final Pattern PAIRS_PATTERN = Pattern.compile("\\w+\\s+=\\s+\\d+");
+ // Pattern for extraction pair <name>: <numeric value>
+ private static final Pattern PAIRS_PATTERN = Pattern.compile("\\w* \\w+:\\s+\\d+");
/**
* Construct LogParser Object
@@ -108,24 +105,29 @@
if (matcher.find()) {
Map<ReportType,Map<String, Long>> oneReportItem;
ReportType reportType;
- // Second line in log is statistics for Old PLAB allocation
- if ( !allocationStatistics.containsKey(gc_id.get()) ) {
- oneReportItem = new EnumMap<>(ReportType.class);
+
+ if (!allocationStatistics.containsKey(gc_id.get())) {
+ allocationStatistics.put(gc_id.get(), new EnumMap<>(ReportType.class));
+ }
+
+ if ( line.contains("Young") ) {
reportType = ReportType.SURVIVOR_STATS;
- allocationStatistics.put(gc_id.get(), oneReportItem);
} else {
- oneReportItem = allocationStatistics.get(gc_id.get());
reportType = ReportType.OLD_STATS;
}
+ oneReportItem = allocationStatistics.get(gc_id.get());
+ if (!oneReportItem.containsKey(reportType)) {
+ oneReportItem.put(reportType,new HashMap<String, Long>());
+ }
+
// Extract all pairs from log.
- HashMap<String, Long> plabStats = new HashMap<>();
+ Map<String, Long> plabStats = oneReportItem.get(reportType);
do {
String pair = matcher.group();
- String[] nameValue = pair.replaceAll(" ", "").split("=");
- plabStats.put(nameValue[0], Long.parseLong(nameValue[1]));
+ String[] nameValue = pair.replaceAll(": ", ":").split(":");
+ plabStats.put(nameValue[0].trim(), Long.parseLong(nameValue[1]));
} while (matcher.find());
- oneReportItem.put(reportType,plabStats);
}
}
}
--- a/hotspot/test/native_sanity/JniVersion.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/native_sanity/JniVersion.java Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,12 @@
*/
public class JniVersion {
- public static final int JNI_VERSION_1_8 = 0x00010008;
+ public static final int JNI_VERSION_9 = 0x00090000;
public static void main(String... args) throws Exception {
System.loadLibrary("JniVersion");
int res = getJniVersion();
- if (res < JNI_VERSION_1_8) {
+ if (res != JNI_VERSION_9) {
throw new Exception("Unexpected value returned from getJniVersion(): 0x" + Integer.toHexString(res));
}
}
--- a/hotspot/test/runtime/logging/ItablesTest.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/runtime/logging/ItablesTest.java Sat Mar 05 10:10:23 2016 +0100
@@ -49,7 +49,6 @@
output.shouldContain("invokespecial resolved method: caller-class:ClassB");
output.shouldContain("invokespecial selected method: resolved-class:ClassB");
output.shouldContain("invokeinterface selected method: receiver-class");
- output.shouldContain("Resolving: klass: ");
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder("-Xlog:itables=trace", "ItablesVtableTest");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/ProtectionDomainVerificationTest.java Sat Mar 05 10:10:23 2016 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test ProtectionDomainVerificationTest
+ * @bug 8149064
+ * @library /testlibrary
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.Platform jdk.test.lib.ProcessTools
+ * @run driver ProtectionDomainVerificationTest
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class ProtectionDomainVerificationTest {
+
+ public static void main(String... args) throws Exception {
+
+ // -Xlog:protectiondomain=trace
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:protectiondomain=trace",
+ "-Xmx64m",
+ Hello.class.getName());
+ OutputAnalyzer out = new OutputAnalyzer(pb.start());
+ out.shouldContain("[protectiondomain] Checking package access");
+ out.shouldContain("[protectiondomain] pd set count = #");
+
+ // -Xlog:protectiondomain=debug
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:protectiondomain=debug",
+ "-Xmx64m",
+ Hello.class.getName());
+ out = new OutputAnalyzer(pb.start());
+ out.shouldContain("[protectiondomain] Checking package access");
+ out.shouldNotContain("pd set count = #");
+ }
+
+ public static class Hello {
+ public static void main(String[] args) {
+ System.out.print("Hello!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/ThreadLoggingTest.java Sat Mar 05 10:10:23 2016 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8149036 8150619
+ * @summary os+thread output should contain logging calls for thread start stop attaches detaches
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ * java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools
+ * @run driver ThreadLoggingTest
+ * @author Thomas Stuefe (SAP)
+ */
+
+import java.io.File;
+import java.util.Map;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+
+public class ThreadLoggingTest {
+
+ static void analyzeOutputForInfoLevel(OutputAnalyzer output) throws Exception {
+ output.shouldContain("Thread started");
+ output.shouldContain("Thread is alive");
+ output.shouldContain("Thread finished");
+ output.shouldHaveExitValue(0);
+ }
+
+ static void analyzeOutputForDebugLevel(OutputAnalyzer output) throws Exception {
+ analyzeOutputForInfoLevel(output);
+ output.shouldContain("stack dimensions");
+ output.shouldContain("stack guard pages");
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:os+thread", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ analyzeOutputForInfoLevel(output);
+
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:os+thread=debug", "-version");
+ output = new OutputAnalyzer(pb.start());
+ analyzeOutputForDebugLevel(output);
+
+ }
+
+}
--- a/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java Sat Mar 05 10:10:23 2016 +0100
@@ -22,6 +22,10 @@
*/
import java.io.*;
import java.nio.file.*;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
import jdk.test.lib.*;
import jdk.test.lib.dcmd.*;
import org.testng.annotations.Test;
@@ -55,12 +59,7 @@
"'-Dtest.jdk=/path/to/jdk'.");
}
- Path libpath;
- if (Platform.isWindows()) {
- libpath = Paths.get(jdkPath, "bin", "instrument.dll");
- } else {
- libpath = Paths.get(jdkPath, "lib", Platform.getOsArch(), "libinstrument.so");
- }
+ Path libpath = Paths.get(jdkPath, Platform.jdkLibPath(), Platform.sharedObjectName("instrument"));
if (!libpath.toFile().exists()) {
throw new FileNotFoundException(
@@ -70,31 +69,62 @@
return libpath.toAbsolutePath().toString();
}
+
+ public void createJarFileForAgent()
+ throws IOException {
+
+ final String jarName = "agent.jar";
+ final String agentClass = "SimpleJvmtiAgent";
+
+ Manifest manifest = new Manifest();
+
+ manifest.getMainAttributes().put(
+ Attributes.Name.MANIFEST_VERSION, "1.0");
+
+ manifest.getMainAttributes().put(
+ new Attributes.Name("Agent-Class"), agentClass);
+
+ JarOutputStream target = null;
+
+ try {
+ target = new
+ JarOutputStream(new FileOutputStream(jarName), manifest);
+ JarEntry entry = new JarEntry(agentClass + ".class");
+ target.putNextEntry(entry);
+ target.closeEntry();
+ } finally {
+ target.close();
+ }
+ }
+
public void run(CommandExecutor executor) {
try{
- PrintWriter pw = new PrintWriter("MANIFEST.MF");
- pw.println("Agent-Class: SimpleJvmtiAgent");
- pw.close();
- ProcessBuilder pb = new ProcessBuilder();
- pb.command(new String[] { JDKToolFinder.getJDKTool("jar"),
- "cmf",
- "MANIFEST.MF",
- "agent.jar",
- "SimpleJvmtiAgent.class"});
- pb.start().waitFor();
+ createJarFileForAgent();
String libpath = getLibInstrumentPath();
+ OutputAnalyzer output = null;
- // Test 1: No argument
- OutputAnalyzer output = executor.execute("JVMTI.agent_load " +
- libpath + " agent.jar");
+ // Test 1: Native agent, no arguments
+ output = executor.execute("JVMTI.agent_load " +
+ libpath + " agent.jar");
output.stderrShouldBeEmpty();
- // Test 2: With argument
+ // Test 2: Native agent, with arguments
+ output = executor.execute("JVMTI.agent_load " +
+ libpath + " \"agent.jar=foo=bar\"");
+ output.stderrShouldBeEmpty();
+
+ // Test 3: Java agent, no arguments
output = executor.execute("JVMTI.agent_load " +
- libpath + " \"agent.jar=foo=bar\"");
+ "agent.jar");
output.stderrShouldBeEmpty();
+
+ // Test 4: Java agent, with arguments
+ output = executor.execute("JVMTI.agent_load " +
+ "\"agent.jar=foo=bar\"");
+ output.stderrShouldBeEmpty();
+
} catch (Exception e) {
throw new RuntimeException(e);
}
--- a/hotspot/test/serviceability/dcmd/jvmti/LoadJavaAgentDcmdTest.java Thu Mar 03 14:07:10 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-import java.io.*;
-import jdk.test.lib.*;
-import jdk.test.lib.dcmd.*;
-import org.testng.annotations.Test;
-
-/*
- * Test to attach JVMTI java agent.
- *
- * @test
- * @bug 8147388
- * @library /testlibrary
- * @modules java.base/sun.misc
- * java.compiler
- * java.instrument
- * java.management
- * jdk.jvmstat/sun.jvmstat.monitor
- * @build ClassFileInstaller jdk.test.lib.* SimpleJvmtiAgent
- * @run main ClassFileInstaller SimpleJvmtiAgent
- * @run testng LoadJavaAgentDcmdTest
- */
-public class LoadJavaAgentDcmdTest {
- public void run(CommandExecutor executor) {
- try{
- PrintWriter pw = new PrintWriter("MANIFEST.MF");
- pw.println("Agent-Class: SimpleJvmtiAgent");
- pw.close();
-
- ProcessBuilder pb = new ProcessBuilder();
- pb.command(new String[] { JDKToolFinder.getJDKTool("jar"),
- "cmf",
- "MANIFEST.MF",
- "agent.jar",
- "SimpleJvmtiAgent.class"});
- pb.start().waitFor();
-
- // Test 1: No argument
- OutputAnalyzer output = executor.execute("JVMTI.agent_load " +
- "agent.jar");
- output.stderrShouldBeEmpty();
-
- // Test 2: With argument
- output = executor.execute("JVMTI.agent_load " +
- "\"agent.jar=foo=bar\"");
- output.stderrShouldBeEmpty();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Test
- public void jmx() throws Throwable {
- run(new JMXExecutor());
- }
-
- @Test
- public void cli() throws Throwable {
- run(new PidJcmdExecutor());
- }
-}
--- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,6 @@
public class JMapHProfLargeHeapTest {
private static final String HEAP_DUMP_FILE_NAME = "heap.hprof";
- private static final String HPROF_HEADER_1_0_1 = "JAVA PROFILE 1.0.1";
private static final String HPROF_HEADER_1_0_2 = "JAVA PROFILE 1.0.2";
private static final long M = 1024L;
private static final long G = 1024L * M;
@@ -79,8 +78,8 @@
}
}
- // Small heap 22 megabytes, should create 1.0.1 file format
- testHProfFileFormat("-Xmx1g", 22 * M, HPROF_HEADER_1_0_1);
+ // All heap dumps should create 1.0.2 file format
+ testHProfFileFormat("-Xmx1g", 22 * M, HPROF_HEADER_1_0_2);
/**
* This test was deliberately commented out since the test system lacks
--- a/hotspot/test/testlibrary/jdk/test/lib/Platform.java Thu Mar 03 14:07:10 2016 +0000
+++ b/hotspot/test/testlibrary/jdk/test/lib/Platform.java Sat Mar 05 10:10:23 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -203,4 +203,31 @@
public static boolean canAttachOSX() throws Exception {
return userName.equals("root");
}
+
+ /**
+ * return path to library inside jdk tree
+ */
+ public static String jdkLibPath() {
+ if (isWindows()) {
+ return "bin";
+ }
+ if (isOSX()) {
+ return "lib";
+ }
+
+ return "lib/" + getOsArch();
+ }
+
+ /**
+ * Build name of shared object according to platform rules
+ */
+ public static String sharedObjectName(String name) {
+ if (isWindows()) {
+ return name + ".dll";
+ }
+ if (isOSX()) {
+ return "lib" + name + ".dylib";
+ }
+ return "lib" + name + ".so";
+ }
}