changeset 37267:ad8c0e8de29f

Merge
author dcubed
date Thu, 07 Apr 2016 09:47:48 -0700
parents 33688f44fb2a e7fe9a7bd991
children b2c690909eea 5b1720e87eda
files hotspot/src/share/vm/c1/c1_GraphBuilder.cpp hotspot/src/share/vm/ci/ciEnv.cpp hotspot/src/share/vm/classfile/systemDictionary.cpp hotspot/src/share/vm/classfile/vmSymbols.hpp hotspot/src/share/vm/code/nmethod.cpp hotspot/src/share/vm/compiler/compileBroker.cpp hotspot/src/share/vm/gc/shared/liveRange.hpp hotspot/src/share/vm/interpreter/linkResolver.cpp hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp hotspot/src/share/vm/jvmci/jvmciRuntime.cpp hotspot/src/share/vm/memory/metaspace.cpp hotspot/src/share/vm/oops/method.cpp hotspot/src/share/vm/opto/library_call.cpp hotspot/src/share/vm/opto/memnode.cpp hotspot/src/share/vm/prims/methodHandles.cpp hotspot/src/share/vm/prims/unsafe.cpp hotspot/src/share/vm/runtime/globals.hpp hotspot/src/share/vm/runtime/logTimer.hpp hotspot/src/share/vm/services/diagnosticCommand.cpp hotspot/src/share/vm/trace/trace.xml hotspot/src/share/vm/trace/traceevents.xml hotspot/src/share/vm/trace/tracerelationdecls.xml hotspot/src/share/vm/utilities/globalDefinitions.hpp hotspot/test/TEST.groups hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java
diffstat 476 files changed, 22533 insertions(+), 6348 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/make/aix/adlc_updater	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/aix/adlc_updater	Thu Apr 07 09:47:48 2016 -0700
@@ -9,12 +9,15 @@
 #
 fix_lines() {
   # repair bare #line directives in $1 to refer to $2
-  awk < $1 > $1+ '
+  # and add an override of __FILE__ with just the basename on the
+  # first line of the file.
+  awk < $1 > $1+ -v F2=$2 '
+    BEGIN { print "#line 1 \"" F2 "\""; }
     /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
     {print}
-  ' F2=$2
+  '
   mv $1+ $1
 }
-fix_lines $2/$1 $3/$1
+fix_lines $2/$1 $1
 [ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
 ( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/aix/makefiles/trace.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/aix/makefiles/trace.make	Thu Apr 07 09:47:48 2016 -0700
@@ -27,14 +27,17 @@
 #
 # It knows how to build and run the tools to generate trace files.
 
-include $(GAMMADIR)/make/linux/makefiles/rules.make
+include $(GAMMADIR)/make/aix/makefiles/rules.make
 include $(GAMMADIR)/make/altsrc.make
 
 # #########################################################################
 
-HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
-  echo "true"; else echo "false";\
-  fi)
+HAS_ALT_SRC := false
+ifndef OPENJDK
+  ifneq ($(wildcard $(HS_ALT_SRC)/share/vm/trace), )
+    HAS_ALT_SRC := true
+  endif
+endif
 
 TOPDIR      = $(shell echo `pwd`)
 GENERATED   = $(TOPDIR)/../generated
@@ -50,23 +53,30 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-	traceEventIds.hpp     \
-	traceTypes.hpp
+    traceEventIds.hpp     \
+    traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-TraceGeneratedNames +=  \
-	traceRequestables.hpp \
-    traceEventControl.hpp
+  TraceGeneratedNames +=  \
+      traceRequestables.hpp \
+      traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
 
 XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
 
-XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
-	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+TraceXml = $(TraceSrcDir)/trace.xml
 ifeq ($(HAS_ALT_SRC), true)
-	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+  TraceXml = $(TraceAltSrcDir)/trace.xml
+endif
+
+XML_DEPS = $(TraceXml) $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod \
+    $(TraceSrcDir)/tracerelationdecls.xml $(TraceSrcDir)/traceevents.xml
+ifeq ($(HAS_ALT_SRC), true)
+  XML_DEPS += $(TraceAltSrcDir)/traceeventscustom.xml \
+      $(TraceAltSrcDir)/traceeventtypes.xml
 endif
 
 .PHONY: all clean cleanall
@@ -79,26 +89,26 @@
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
   $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
-$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventIds.hpp: $(TraceXml) $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+$(TraceOutDir)/traceTypes.hpp: $(TraceXml) $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 ifeq ($(HAS_ALT_SRC), false)
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 else
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+$(TraceOutDir)/traceRequestables.hpp: $(TraceXml) $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventControl.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 endif
--- a/hotspot/make/bsd/adlc_updater	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/bsd/adlc_updater	Thu Apr 07 09:47:48 2016 -0700
@@ -9,12 +9,15 @@
 #
 fix_lines() {
   # repair bare #line directives in $1 to refer to $2
-  awk < $1 > $1+ '
+  # and add an override of __FILE__ with just the basename on the
+  # first line of the file.
+  awk < $1 > $1+ -v F2=$2 '
+    BEGIN { print "#line 1 \"" F2 "\""; }
     /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
     {print}
-  ' F2=$2
+  '
   mv $1+ $1
 }
-fix_lines $2/$1 $3/$1
+fix_lines $2/$1 $1
 [ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
 ( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/bsd/makefiles/trace.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/bsd/makefiles/trace.make	Thu Apr 07 09:47:48 2016 -0700
@@ -32,9 +32,12 @@
 
 # #########################################################################
 
-HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
-  echo "true"; else echo "false";\
-  fi)
+HAS_ALT_SRC := false
+ifndef OPENJDK
+  ifneq ($(wildcard $(HS_ALT_SRC)/share/vm/trace), )
+    HAS_ALT_SRC := true
+  endif
+endif
 
 TOPDIR      = $(shell echo `pwd`)
 GENERATED   = $(TOPDIR)/../generated
@@ -50,24 +53,30 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-	traceEventIds.hpp     \
-	traceTypes.hpp
+    traceEventIds.hpp     \
+    traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-TraceGeneratedNames +=  \
-	traceRequestables.hpp \
-    traceEventControl.hpp
+  TraceGeneratedNames +=  \
+      traceRequestables.hpp \
+      traceEventControl.hpp
 endif
 
-
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
 
 XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
 
-XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
-	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+TraceXml = $(TraceSrcDir)/trace.xml
 ifeq ($(HAS_ALT_SRC), true)
-	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+  TraceXml = $(TraceAltSrcDir)/trace.xml
+endif
+
+XML_DEPS = $(TraceXml) $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod \
+    $(TraceSrcDir)/tracerelationdecls.xml $(TraceSrcDir)/traceevents.xml
+ifeq ($(HAS_ALT_SRC), true)
+  XML_DEPS += $(TraceAltSrcDir)/traceeventscustom.xml \
+      $(TraceAltSrcDir)/traceeventtypes.xml
 endif
 
 .PHONY: all clean cleanall
@@ -80,32 +89,31 @@
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
   $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
-$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventIds.hpp: $(TraceXml) $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+$(TraceOutDir)/traceTypes.hpp: $(TraceXml) $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 ifeq ($(HAS_ALT_SRC), false)
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 else
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+$(TraceOutDir)/traceRequestables.hpp: $(TraceXml) $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventControl.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 endif
 
 # #########################################################################
 
-
 clean cleanall:
 	rm $(TraceGeneratedFiles)
--- a/hotspot/make/linux/adlc_updater	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/linux/adlc_updater	Thu Apr 07 09:47:48 2016 -0700
@@ -9,12 +9,15 @@
 #
 fix_lines() {
   # repair bare #line directives in $1 to refer to $2
-  awk < $1 > $1+ '
+  # and add an override of __FILE__ with just the basename on the
+  # first line of the file.
+  awk < $1 > $1+ -v F2=$2 '
+    BEGIN { print "#line 1 \"" F2 "\""; }
     /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
     {print}
-  ' F2=$2
+  '
   mv $1+ $1
 }
-fix_lines $2/$1 $3/$1
+fix_lines $2/$1 $1
 [ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
 ( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/linux/makefiles/trace.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/linux/makefiles/trace.make	Thu Apr 07 09:47:48 2016 -0700
@@ -32,9 +32,12 @@
 
 # #########################################################################
 
-HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
-  echo "true"; else echo "false";\
-  fi)
+HAS_ALT_SRC := false
+ifndef OPENJDK
+  ifneq ($(wildcard $(HS_ALT_SRC)/share/vm/trace), )
+    HAS_ALT_SRC := true
+  endif
+endif
 
 TOPDIR      = $(shell echo `pwd`)
 GENERATED   = $(TOPDIR)/../generated
@@ -50,23 +53,30 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-	traceEventIds.hpp     \
-	traceTypes.hpp
+    traceEventIds.hpp     \
+    traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-TraceGeneratedNames +=  \
-	traceRequestables.hpp \
-    traceEventControl.hpp
+  TraceGeneratedNames +=  \
+      traceRequestables.hpp \
+      traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
 
 XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
 
-XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
-	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+TraceXml = $(TraceSrcDir)/trace.xml
 ifeq ($(HAS_ALT_SRC), true)
-	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+  TraceXml = $(TraceAltSrcDir)/trace.xml
+endif
+
+XML_DEPS = $(TraceXml) $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod \
+    $(TraceSrcDir)/tracerelationdecls.xml $(TraceSrcDir)/traceevents.xml
+ifeq ($(HAS_ALT_SRC), true)
+  XML_DEPS += $(TraceAltSrcDir)/traceeventscustom.xml \
+      $(TraceAltSrcDir)/traceeventtypes.xml
 endif
 
 .PHONY: all clean cleanall
@@ -79,26 +89,26 @@
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
   $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
-$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventIds.hpp: $(TraceXml) $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+$(TraceOutDir)/traceTypes.hpp: $(TraceXml) $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 ifeq ($(HAS_ALT_SRC), false)
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 else
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+$(TraceOutDir)/traceRequestables.hpp: $(TraceXml) $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventControl.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 endif
@@ -107,5 +117,3 @@
 
 clean cleanall:
 	rm $(TraceGeneratedFiles)
-
-
--- a/hotspot/make/share/makefiles/mapfile-vers	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/share/makefiles/mapfile-vers	Thu Apr 07 09:47:48 2016 -0700
@@ -109,8 +109,7 @@
                 JVM_GetPrimitiveArrayElement;
                 JVM_GetProtectionDomain;
                 JVM_GetStackAccessControlContext;
-                JVM_GetStackTraceDepth;
-                JVM_GetStackTraceElement;
+                JVM_GetStackTraceElements;
                 JVM_GetSystemPackage;
                 JVM_GetSystemPackages;
                 JVM_GetTemporaryDirectory;
--- a/hotspot/make/solaris/adlc_updater	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/solaris/adlc_updater	Thu Apr 07 09:47:48 2016 -0700
@@ -9,12 +9,15 @@
 #
 fix_lines() {
   # repair bare #line directives in $1 to refer to $2
-  awk < $1 > $1+ '
+  # and add an override of __FILE__ with just the basename on the
+  # first line of the file.
+  nawk < $1 > $1+ -v F2=$2 '
+    BEGIN { print "#line 1 \"" F2 "\""; }
     /^#line 999999$/ {print "#line " (NR+1) " \"" F2 "\""; next}
     {print}
-  ' F2=$2
+  '
   mv $1+ $1
 }
-fix_lines $2/$1 $3/$1
+fix_lines $2/$1 $1
 [ -f $3/$1 ] && cmp -s $2/$1 $3/$1 || \
 ( [ -f $3/$1 ] && echo Updating $3/$1 ; touch $2/made-change ; mv $2/$1 $3/$1 )
--- a/hotspot/make/solaris/makefiles/trace.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/solaris/makefiles/trace.make	Thu Apr 07 09:47:48 2016 -0700
@@ -32,9 +32,12 @@
 
 # #########################################################################
 
-HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
-  echo "true"; else echo "false";\
-  fi)
+HAS_ALT_SRC := false
+ifndef OPENJDK
+  ifneq ($(wildcard $(HS_ALT_SRC)/share/vm/trace), )
+    HAS_ALT_SRC := true
+  endif
+endif
 
 TOPDIR      = $(shell echo `pwd`)
 GENERATED   = $(TOPDIR)/../generated
@@ -50,23 +53,30 @@
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
-	traceEventIds.hpp     \
-	traceTypes.hpp
+    traceEventIds.hpp     \
+    traceTypes.hpp
 
 ifeq ($(HAS_ALT_SRC), true)
-TraceGeneratedNames +=  \
-	traceRequestables.hpp \
-    traceEventControl.hpp
+  TraceGeneratedNames +=  \
+      traceRequestables.hpp \
+      traceEventControl.hpp
 endif
 
 TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
 
 XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
 
-XML_DEPS =  $(TraceSrcDir)/trace.xml  $(TraceSrcDir)/tracetypes.xml \
-	$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+TraceXml = $(TraceSrcDir)/trace.xml
 ifeq ($(HAS_ALT_SRC), true)
-	XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+  TraceXml = $(TraceAltSrcDir)/trace.xml
+endif
+
+XML_DEPS = $(TraceXml) $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod \
+    $(TraceSrcDir)/tracerelationdecls.xml $(TraceSrcDir)/traceevents.xml
+ifeq ($(HAS_ALT_SRC), true)
+  XML_DEPS += $(TraceAltSrcDir)/traceeventscustom.xml \
+      $(TraceAltSrcDir)/traceeventtypes.xml
 endif
 
 .PHONY: all clean cleanall
@@ -79,26 +89,26 @@
   $(QUIETLY) echo $(LOG_INFO) Generating $@; \
   $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@
 
-$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventIds.hpp: $(TraceXml) $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+$(TraceOutDir)/traceTypes.hpp: $(TraceXml) $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 ifeq ($(HAS_ALT_SRC), false)
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 else
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+$(TraceOutDir)/traceRequestables.hpp: $(TraceXml) $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
-$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventControl.hpp: $(TraceXml) $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
 	$(GENERATE_CODE)
 
 endif
--- a/hotspot/make/windows/build.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/windows/build.make	Thu Apr 07 09:47:48 2016 -0700
@@ -114,11 +114,15 @@
 # Define HOTSPOT_VM_DISTRO based on settings in make/openjdk_distro
 # or make/hotspot_distro.
 !ifndef HOTSPOT_VM_DISTRO
+!ifndef OPENJDK
 !if exists($(WorkSpace)\src\closed)
 !include $(WorkSpace)\make\hotspot_distro
 !else
 !include $(WorkSpace)\make\openjdk_distro
 !endif
+!else
+!include $(WorkSpace)\make\openjdk_distro
+!endif
 !endif
 
 HS_FILEDESC=$(HOTSPOT_VM_DISTRO) $(ARCH_TEXT) $(VARIANT_TEXT) VM
--- a/hotspot/make/windows/create_obj_files.sh	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/windows/create_obj_files.sh	Thu Apr 07 09:47:48 2016 -0700
@@ -55,7 +55,11 @@
 ALTSRC_REL=src/closed # Change this to pick up alt sources from somewhere else
 
 COMMONSRC=${WorkSpace}/${COMMONSRC_REL}
-ALTSRC=${WorkSpace}/${ALTSRC_REL}
+if [ "x$OPENJDK" != "xtrue" ]; then
+  ALTSRC=${WorkSpace}/${ALTSRC_REL}
+else
+  ALTSRC=PATH_THAT_DOES_NOT_EXIST
+fi
 
 BASE_PATHS="`if [ -d ${ALTSRC}/share/vm ]; then $FIND ${ALTSRC}/share/vm ! -name vm -prune -type d \! \( -name adlc -o -name c1 -o -name gc -o -name opto -o -name shark -o -name libadt \); fi`"
 BASE_PATHS="${BASE_PATHS} ` $FIND ${COMMONSRC}/share/vm ! -name vm -prune -type d \! \( -name adlc -o -name c1 -o -name gc -o -name opto -o -name shark -o -name libadt \)`"
@@ -158,6 +162,6 @@
         fi
 	Obj_Files="${Obj_Files}$o "
 done
-Obj_Files=`echo ${Obj_Files} | tr ' ' '\n' | sort`
+Obj_Files=`echo ${Obj_Files} | tr ' ' '\n' | LC_ALL=C sort`
 
 echo Obj_Files=${Obj_Files}
--- a/hotspot/make/windows/makefiles/defs.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/windows/makefiles/defs.make	Thu Apr 07 09:47:48 2016 -0700
@@ -276,3 +276,7 @@
     MAKE_ARGS += MT="$(subst /,\\,$(MT))"
   endif
 endif
+
+ifdef OPENJDK
+  MAKE_ARGS += OPENJDK="$(OPENJDK)"
+endif
--- a/hotspot/make/windows/makefiles/trace.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/windows/makefiles/trace.make	Thu Apr 07 09:47:48 2016 -0700
@@ -32,15 +32,21 @@
 # #########################################################################
 
 
-TraceAltSrcDir = $(WorkSpace)/src/closed/share/vm/trace
-TraceSrcDir = $(WorkSpace)/src/share/vm/trace
+TraceAltSrcDir = $(WorkSpace)\src\closed\share\vm\trace
+TraceSrcDir = $(WorkSpace)\src\share\vm\trace
+
+!ifndef OPENJDK
+!if EXISTS($(TraceAltSrcDir))
+HAS_ALT_SRC = true
+!endif
+!endif
 
 TraceGeneratedNames =     \
     traceEventClasses.hpp \
     traceEventIds.hpp     \
     traceTypes.hpp
 
-!if EXISTS($(TraceAltSrcDir))
+!ifdef HAS_ALT_SRC
 TraceGeneratedNames = $(TraceGeneratedNames) \
     traceRequestables.hpp \
     traceEventControl.hpp
@@ -51,22 +57,30 @@
 #Should be equivalent to "TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)"
 TraceGeneratedFiles = \
     $(TraceOutDir)/traceEventClasses.hpp \
-	$(TraceOutDir)/traceEventIds.hpp     \
-	$(TraceOutDir)/traceTypes.hpp
+    $(TraceOutDir)/traceEventIds.hpp     \
+    $(TraceOutDir)/traceTypes.hpp
 
-!if EXISTS($(TraceAltSrcDir))
+!ifdef HAS_ALT_SRC
 TraceGeneratedFiles = $(TraceGeneratedFiles) \
-	$(TraceOutDir)/traceRequestables.hpp \
+    $(TraceOutDir)/traceRequestables.hpp \
     $(TraceOutDir)/traceEventControl.hpp
 !endif
 
 XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
 
-XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
-    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+TraceXml = $(TraceSrcDir)/trace.xml
+
+!ifdef HAS_ALT_SRC
+TraceXml = $(TraceAltSrcDir)/trace.xml
+!endif
 
-!if EXISTS($(TraceAltSrcDir))
-XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml
+XML_DEPS = $(TraceXml) $(TraceSrcDir)/tracetypes.xml \
+    $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod \
+    $(TraceSrcDir)/tracerelationdecls.xml $(TraceSrcDir)/traceevents.xml
+
+!ifdef HAS_ALT_SRC
+XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceeventscustom.xml \
+    $(TraceAltSrcDir)/traceeventtypes.xml
 !endif
 
 .PHONY: all clean cleanall
@@ -76,33 +90,33 @@
 default::
 	@if not exist $(TraceOutDir) mkdir $(TraceOutDir)
 
-$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
 	@echo Generating $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventIds.xsl -OUT $(TraceOutDir)/traceEventIds.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceSrcDir)/traceEventIds.xsl -OUT $(TraceOutDir)/traceEventIds.hpp
 
-$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
 	@echo Generating $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
 
-!if !EXISTS($(TraceAltSrcDir))
+!ifndef HAS_ALT_SRC
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	@echo Generating OpenJDK $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
 
 !else
 
-$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
 	@echo Generating AltSrc $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
 
-$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+$(TraceOutDir)/traceRequestables.hpp: $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
 	@echo Generating AltSrc $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
 
-$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+$(TraceOutDir)/traceEventControl.hpp: $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
 	@echo Generating AltSrc $@
-	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
+	$(XSLT) -IN $(TraceXml) -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
 
 !endif
 
@@ -110,5 +124,3 @@
 
 cleanall :
 	rm $(TraceGeneratedFiles)
-
-
--- a/hotspot/make/windows/makefiles/vm.make	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/make/windows/makefiles/vm.make	Thu Apr 07 09:47:48 2016 -0700
@@ -118,6 +118,7 @@
 
 CXX_INCLUDE_DIRS=/I "..\generated"
 
+!ifndef OPENJDK
 !if exists($(ALTSRC)\share\vm)
 CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\share\vm"
 !endif
@@ -133,6 +134,7 @@
 !if exists($(ALTSRC)\cpu\$(Platform_arch)\vm)
 CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) /I "$(ALTSRC)\cpu\$(Platform_arch)\vm"
 !endif
+!endif # OPENJDK
 
 CXX_INCLUDE_DIRS=$(CXX_INCLUDE_DIRS) \
   /I "$(COMMONSRC)\share\vm" \
@@ -187,10 +189,12 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
 
+!ifndef OPENJDK
 !if exists($(ALTSRC)\share\vm\jfr)
 VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr
 VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/buffers
 !endif
+!endif # OPENJDK
 
 VM_PATH={$(VM_PATH)}
 
@@ -310,6 +314,7 @@
 {$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+!ifndef OPENJDK
 {$(ALTSRC)\share\vm\c1}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
@@ -392,6 +397,13 @@
 {$(ALTSRC)\os_cpu\windows_$(Platform_arch)\vm}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(ALTSRC)\share\vm\jfr}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
+{$(ALTSRC)\share\vm\jfr\buffers}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+!endif
+
 {..\generated\incls}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
@@ -404,12 +416,6 @@
 {..\generated\tracefiles}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
-{$(ALTSRC)\share\vm\jfr}.cpp.obj::
-        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
-{$(ALTSRC)\share\vm\jfr\buffers}.cpp.obj::
-        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
 default::
 
 _build_pch_file.obj:
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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.
  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -31,6 +31,7 @@
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/compiledICHolder.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,6 +32,7 @@
 #include "interpreter/templateInterpreterGenerator.hpp"
 #include "interpreter/templateTable.hpp"
 #include "interpreter/bytecodeTracer.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
@@ -1967,7 +1968,7 @@
   __ push(RegSet::range(r0, r15), sp);
   __ mov(c_rarg2, r0);  // Pass itos
   __ call_VM(noreg,
-             CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode),
+             CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode),
              c_rarg1, c_rarg2, c_rarg3);
   __ pop(RegSet::range(r0, r15), sp);
   __ pop(state);
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -28,6 +28,7 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/hotspot/src/cpu/ppc/vm/runtime_ppc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/runtime_ppc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -31,6 +31,7 @@
 #include "code/vmreg.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
+#include "memory/resourceArea.hpp"
 #include "nativeInst_ppc.hpp"
 #include "opto/runtime.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -31,6 +31,7 @@
 #include "frame_ppc.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/compiledICHolder.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -2211,7 +2211,7 @@
   __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
   __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
   __ mflr(R31);
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
   __ mtlr(R31);
   __ pop(state);
 
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,6 +28,7 @@
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/hotspot/src/cpu/sparc/vm/runtime_sparc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/runtime_sparc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, 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
@@ -28,6 +28,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "code/vmreg.hpp"
 #include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
 #include "nativeInst_sparc.hpp"
 #include "opto/runtime.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -28,6 +28,7 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/compiledICHolder.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1966,7 +1966,7 @@
 
   // Pass a 0 (not used in sparc) and the top of stack to the bytecode tracer
   __ mov( Otos_l2, G3_scratch );
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), G0, Otos_l1, G3_scratch);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), G0, Otos_l1, G3_scratch);
   __ mov(Lscratch, O7); // restore return address
   __ pop(state);
   __ retl();
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -312,7 +312,7 @@
   Register OSR_buf = osrBufferPointer()->as_pointer_register();
   { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
     int monitor_offset = BytesPerWord * method()->max_locals() +
-      (2 * BytesPerWord) * (number_of_locks - 1);
+      (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
     // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
     // the OSR buffer using 2 word entries: first the lock and then
     // the oop.
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -54,44 +54,6 @@
 //                               <- sender sp
 // ------------------------------ Asm interpreter ----------------------------------------
 
-// ------------------------------ C++ interpreter ----------------------------------------
-//
-// Layout of C++ interpreter frame: (While executing in BytecodeInterpreter::run)
-//
-//                             <- SP (current esp/rsp)
-//    [local variables         ] BytecodeInterpreter::run local variables
-//    ...                        BytecodeInterpreter::run local variables
-//    [local variables         ] BytecodeInterpreter::run local variables
-//    [old frame pointer       ]   fp [ BytecodeInterpreter::run's ebp/rbp ]
-//    [return pc               ]  (return to frame manager)
-//    [interpreter_state*      ]  (arg to BytecodeInterpreter::run)   --------------
-//    [expression stack        ] <- last_Java_sp                           |
-//    [...                     ] * <- interpreter_state.stack              |
-//    [expression stack        ] * <- interpreter_state.stack_base         |
-//    [monitors                ]   \                                       |
-//     ...                          | monitor block size                   |
-//    [monitors                ]   / <- interpreter_state.monitor_base     |
-//    [struct interpretState   ] <-----------------------------------------|
-//    [return pc               ] (return to callee of frame manager [1]
-//    [locals and parameters   ]
-//                               <- sender sp
-
-// [1] When the C++ interpreter calls a new method it returns to the frame
-//     manager which allocates a new frame on the stack. In that case there
-//     is no real callee of this newly allocated frame. The frame manager is
-//     aware of the additional frame(s) and will pop them as nested calls
-//     complete. However, to make it look good in the debugger the frame
-//     manager actually installs a dummy pc pointing to RecursiveInterpreterActivation
-//     with a fake interpreter_state* parameter to make it easy to debug
-//     nested calls.
-
-// Note that contrary to the layout for the assembly interpreter the
-// expression stack allocated for the C++ interpreter is full sized.
-// However this is not as bad as it seems as the interpreter frame_manager
-// will truncate the unused space on successive method calls.
-//
-// ------------------------------ C++ interpreter ----------------------------------------
-
  public:
   enum {
     pc_return_offset                                 =  0,
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -296,7 +296,7 @@
     Label L;
     cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
     jcc(Assembler::equal, L);
-    stop("InterpreterMacroAssembler::call_VM_leaf_base:"
+    stop("InterpreterMacroAssembler::call_VM_base:"
          " last_sp != NULL");
     bind(L);
   }
@@ -1099,7 +1099,7 @@
     movptr(Address(lock_reg, mark_offset), swap_reg);
 
     assert(lock_offset == 0,
-           "displached header must be first word in BasicObjectLock");
+           "displaced header must be first word in BasicObjectLock");
 
     if (os::is_MP()) lock();
     cmpxchgptr(lock_reg, Address(obj_reg, 0));
@@ -1154,7 +1154,7 @@
 // Kills:
 //      rax
 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
-//      rscratch1, rscratch2 (scratch regs)
+//      rscratch1 (scratch reg)
 // rax, rbx, rcx, rdx
 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
   assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
@@ -1201,7 +1201,7 @@
     if (os::is_MP()) lock();
     cmpxchgptr(header_reg, Address(obj_reg, 0));
 
-    // zero for recursive case
+    // zero for simple unlock of a stack-lock case
     jcc(Assembler::zero, done);
 
     // Call the runtime routine for slow case.
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1106,7 +1106,7 @@
   assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg);
   assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
   Address mark_addr      (obj_reg, oopDesc::mark_offset_in_bytes());
-  Address saved_mark_addr(lock_reg, 0);
+  NOT_LP64( Address saved_mark_addr(lock_reg, 0); )
 
   if (PrintBiasedLockingStatistics && counters == NULL) {
     counters = BiasedLocking::counters();
@@ -1695,7 +1695,7 @@
                                RTMLockingCounters* stack_rtm_counters,
                                Metadata* method_data,
                                bool use_rtm, bool profile_rtm) {
-  // Ensure the register assignents are disjoint
+  // Ensure the register assignments are disjoint
   assert(tmpReg == rax, "");
 
   if (use_rtm) {
@@ -2194,8 +2194,8 @@
       cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
       jccb  (Assembler::zero, LGoSlowPath);
 
+      xorptr(boxReg, boxReg);
       if ((EmitSync & 16) && os::is_MP()) {
-        orptr(boxReg, boxReg);
         xchgptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
       } else {
         movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
@@ -2227,7 +2227,6 @@
 
       // box is really RAX -- the following CMPXCHG depends on that binding
       // cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
-      movptr(boxReg, (int32_t)NULL_WORD);
       if (os::is_MP()) { lock(); }
       cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
       // There's no successor so we tried to regrab the lock.
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -28,6 +28,7 @@
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/runtime_x86_32.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, 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
@@ -29,6 +29,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "code/vmreg.hpp"
 #include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
 #include "opto/runtime.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -29,6 +29,7 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/compiledICHolder.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,6 +32,7 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/compiledICHolder.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1830,7 +1830,7 @@
   __ push(state);       // save tosca
 
   // pass tosca registers as arguments & call tracer
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), rcx, rax, rdx);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), rcx, rax, rdx);
   __ mov(rcx, rax);     // make sure return address is not destroyed by pop(state)
   __ pop(state);        // restore tosca
 
@@ -1847,7 +1847,7 @@
   __ movflt(xmm3, xmm0); // Pass ftos
 #endif
   __ call_VM(noreg,
-             CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode),
+             CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode),
              c_rarg1, c_rarg2, c_rarg3);
   __ pop(c_rarg3);
   __ pop(c_rarg2);
--- a/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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.
  * Copyright 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -27,6 +27,7 @@
 #include "interpreter/cppInterpreterGenerator.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/methodHandles.hpp"
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java	Thu Apr 07 09:47:48 2016 -0700
@@ -549,11 +549,9 @@
         },
         new Command("buildreplayjars", "buildreplayjars [ all | app | boot ]  | [ prefix ]", false) {
             // This is used to dump jar files of all the classes
-            // loaded in the core.  Everything on the bootclasspath
+            // loaded in the core.  Everything with null classloader
             // will go in boot.jar and everything else will go in
-            // app.jar.  Then the classes can be loaded by the replay
-            // jvm using -Xbootclasspath/p:boot.jar -cp app.jar. boot.jar usually
-            // not needed, unless changed by jvmti.
+            // app.jar. boot.jar usually not needed, unless changed by jvmti.
             public void doit(Tokens t) {
                 int tcount = t.countTokens();
                 if (tcount > 2) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java	Thu Apr 07 09:47:48 2016 -0700
@@ -84,7 +84,11 @@
             }
             else {
                 // Mixed style options --file name
-                extractOptarg(ca[0]);
+                try {
+                    extractOptarg(ca[0]);
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    throw new RuntimeException("Argument is expected for '" + ca[0] + "'");
+                }
             }
 
             return ca[0];
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java	Thu Apr 07 09:47:48 2016 -0700
@@ -30,6 +30,7 @@
 import sun.jvm.hotspot.tools.JStack;
 import sun.jvm.hotspot.tools.JMap;
 import sun.jvm.hotspot.tools.JInfo;
+import sun.jvm.hotspot.tools.JSnap;
 
 public class SALauncher {
 
@@ -39,6 +40,7 @@
         System.out.println("    jstack --help\tto get more information");
         System.out.println("    jmap   --help\tto get more information");
         System.out.println("    jinfo  --help\tto get more information");
+        System.out.println("    jsnap  --help\tto get more information");
         return false;
     }
 
@@ -85,6 +87,11 @@
         return commonHelp();
     }
 
+    private static boolean jsnapHelp() {
+        System.out.println("    --all\tto print all performance counters");
+        return commonHelp();
+    }
+
     private static boolean toolHelp(String toolName) {
         if (toolName.equals("jstack")) {
             return jstackHelp();
@@ -95,24 +102,62 @@
         if (toolName.equals("jmap")) {
             return jmapHelp();
         }
+        if (toolName.equals("jsnap")) {
+            return jsnapHelp();
+        }
         if (toolName.equals("hsdb") || toolName.equals("clhsdb")) {
             return commonHelp();
         }
         return launcherHelp();
     }
 
+    private static void buildAttachArgs(ArrayList<String> newArgs,
+                                        String pid, String exe, String core) {
+        if ((pid == null) && (exe == null)) {
+            throw new IllegalArgumentException(
+                                     "You have to set --pid or --exe.");
+        }
+
+        if (pid != null) { // Attach to live process
+            if (exe != null) {
+                throw new IllegalArgumentException(
+                                             "Unnecessary argument: --exe");
+            } else if (core != null) {
+                throw new IllegalArgumentException(
+                                             "Unnecessary argument: --core");
+            } else if (!pid.matches("^\\d+$")) {
+                throw new IllegalArgumentException("Invalid pid: " + pid);
+            }
+
+            newArgs.add(pid);
+        } else {
+            if (exe.length() == 0) {
+                throw new IllegalArgumentException("You have to set --exe.");
+            }
+
+            newArgs.add(exe);
+
+            if ((core == null) || (core.length() == 0)) {
+                throw new IllegalArgumentException("You have to set --core.");
+            }
+
+            newArgs.add(core);
+        }
+    }
+
     private static void runCLHSDB(String[] oldArgs) {
         SAGetopt sg = new SAGetopt(oldArgs);
         String[] longOpts = {"exe=", "core=", "pid="};
 
         ArrayList<String> newArgs = new ArrayList();
-        String exeORpid = null;
+        String pid = null;
+        String exe = null;
         String core = null;
         String s = null;
 
         while((s = sg.next(null, longOpts)) != null) {
             if (s.equals("exe")) {
-                exeORpid = sg.getOptarg();
+                exe = sg.getOptarg();
                 continue;
             }
             if (s.equals("core")) {
@@ -120,17 +165,12 @@
                 continue;
             }
             if (s.equals("pid")) {
-                exeORpid = sg.getOptarg();
+                pid = sg.getOptarg();
                 continue;
             }
         }
 
-        if (exeORpid != null) {
-            newArgs.add(exeORpid);
-            if (core != null) {
-                newArgs.add(core);
-            }
-        }
+        buildAttachArgs(newArgs, pid, exe, core);
         CLHSDB.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -139,13 +179,14 @@
         String[] longOpts = {"exe=", "core=", "pid="};
 
         ArrayList<String> newArgs = new ArrayList();
-        String exeORpid = null;
+        String pid = null;
+        String exe = null;
         String core = null;
         String s = null;
 
         while((s = sg.next(null, longOpts)) != null) {
             if (s.equals("exe")) {
-                exeORpid = sg.getOptarg();
+                exe = sg.getOptarg();
                 continue;
             }
             if (s.equals("core")) {
@@ -153,17 +194,12 @@
                 continue;
             }
             if (s.equals("pid")) {
-                exeORpid = sg.getOptarg();
+                pid = sg.getOptarg();
                 continue;
             }
         }
 
-        if (exeORpid != null) {
-            newArgs.add(exeORpid);
-            if (core != null) {
-                newArgs.add(core);
-            }
-        }
+        buildAttachArgs(newArgs, pid, exe, core);
         HSDB.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -173,13 +209,14 @@
                                  "mixed", "locks"};
 
         ArrayList<String> newArgs = new ArrayList();
-        String exeORpid = null;
+        String pid = null;
+        String exe = null;
         String core = null;
         String s = null;
 
         while((s = sg.next(null, longOpts)) != null) {
             if (s.equals("exe")) {
-                exeORpid = sg.getOptarg();
+                exe = sg.getOptarg();
                 continue;
             }
             if (s.equals("core")) {
@@ -187,7 +224,7 @@
                 continue;
             }
             if (s.equals("pid")) {
-                exeORpid = sg.getOptarg();
+                pid = sg.getOptarg();
                 continue;
             }
             if (s.equals("mixed")) {
@@ -200,13 +237,7 @@
             }
         }
 
-        if (exeORpid != null) {
-            newArgs.add(exeORpid);
-            if (core != null) {
-                newArgs.add(core);
-            }
-        }
-
+        buildAttachArgs(newArgs, pid, exe, core);
         JStack.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -216,13 +247,14 @@
               "heap", "binaryheap", "histo", "clstats", "finalizerinfo"};
 
         ArrayList<String> newArgs = new ArrayList();
-        String exeORpid = null;
+        String pid = null;
+        String exe = null;
         String core = null;
         String s = null;
 
         while((s = sg.next(null, longOpts)) != null) {
             if (s.equals("exe")) {
-                exeORpid = sg.getOptarg();
+                exe = sg.getOptarg();
                 continue;
             }
             if (s.equals("core")) {
@@ -230,7 +262,7 @@
                 continue;
             }
             if (s.equals("pid")) {
-                exeORpid = sg.getOptarg();
+                pid = sg.getOptarg();
                 continue;
             }
             if (s.equals("heap")) {
@@ -255,13 +287,7 @@
             }
         }
 
-        if (exeORpid != null) {
-            newArgs.add(exeORpid);
-            if (core != null) {
-                newArgs.add(core);
-            }
-        }
-
+        buildAttachArgs(newArgs, pid, exe, core);
         JMap.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
@@ -271,13 +297,14 @@
                                      "flags", "sysprops"};
 
         ArrayList<String> newArgs = new ArrayList();
-        String exeORpid = null;
+        String exe = null;
+        String pid = null;
         String core = null;
         String s = null;
 
         while((s = sg.next(null, longOpts)) != null) {
             if (s.equals("exe")) {
-                exeORpid = sg.getOptarg();
+                exe = sg.getOptarg();
                 continue;
             }
             if (s.equals("core")) {
@@ -285,7 +312,7 @@
                 continue;
             }
             if (s.equals("pid")) {
-                exeORpid = sg.getOptarg();
+                pid = sg.getOptarg();
                 continue;
             }
             if (s.equals("flags")) {
@@ -298,14 +325,41 @@
             }
         }
 
-        if (exeORpid != null) {
-            newArgs.add(exeORpid);
-            if (core != null) {
-                newArgs.add(core);
+        buildAttachArgs(newArgs, pid, exe, core);
+        JInfo.main(newArgs.toArray(new String[newArgs.size()]));
+    }
+
+    private static void runJSNAP(String[] oldArgs) {
+        SAGetopt sg = new SAGetopt(oldArgs);
+        String[] longOpts = {"exe=", "core=", "pid=", "all"};
+
+        ArrayList<String> newArgs = new ArrayList();
+        String exe = null;
+        String pid = null;
+        String core = null;
+        String s = null;
+
+        while((s = sg.next(null, longOpts)) != null) {
+            if (s.equals("exe")) {
+                exe = sg.getOptarg();
+                continue;
+            }
+            if (s.equals("core")) {
+                core = sg.getOptarg();
+                continue;
+            }
+            if (s.equals("pid")) {
+                pid = sg.getOptarg();
+                continue;
+            }
+            if (s.equals("all")) {
+                newArgs.add("-a");
+                continue;
             }
         }
 
-        JInfo.main(newArgs.toArray(new String[newArgs.size()]));
+        buildAttachArgs(newArgs, pid, exe, core);
+        JSnap.main(newArgs.toArray(new String[newArgs.size()]));
     }
 
     public static void main(String[] args) {
@@ -329,31 +383,43 @@
 
         String[] oldArgs = Arrays.copyOfRange(args, 1, args.length);
 
-        // Run SA interactive mode
-        if (args[0].equals("clhsdb")) {
-            runCLHSDB(oldArgs);
-            return;
-        }
+        try {
+            // Run SA interactive mode
+            if (args[0].equals("clhsdb")) {
+                runCLHSDB(oldArgs);
+                return;
+            }
 
-        if (args[0].equals("hsdb")) {
-            runHSDB(oldArgs);
-            return;
-        }
+            if (args[0].equals("hsdb")) {
+                runHSDB(oldArgs);
+                return;
+            }
+
+            // Run SA tmtools mode
+            if (args[0].equals("jstack")) {
+                runJSTACK(oldArgs);
+                return;
+            }
 
-        // Run SA tmtools mode
-        if (args[0].equals("jstack")) {
-            runJSTACK(oldArgs);
-            return;
-        }
+            if (args[0].equals("jmap")) {
+                runJMAP(oldArgs);
+                return;
+            }
+
+            if (args[0].equals("jinfo")) {
+                runJINFO(oldArgs);
+                return;
+            }
 
-        if (args[0].equals("jmap")) {
-            runJMAP(oldArgs);
-            return;
-        }
+            if (args[0].equals("jsnap")) {
+                runJSNAP(oldArgs);
+                return;
+            }
 
-        if (args[0].equals("jinfo")) {
-            runJINFO(oldArgs);
-            return;
+            throw new IllegalArgumentException("Unknown tool: " + args[0]);
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+            toolHelp(args[0]);
         }
     }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java	Thu Apr 07 09:47:48 2016 -0700
@@ -35,6 +35,11 @@
   _gc_locker ("GCLocker Initiated GC"),
   _heap_inspection ("Heap Inspection Initiated GC"),
   _heap_dump ("Heap Dump Initiated GC"),
+  _wb_young_gc ("WhiteBox Initiated Young GC"),
+  _wb_conc_mark ("WhiteBox Initiated Concurrent Mark"),
+  _wb_full_gc ("WhiteBox Initiated Full GC"),
+  _update_allocation_context_stats_inc ("Update Allocation Context Stats"),
+  _update_allocation_context_stats_full ("Update Allocation Context Stats"),
 
   _no_gc ("No GC"),
   _no_cause_specified ("Unknown GCCause"),
@@ -42,6 +47,7 @@
 
   _tenured_generation_full ("Tenured Generation Full"),
   _metadata_GC_threshold ("Metadata GC Threshold"),
+  _metadata_GC_clear_soft_refs ("Metadata GC Clear Soft References"),
 
   _cms_generation_full ("CMS Generation Full"),
   _cms_initial_mark ("CMS Initial Mark"),
@@ -55,7 +61,8 @@
   _g1_inc_collection_pause ("G1 Evacuation Pause"),
   _g1_humongous_allocation ("G1 Humongous Allocation"),
 
-  _last_ditch_collection ("Last ditch collection"),
+  _dcmd_gc_run ("Diagnostic Command"),
+
   _last_gc_cause ("ILLEGAL VALUE - last gc cause - ILLEGAL VALUE");
 
   private final String value;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java	Thu Apr 07 09:47:48 2016 -0700
@@ -780,8 +780,8 @@
         return getPath("java.class.path");
     }
 
-    public List bootClassPath() {
-        return getPath("sun.boot.class.path");
+    public List<String> bootClassPath() {
+        return Collections.emptyList();
     }
 
     public String baseDirectory() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,7 +130,7 @@
             virtualConstructor.addMapping("CodeCacheSweeperThread", CodeCacheSweeperThread.class);
         }
         // for now, use JavaThread itself. fix it later with appropriate class if needed
-        virtualConstructor.addMapping("SurrogateLockerThread", JavaThread.class);
+        virtualConstructor.addMapping("ReferencePendingListLockerThread", JavaThread.class);
         virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
         virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
     }
@@ -172,7 +172,7 @@
             return thread;
         } catch (Exception e) {
             throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
-            " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, SurrogateLockerThread, or CodeCacheSweeperThread)", e);
+            " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, ReferencePendingListLockerThread, or CodeCacheSweeperThread)", e);
         }
     }
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JSnap.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JSnap.java	Thu Apr 07 09:47:48 2016 -0700
@@ -25,11 +25,15 @@
 package sun.jvm.hotspot.tools;
 
 import java.io.*;
+import java.util.*;
+import java.util.stream.*;
 import sun.jvm.hotspot.debugger.JVMDebugger;
 import sun.jvm.hotspot.runtime.*;
 
 public class JSnap extends Tool {
 
+    private boolean all;
+
     public JSnap() {
         super();
     }
@@ -45,7 +49,7 @@
             if (prologue.accessible()) {
                 PerfMemory.iterate(new PerfMemory.PerfDataEntryVisitor() {
                         public boolean visit(PerfDataEntry pde) {
-                            if (pde.supported()) {
+                            if (all || pde.supported()) {
                                 out.print(pde.name());
                                 out.print('=');
                                 out.println(pde.valueAsString());
@@ -62,8 +66,24 @@
         }
     }
 
+    @Override
+    protected void printFlagsUsage() {
+        System.out.println("    -a\tto print all performance counters");
+        super.printFlagsUsage();
+    }
+
     public static void main(String[] args) {
         JSnap js = new JSnap();
+        js.all = Arrays.stream(args)
+                       .anyMatch(s -> s.equals("-a"));
+
+        if (js.all) {
+            args = Arrays.stream(args)
+                         .filter(s -> !s.equals("-a"))
+                         .collect(Collectors.toList())
+                         .toArray(new String[0]);
+        }
+
         js.execute(args);
     }
 }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java	Thu Apr 07 09:47:48 2016 -0700
@@ -81,6 +81,12 @@
   }
 
   public Symbol probe(byte[] name, long hash) {
+
+    if (bucketCount() == 0) {
+      // The table is invalid, so don't try to lookup
+      return null;
+    }
+
     long    symOffset;
     Symbol  sym;
     Address baseAddress = baseAddressField.getValue(addr);
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaVM.java	Thu Apr 07 09:47:48 2016 -0700
@@ -75,8 +75,6 @@
             return vm.getVMRelease();
         case FIELD_CLASS_PATH:
             return getClassPath();
-        case FIELD_BOOT_CLASS_PATH:
-            return getBootClassPath();
         case FIELD_USER_DIR:
             return getUserDir();
         case FIELD_UNDEFINED:
@@ -143,7 +141,6 @@
         addField("type", FIELD_TYPE);
         addField("version", FIELD_VERSION);
         addField("classPath", FIELD_CLASS_PATH);
-        addField("bootClassPath", FIELD_BOOT_CLASS_PATH);
         addField("userDir", FIELD_USER_DIR);
     }
 
@@ -217,10 +214,6 @@
         return vm.getSystemProperty("java.class.path");
     }
 
-    private String getBootClassPath() {
-        return vm.getSystemProperty("sun.boot.class.path");
-    }
-
     private String getUserDir() {
         return vm.getSystemProperty("user.dir");
     }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -837,7 +837,7 @@
 vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
 vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
 vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
-vmType2Class["SurrogateLockerThread"] = sapkg.runtime.JavaThread;
+vmType2Class["ReferencePendingListLockerThread"] = sapkg.runtime.JavaThread;
 vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
 
 // gc
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -910,8 +910,8 @@
     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));
+    log_warning(os, thread)("Failed to start thread - pthread_create failed (%d=%s) for attributes: %s.",
+      ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
   }
 
   pthread_attr_destroy(&attr);
@@ -1178,7 +1178,7 @@
 size_t os::lasterror(char *buf, size_t len) {
   if (errno == 0) return 0;
 
-  const char *s = ::strerror(errno);
+  const char *s = os::strerror(errno);
   size_t n = ::strlen(s);
   if (n >= len) {
     n = len - 1;
@@ -1714,14 +1714,14 @@
   if (os::Aix::on_aix()) {
     int rc = ::sem_post(&sig_sem);
     if (rc == -1 && !warn_only_once) {
-      trcVerbose("sem_post failed (errno = %d, %s)", errno, strerror(errno));
+      trcVerbose("sem_post failed (errno = %d, %s)", errno, os::errno_name(errno));
       warn_only_once = true;
     }
   } else {
     guarantee0(p_sig_msem != NULL);
     int rc = ::msem_unlock(p_sig_msem, 0);
     if (rc == -1 && !warn_only_once) {
-      trcVerbose("msem_unlock failed (errno = %d, %s)", errno, strerror(errno));
+      trcVerbose("msem_unlock failed (errno = %d, %s)", errno, os::errno_name(errno));
       warn_only_once = true;
     }
   }
@@ -1732,14 +1732,14 @@
   if (os::Aix::on_aix()) {
     int rc = ::sem_wait(&sig_sem);
     if (rc == -1 && !warn_only_once) {
-      trcVerbose("sem_wait failed (errno = %d, %s)", errno, strerror(errno));
+      trcVerbose("sem_wait failed (errno = %d, %s)", errno, os::errno_name(errno));
       warn_only_once = true;
     }
   } else {
     guarantee0(p_sig_msem != NULL); // must init before use
     int rc = ::msem_lock(p_sig_msem, 0);
     if (rc == -1 && !warn_only_once) {
-      trcVerbose("msem_lock failed (errno = %d, %s)", errno, strerror(errno));
+      trcVerbose("msem_lock failed (errno = %d, %s)", errno, os::errno_name(errno));
       warn_only_once = true;
     }
   }
@@ -2203,7 +2203,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
-          strerror(err), err);
+          os::errno_name(err), err);
 }
 #endif
 
@@ -2412,7 +2412,7 @@
   bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;
 
   if (!rc) {
-    const char* const s_errno = strerror(errno);
+    const char* const s_errno = os::errno_name(errno);
     warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno);
     return false;
   }
@@ -2634,7 +2634,7 @@
 
   if (ret != 0) {
     trcVerbose("Could not change priority for thread %d to %d (error %d, %s)",
-        (int)thr, newpri, ret, strerror(ret));
+        (int)thr, newpri, ret, os::errno_name(ret));
   }
   return (ret == 0) ? OS_OK : OS_ERR;
 }
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -30,6 +30,7 @@
 #include "oops/oop.inline.hpp"
 #include "os_aix.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/os.hpp"
 #include "runtime/perfMemory.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
@@ -101,7 +102,7 @@
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
-              destfile, strerror(errno));
+              destfile, os::strerror(errno));
     }
   } else {
     int fd = result;
@@ -112,7 +113,7 @@
       if (result == OS_ERR) {
         if (PrintMiscellaneous && Verbose) {
           warning("Could not write Perfdata save file: %s: %s\n",
-                  destfile, strerror(errno));
+                  destfile, os::strerror(errno));
         }
         break;
       }
@@ -124,7 +125,7 @@
     result = ::close(fd);
     if (PrintMiscellaneous && Verbose) {
       if (result == OS_ERR) {
-        warning("Could not close %s: %s\n", destfile, strerror(errno));
+        warning("Could not close %s: %s\n", destfile, os::strerror(errno));
       }
     }
   }
@@ -397,7 +398,7 @@
       if (errno == ELOOP) {
         warning("directory %s is a symlink and is not secure\n", dirname);
       } else {
-        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+        warning("could not open directory %s: %s\n", dirname, os::strerror(errno));
       }
     }
     return dirp;
@@ -507,7 +508,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+      warning("fstat failed on %s: %s\n", filename, os::strerror(errno));
     }
     return false;
   }
@@ -543,7 +544,7 @@
     if (PrintMiscellaneous && Verbose) {
       if (result != 0) {
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(result));
+                os::strerror(result));
       }
       else if (p == NULL) {
         // this check is added to protect against an observed problem
@@ -557,7 +558,7 @@
         // Bug Id 89052 was opened with RedHat.
         //
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(errno));
+                os::strerror(errno));
       }
       else {
         warning("Could not determine user name: %s\n",
@@ -593,7 +594,7 @@
                   "Process not found");
     }
     else /* EPERM */ {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_0(vmSymbols::java_io_IOException(), os::strerror(errno));
     }
   }
 
@@ -746,7 +747,7 @@
   if (PrintMiscellaneous && Verbose && result == OS_ERR) {
     if (errno != ENOENT) {
       warning("Could not unlink shared memory backing"
-              " store file %s : %s\n", path, strerror(errno));
+              " store file %s : %s\n", path, os::strerror(errno));
     }
   }
 }
@@ -849,7 +850,7 @@
       //
       if (PrintMiscellaneous && Verbose) {
         warning("could not create directory %s: %s\n",
-                dirname, strerror(errno));
+                dirname, os::strerror(errno));
       }
       return false;
     }
@@ -900,7 +901,7 @@
       if (errno == ELOOP) {
         warning("file %s is a symlink and is not secure\n", filename);
       } else {
-        warning("could not create file %s: %s\n", filename, strerror(errno));
+        warning("could not create file %s: %s\n", filename, os::strerror(errno));
       }
     }
     // Close the directory and reset the current working directory.
@@ -924,7 +925,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not truncate shared memory file: %s\n", strerror(errno));
+      warning("could not truncate shared memory file: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -933,7 +934,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not set shared memory file size: %s\n", strerror(errno));
+      warning("could not set shared memory file size: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -968,7 +969,7 @@
                   "Permission denied");
     }
     else {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_0(vmSymbols::java_io_IOException(), os::strerror(errno));
     }
   }
   int fd = result;
@@ -1041,7 +1042,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed -  %s\n", strerror(errno));
+      warning("mmap failed -  %s\n", os::strerror(errno));
     }
     remove_file(filename);
     FREE_C_HEAP_ARRAY(char, filename);
@@ -1109,7 +1110,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed: %s\n", strerror(errno));
+      warning("fstat failed: %s\n", os::strerror(errno));
     }
     THROW_MSG_0(vmSymbols::java_io_IOException(),
                 "Could not determine PerfMemory size");
@@ -1231,7 +1232,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed: %s\n", strerror(errno));
+      warning("mmap failed: %s\n", os::strerror(errno));
     }
     THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
               "Could not map PerfMemory");
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -789,7 +789,7 @@
         (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));
+        os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
     }
 
     pthread_attr_destroy(&attr);
@@ -1122,7 +1122,7 @@
 size_t os::lasterror(char *buf, size_t len) {
   if (errno == 0)  return 0;
 
-  const char *s = ::strerror(errno);
+  const char *s = os::strerror(errno);
   size_t n = ::strlen(s);
   if (n >= len) {
     n = len - 1;
@@ -2141,7 +2141,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
-          strerror(err), err);
+          os::errno_name(err), err);
 }
 
 // NOTE: Bsd kernel does not really reserve the pages for us.
@@ -3422,7 +3422,7 @@
 
   Bsd::set_page_size(getpagesize());
   if (Bsd::page_size() == -1) {
-    fatal("os_bsd.cpp: os::init: sysconf failed (%s)", strerror(errno));
+    fatal("os_bsd.cpp: os::init: sysconf failed (%s)", os::strerror(errno));
   }
   init_page_sizes((size_t) Bsd::page_size());
 
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -29,6 +29,7 @@
 #include "oops/oop.inline.hpp"
 #include "os_bsd.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/os.hpp"
 #include "runtime/perfMemory.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
@@ -100,7 +101,7 @@
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
-              destfile, strerror(errno));
+              destfile, os::strerror(errno));
     }
   } else {
     int fd = result;
@@ -111,7 +112,7 @@
       if (result == OS_ERR) {
         if (PrintMiscellaneous && Verbose) {
           warning("Could not write Perfdata save file: %s: %s\n",
-                  destfile, strerror(errno));
+                  destfile, os::strerror(errno));
         }
         break;
       }
@@ -123,7 +124,7 @@
     result = ::close(fd);
     if (PrintMiscellaneous && Verbose) {
       if (result == OS_ERR) {
-        warning("Could not close %s: %s\n", destfile, strerror(errno));
+        warning("Could not close %s: %s\n", destfile, os::strerror(errno));
       }
     }
   }
@@ -309,7 +310,7 @@
       if (errno == ELOOP) {
         warning("directory %s is a symlink and is not secure\n", dirname);
       } else {
-        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+        warning("could not open directory %s: %s\n", dirname, os::strerror(errno));
       }
     }
     return dirp;
@@ -420,7 +421,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+      warning("fstat failed on %s: %s\n", filename, os::strerror(errno));
     }
     return false;
   }
@@ -459,7 +460,7 @@
     if (PrintMiscellaneous && Verbose) {
       if (result != 0) {
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(result));
+                os::strerror(result));
       }
       else if (p == NULL) {
         // this check is added to protect against an observed problem
@@ -473,7 +474,7 @@
         // Bug Id 89052 was opened with RedHat.
         //
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(errno));
+                os::strerror(errno));
       }
       else {
         warning("Could not determine user name: %s\n",
@@ -509,7 +510,7 @@
                   "Process not found");
     }
     else /* EPERM */ {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_0(vmSymbols::java_io_IOException(), os::strerror(errno));
     }
   }
 
@@ -652,7 +653,7 @@
   if (PrintMiscellaneous && Verbose && result == OS_ERR) {
     if (errno != ENOENT) {
       warning("Could not unlink shared memory backing"
-              " store file %s : %s\n", path, strerror(errno));
+              " store file %s : %s\n", path, os::strerror(errno));
     }
   }
 }
@@ -762,7 +763,7 @@
       //
       if (PrintMiscellaneous && Verbose) {
         warning("could not create directory %s: %s\n",
-                dirname, strerror(errno));
+                dirname, os::strerror(errno));
       }
       return false;
     }
@@ -804,7 +805,7 @@
       if (errno == ELOOP) {
         warning("file %s is a symlink and is not secure\n", filename);
       } else {
-        warning("could not create file %s: %s\n", filename, strerror(errno));
+        warning("could not create file %s: %s\n", filename, os::strerror(errno));
       }
     }
     // close the directory and reset the current working directory
@@ -828,7 +829,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not truncate shared memory file: %s\n", strerror(errno));
+      warning("could not truncate shared memory file: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -837,7 +838,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not set shared memory file size: %s\n", strerror(errno));
+      warning("could not set shared memory file size: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -887,7 +888,7 @@
                   "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
+      THROW_MSG_(vmSymbols::java_io_IOException(), os::strerror(errno), OS_ERR);
     }
   }
   int fd = result;
@@ -961,7 +962,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed -  %s\n", strerror(errno));
+      warning("mmap failed -  %s\n", os::strerror(errno));
     }
     remove_file(filename);
     FREE_C_HEAP_ARRAY(char, filename);
@@ -1025,7 +1026,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed: %s\n", strerror(errno));
+      warning("fstat failed: %s\n", os::strerror(errno));
     }
     THROW_MSG_0(vmSymbols::java_io_IOException(),
                 "Could not determine PerfMemory size");
@@ -1136,7 +1137,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed: %s\n", strerror(errno));
+      warning("mmap failed: %s\n", os::strerror(errno));
     }
     THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
               "Could not map PerfMemory");
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -594,15 +594,7 @@
 // _expand_stack_to() assumes its frame size is less than page size, which
 // should always be true if the function is not inlined.
 
-#if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
-  #define NOINLINE
-#else
-  #define NOINLINE __attribute__ ((noinline))
-#endif
-
-static void _expand_stack_to(address bottom) NOINLINE;
-
-static void _expand_stack_to(address bottom) {
+static void NOINLINE _expand_stack_to(address bottom) {
   address sp;
   size_t size;
   volatile char *p;
@@ -769,7 +761,7 @@
         (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));
+        os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
     }
 
     pthread_attr_destroy(&attr);
@@ -890,6 +882,13 @@
   assert(osthread != NULL, "osthread not set");
 
   if (Thread::current()->osthread() == osthread) {
+#ifdef ASSERT
+    sigset_t current;
+    sigemptyset(&current);
+    pthread_sigmask(SIG_SETMASK, NULL, &current);
+    assert(!sigismember(&current, SR_signum), "SR signal should not be blocked!");
+#endif
+
     // Restore caller's signal mask
     sigset_t sigmask = osthread->caller_sigmask();
     pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
@@ -1395,7 +1394,7 @@
 size_t os::lasterror(char *buf, size_t len) {
   if (errno == 0)  return 0;
 
-  const char *s = ::strerror(errno);
+  const char *s = os::strerror(errno);
   size_t n = ::strlen(s);
   if (n >= len) {
     n = len - 1;
@@ -2601,7 +2600,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,
-          strerror(err), err);
+          os::strerror(err), err);
 }
 
 static void warn_fail_commit_memory(char* addr, size_t size,
@@ -2609,7 +2608,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", p2i(addr), size,
-          alignment_hint, exec, strerror(err), err);
+          alignment_hint, exec, os::strerror(err), err);
 }
 
 // NOTE: Linux kernel does not really reserve the pages for us.
@@ -3912,7 +3911,8 @@
   // after sigsuspend.
   int old_errno = errno;
 
-  Thread* thread = Thread::current();
+  Thread* thread = Thread::current_or_null_safe();
+  assert(thread != NULL, "Missing current thread in SR_handler");
   OSThread* osthread = thread->osthread();
   assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
 
@@ -3924,7 +3924,7 @@
     os::SuspendResume::State state = osthread->sr.suspended();
     if (state == os::SuspendResume::SR_SUSPENDED) {
       sigset_t suspend_set;  // signals for sigsuspend()
-
+      sigemptyset(&suspend_set);
       // get current set of blocked signals and unblock resume signal
       pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
       sigdelset(&suspend_set, SR_signum);
@@ -4178,6 +4178,7 @@
 
     // try to honor the signal mask
     sigset_t oset;
+    sigemptyset(&oset);
     pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
 
     // call into the chained handler
@@ -4188,7 +4189,7 @@
     }
 
     // restore the signal mask
-    pthread_sigmask(SIG_SETMASK, &oset, 0);
+    pthread_sigmask(SIG_SETMASK, &oset, NULL);
   }
   // Tell jvm's signal handler the signal is taken care of.
   return true;
@@ -4615,7 +4616,7 @@
   Linux::set_page_size(sysconf(_SC_PAGESIZE));
   if (Linux::page_size() == -1) {
     fatal("os_linux.cpp: os::init: sysconf failed (%s)",
-          strerror(errno));
+          os::strerror(errno));
   }
   init_page_sizes((size_t) Linux::page_size());
 
@@ -4633,7 +4634,7 @@
   int status;
   pthread_condattr_t* _condattr = os::Linux::condAttr();
   if ((status = pthread_condattr_init(_condattr)) != 0) {
-    fatal("pthread_condattr_init: %s", strerror(status));
+    fatal("pthread_condattr_init: %s", os::strerror(status));
   }
   // Only set the clock if CLOCK_MONOTONIC is available
   if (os::supports_monotonic_clock()) {
@@ -4642,7 +4643,7 @@
         warning("Unable to use monotonic clock with relative timed-waits" \
                 " - changes to the time-of-day clock may have adverse affects");
       } else {
-        fatal("pthread_condattr_setclock: %s", strerror(status));
+        fatal("pthread_condattr_setclock: %s", os::strerror(status));
       }
     }
   }
@@ -4888,7 +4889,7 @@
        log_trace(os)("active_processor_count: "
                      "CPU_ALLOC failed (%s) - using "
                      "online processor count: %d",
-                     strerror(errno), online_cpus);
+                     os::strerror(errno), online_cpus);
        return online_cpus;
     }
   }
@@ -4918,7 +4919,7 @@
   else {
     cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN);
     warning("sched_getaffinity failed (%s)- using online processor count (%d) "
-            "which may exceed available processors", strerror(errno), cpu_count);
+            "which may exceed available processors", os::strerror(errno), cpu_count);
   }
 
   if (cpus_p != &cpus) { // can only be true when CPU_ALLOC used
@@ -5769,6 +5770,7 @@
   // Don't catch signals while blocked; let the running threads have the signals.
   // (This allows a debugger to break into the running thread.)
   sigset_t oldsigs;
+  sigemptyset(&oldsigs);
   sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
   pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
 #endif
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -29,6 +29,7 @@
 #include "oops/oop.inline.hpp"
 #include "os_linux.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/os.hpp"
 #include "runtime/perfMemory.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
@@ -100,7 +101,7 @@
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
-              destfile, strerror(errno));
+              destfile, os::strerror(errno));
     }
   } else {
     int fd = result;
@@ -111,7 +112,7 @@
       if (result == OS_ERR) {
         if (PrintMiscellaneous && Verbose) {
           warning("Could not write Perfdata save file: %s: %s\n",
-                  destfile, strerror(errno));
+                  destfile, os::strerror(errno));
         }
         break;
       }
@@ -123,7 +124,7 @@
     result = ::close(fd);
     if (PrintMiscellaneous && Verbose) {
       if (result == OS_ERR) {
-        warning("Could not close %s: %s\n", destfile, strerror(errno));
+        warning("Could not close %s: %s\n", destfile, os::strerror(errno));
       }
     }
   }
@@ -308,7 +309,7 @@
       if (errno == ELOOP) {
         warning("directory %s is a symlink and is not secure\n", dirname);
       } else {
-        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+        warning("could not open directory %s: %s\n", dirname, os::strerror(errno));
       }
     }
     return dirp;
@@ -419,7 +420,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+      warning("fstat failed on %s: %s\n", filename, os::strerror(errno));
     }
     return false;
   }
@@ -459,7 +460,7 @@
     if (PrintMiscellaneous && Verbose) {
       if (result != 0) {
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(result));
+                os::strerror(result));
       }
       else if (p == NULL) {
         // this check is added to protect against an observed problem
@@ -473,7 +474,7 @@
         // Bug Id 89052 was opened with RedHat.
         //
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(errno));
+                os::strerror(errno));
       }
       else {
         warning("Could not determine user name: %s\n",
@@ -509,7 +510,7 @@
                   "Process not found");
     }
     else /* EPERM */ {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_0(vmSymbols::java_io_IOException(), os::strerror(errno));
     }
   }
 
@@ -664,7 +665,7 @@
   if (PrintMiscellaneous && Verbose && result == OS_ERR) {
     if (errno != ENOENT) {
       warning("Could not unlink shared memory backing"
-              " store file %s : %s\n", path, strerror(errno));
+              " store file %s : %s\n", path, os::strerror(errno));
     }
   }
 }
@@ -772,7 +773,7 @@
       //
       if (PrintMiscellaneous && Verbose) {
         warning("could not create directory %s: %s\n",
-                dirname, strerror(errno));
+                dirname, os::strerror(errno));
       }
       return false;
     }
@@ -814,7 +815,7 @@
       if (errno == ELOOP) {
         warning("file %s is a symlink and is not secure\n", filename);
       } else {
-        warning("could not create file %s: %s\n", filename, strerror(errno));
+        warning("could not create file %s: %s\n", filename, os::strerror(errno));
       }
     }
     // close the directory and reset the current working directory
@@ -838,7 +839,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not truncate shared memory file: %s\n", strerror(errno));
+      warning("could not truncate shared memory file: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -847,7 +848,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not set shared memory file size: %s\n", strerror(errno));
+      warning("could not set shared memory file size: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -897,7 +898,7 @@
                   "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
+      THROW_MSG_(vmSymbols::java_io_IOException(), os::strerror(errno), OS_ERR);
     }
   }
   int fd = result;
@@ -970,7 +971,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed -  %s\n", strerror(errno));
+      warning("mmap failed -  %s\n", os::strerror(errno));
     }
     remove_file(filename);
     FREE_C_HEAP_ARRAY(char, filename);
@@ -1034,7 +1035,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed: %s\n", strerror(errno));
+      warning("fstat failed: %s\n", os::strerror(errno));
     }
     THROW_MSG_0(vmSymbols::java_io_IOException(),
                 "Could not determine PerfMemory size");
@@ -1151,7 +1152,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed: %s\n", strerror(errno));
+      warning("mmap failed: %s\n", os::strerror(errno));
     }
     THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
               "Could not map PerfMemory");
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1144,7 +1144,8 @@
 #define check_with_errno(check_type, cond, msg)                             \
   do {                                                                      \
     int err = errno;                                                        \
-    check_type(cond, "%s; error='%s' (errno=%d)", msg, strerror(err), err); \
+    check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err),   \
+               os::errno_name(err));                                        \
 } while (false)
 
 #define assert_with_errno(cond, msg)    check_with_errno(assert, cond, msg)
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, 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
@@ -461,7 +461,7 @@
     while ((res = ::sema_wait(wakeup())) == EINTR)
       ;
     if (res) {
-      warning("sema_wait failed: %s", strerror(res));
+      warning("sema_wait failed: %s", os::strerror(res));
       return NULL;
     }
 
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1009,7 +1009,7 @@
       (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));
+      os::errno_name(status), describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags));
   }
 
   if (status != 0) {
@@ -1354,7 +1354,7 @@
 jlong os::javaTimeMillis() {
   timeval t;
   if (gettimeofday(&t, NULL) == -1) {
-    fatal("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
+    fatal("os::javaTimeMillis: gettimeofday (%s)", os::strerror(errno));
   }
   return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
 }
@@ -1362,7 +1362,7 @@
 void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
   timeval t;
   if (gettimeofday(&t, NULL) == -1) {
-    fatal("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno));
+    fatal("os::javaTimeSystemUTC: gettimeofday (%s)", os::strerror(errno));
   }
   seconds = jlong(t.tv_sec);
   nanos = jlong(t.tv_usec) * 1000;
@@ -1892,21 +1892,39 @@
 
 static bool check_addr0(outputStream* st) {
   jboolean status = false;
+  const int read_chunk = 200;
+  int ret = 0;
+  int nmap = 0;
   int fd = ::open("/proc/self/map",O_RDONLY);
   if (fd >= 0) {
-    prmap_t p;
-    while (::read(fd, &p, sizeof(p)) > 0) {
-      if (p.pr_vaddr == 0x0) {
-        st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
-        st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
-        st->print("Access:");
-        st->print("%s",(p.pr_mflags & MA_READ)  ? "r" : "-");
-        st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
-        st->print("%s",(p.pr_mflags & MA_EXEC)  ? "x" : "-");
-        st->cr();
-        status = true;
+    prmap_t *p = NULL;
+    char *mbuff = (char *) calloc(read_chunk, sizeof(prmap_t));
+    if (NULL == mbuff) {
+      ::close(fd);
+      return status;
+    }
+    while ((ret = ::read(fd, mbuff, read_chunk*sizeof(prmap_t))) > 0) {
+      //check if read() has not read partial data
+      if( 0 != ret % sizeof(prmap_t)){
+        break;
+      }
+      nmap = ret / sizeof(prmap_t);
+      p = (prmap_t *)mbuff;
+      for(int i = 0; i < nmap; i++){
+        if (p->pr_vaddr == 0x0) {
+          st->print("Warning: Address: " PTR_FORMAT ", Size: " SIZE_FORMAT "K, ",p->pr_vaddr, p->pr_size/1024);
+          st->print("Mapped file: %s, ", p->pr_mapname[0] == '\0' ? "None" : p->pr_mapname);
+          st->print("Access: ");
+          st->print("%s",(p->pr_mflags & MA_READ)  ? "r" : "-");
+          st->print("%s",(p->pr_mflags & MA_WRITE) ? "w" : "-");
+          st->print("%s",(p->pr_mflags & MA_EXEC)  ? "x" : "-");
+          st->cr();
+          status = true;
+        }
+        p++;
       }
     }
+    free(mbuff);
     ::close(fd);
   }
   return status;
@@ -2142,7 +2160,7 @@
 size_t os::lasterror(char *buf, size_t len) {
   if (errno == 0)  return 0;
 
-  const char *s = ::strerror(errno);
+  const char *s = os::strerror(errno);
   size_t n = ::strlen(s);
   if (n >= len) {
     n = len - 1;
@@ -2351,7 +2369,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec,
-          strerror(err), err);
+          os::strerror(err), err);
 }
 
 static void warn_fail_commit_memory(char* addr, size_t bytes,
@@ -2359,7 +2377,7 @@
                                     int err) {
   warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
           ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes,
-          alignment_hint, exec, strerror(err), err);
+          alignment_hint, exec, os::strerror(err), err);
 }
 
 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) {
@@ -2740,7 +2758,7 @@
     char buf[256];
     buf[0] = '\0';
     if (addr == NULL) {
-      jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
+      jio_snprintf(buf, sizeof(buf), ": %s", os::strerror(err));
     }
     warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
             PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
@@ -4354,7 +4372,7 @@
 
   page_size = sysconf(_SC_PAGESIZE);
   if (page_size == -1) {
-    fatal("os_solaris.cpp: os::init: sysconf failed (%s)", strerror(errno));
+    fatal("os_solaris.cpp: os::init: sysconf failed (%s)", os::strerror(errno));
   }
   init_page_sizes((size_t) page_size);
 
@@ -4366,7 +4384,7 @@
 
   int fd = ::open("/dev/zero", O_RDWR);
   if (fd < 0) {
-    fatal("os::init: cannot open /dev/zero (%s)", strerror(errno));
+    fatal("os::init: cannot open /dev/zero (%s)", os::strerror(errno));
   } else {
     Solaris::set_dev_zero_fd(fd);
 
@@ -5607,7 +5625,7 @@
 
   if (pid < 0) {
     // fork failed
-    warning("fork failed: %s", strerror(errno));
+    warning("fork failed: %s", os::strerror(errno));
     return -1;
 
   } else if (pid == 0) {
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -102,7 +102,7 @@
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
-              destfile, strerror(errno));
+              destfile, os::strerror(errno));
     }
   } else {
 
@@ -114,7 +114,7 @@
       if (result == OS_ERR) {
         if (PrintMiscellaneous && Verbose) {
           warning("Could not write Perfdata save file: %s: %s\n",
-                  destfile, strerror(errno));
+                  destfile, os::strerror(errno));
         }
         break;
       }
@@ -125,7 +125,7 @@
     result = ::close(fd);
     if (PrintMiscellaneous && Verbose) {
       if (result == OS_ERR) {
-        warning("Could not close %s: %s\n", destfile, strerror(errno));
+        warning("Could not close %s: %s\n", destfile, os::strerror(errno));
       }
     }
   }
@@ -311,7 +311,7 @@
       if (errno == ELOOP) {
         warning("directory %s is a symlink and is not secure\n", dirname);
       } else {
-        warning("could not open directory %s: %s\n", dirname, strerror(errno));
+        warning("could not open directory %s: %s\n", dirname, os::strerror(errno));
       }
     }
     return dirp;
@@ -422,7 +422,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed on %s: %s\n", filename, strerror(errno));
+      warning("fstat failed on %s: %s\n", filename, os::strerror(errno));
     }
     return false;
   }
@@ -464,7 +464,7 @@
     if (PrintMiscellaneous && Verbose) {
       if (p == NULL) {
         warning("Could not retrieve passwd entry: %s\n",
-                strerror(errno));
+                os::strerror(errno));
       }
       else {
         warning("Could not determine user name: %s\n",
@@ -500,7 +500,7 @@
                   "Process not found");
     }
     else /* EPERM */ {
-      THROW_MSG_0(vmSymbols::java_io_IOException(), strerror(errno));
+      THROW_MSG_0(vmSymbols::java_io_IOException(), os::strerror(errno));
     }
   }
 
@@ -657,7 +657,7 @@
     // In this case, the psinfo file for the process id existed,
     // but we didn't have permission to access it.
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                strerror(errno));
+                os::strerror(errno));
   }
 
   // at this point, we don't know if the process id itself doesn't
@@ -703,7 +703,7 @@
   if (PrintMiscellaneous && Verbose && result == OS_ERR) {
     if (errno != ENOENT) {
       warning("Could not unlink shared memory backing"
-              " store file %s : %s\n", path, strerror(errno));
+              " store file %s : %s\n", path, os::strerror(errno));
     }
   }
 }
@@ -813,7 +813,7 @@
       //
       if (PrintMiscellaneous && Verbose) {
         warning("could not create directory %s: %s\n",
-                dirname, strerror(errno));
+                dirname, os::strerror(errno));
       }
       return false;
     }
@@ -855,7 +855,7 @@
       if (errno == ELOOP) {
         warning("file %s is a symlink and is not secure\n", filename);
       } else {
-        warning("could not create file %s: %s\n", filename, strerror(errno));
+        warning("could not create file %s: %s\n", filename, os::strerror(errno));
       }
     }
     // close the directory and reset the current working directory
@@ -879,7 +879,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)0), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not truncate shared memory file: %s\n", strerror(errno));
+      warning("could not truncate shared memory file: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -888,7 +888,7 @@
   RESTARTABLE(::ftruncate(fd, (off_t)size), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("could not set shared memory file size: %s\n", strerror(errno));
+      warning("could not set shared memory file size: %s\n", os::strerror(errno));
     }
     ::close(fd);
     return -1;
@@ -916,7 +916,7 @@
                   "Permission denied", OS_ERR);
     }
     else {
-      THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
+      THROW_MSG_(vmSymbols::java_io_IOException(), os::strerror(errno), OS_ERR);
     }
   }
   int fd = result;
@@ -990,7 +990,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed -  %s\n", strerror(errno));
+      warning("mmap failed -  %s\n", os::strerror(errno));
     }
     remove_file(filename);
     FREE_C_HEAP_ARRAY(char, filename);
@@ -1055,7 +1055,7 @@
   RESTARTABLE(::fstat(fd, &statbuf), result);
   if (result == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("fstat failed: %s\n", strerror(errno));
+      warning("fstat failed: %s\n", os::strerror(errno));
     }
     THROW_MSG_0(vmSymbols::java_io_IOException(),
                 "Could not determine PerfMemory size");
@@ -1172,7 +1172,7 @@
 
   if (mapAddress == MAP_FAILED) {
     if (PrintMiscellaneous && Verbose) {
-      warning("mmap failed: %s\n", strerror(errno));
+      warning("mmap failed: %s\n", os::strerror(errno));
     }
     THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
               "Could not map PerfMemory");
--- a/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/solaris/vm/threadCritical_solaris.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, 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
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "runtime/os.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
 
@@ -49,7 +50,7 @@
     if (global_mut_owner != owner) {
       if (os::Solaris::mutex_lock(&global_mut))
         fatal("ThreadCritical::ThreadCritical: mutex_lock failed (%s)",
-              strerror(errno));
+              os::strerror(errno));
       assert(global_mut_count == 0, "must have clean count");
       assert(global_mut_owner == -1, "must have clean owner");
     }
@@ -68,7 +69,7 @@
     if (global_mut_count == 0) {
       global_mut_owner = -1;
       if (os::Solaris::mutex_unlock(&global_mut))
-        fatal("ThreadCritical::~ThreadCritical: mutex_unlock failed (%s)", strerror(errno));
+        fatal("ThreadCritical::~ThreadCritical: mutex_unlock failed (%s)", os::strerror(errno));
     }
   } else {
     assert (Threads::number_of_threads() == 0, "valid only during initialization");
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -642,7 +642,7 @@
       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));
+      os::errno_name(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
   }
 
   if (thread_handle == NULL) {
@@ -1898,7 +1898,7 @@
 
   if (errno != 0) {
     // C runtime error that has no corresponding DOS error code
-    const char* s = strerror(errno);
+    const char* s = os::strerror(errno);
     size_t n = strlen(s);
     if (n >= len) n = len - 1;
     strncpy(buf, s, n);
@@ -2186,13 +2186,6 @@
 // Windows Vista/2008 heap corruption check
 #define EXCEPTION_HEAP_CORRUPTION        0xC0000374
 
-#define def_excpt(val) #val, val
-
-struct siglabel {
-  char *name;
-  int   number;
-};
-
 // All Visual C++ exceptions thrown from code generated by the Microsoft Visual
 // C++ compiler contain this error code. Because this is a compiler-generated
 // error, the code is not listed in the Win32 API header files.
@@ -2202,8 +2195,9 @@
 
 #define EXCEPTION_UNCAUGHT_CXX_EXCEPTION    0xE06D7363
 
-
-struct siglabel exceptlabels[] = {
+#define def_excpt(val) { #val, (val) }
+
+static const struct { char* name; uint number; } exceptlabels[] = {
     def_excpt(EXCEPTION_ACCESS_VIOLATION),
     def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
     def_excpt(EXCEPTION_BREAKPOINT),
@@ -2228,16 +2222,18 @@
     def_excpt(EXCEPTION_GUARD_PAGE),
     def_excpt(EXCEPTION_INVALID_HANDLE),
     def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
-    def_excpt(EXCEPTION_HEAP_CORRUPTION),
+    def_excpt(EXCEPTION_HEAP_CORRUPTION)
 #ifdef _M_IA64
-    def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
+    , def_excpt(EXCEPTION_REG_NAT_CONSUMPTION)
 #endif
-    NULL, 0
 };
 
+#undef def_excpt
+
 const char* os::exception_name(int exception_code, char *buf, size_t size) {
-  for (int i = 0; exceptlabels[i].name != NULL; i++) {
-    if (exceptlabels[i].number == exception_code) {
+  uint code = static_cast<uint>(exception_code);
+  for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {
+    if (exceptlabels[i].number == code) {
       jio_snprintf(buf, size, "%s", exceptlabels[i].name);
       return buf;
     }
@@ -2445,7 +2441,7 @@
             jio_snprintf(buf, sizeof(buf), "Execution protection violation "
                          "at " INTPTR_FORMAT
                          ", unguarding " INTPTR_FORMAT ": %s", addr,
-                         page_start, (res ? "success" : strerror(errno)));
+                         page_start, (res ? "success" : os::strerror(errno)));
             tty->print_raw_cr(buf);
           }
 
@@ -5638,9 +5634,11 @@
   "TERM",       SIGTERM,        // software term signal from kill
   "BREAK",      SIGBREAK,       // Ctrl-Break sequence
   "ILL",        SIGILL};        // illegal instruction
-  for(int i=0;i<sizeof(siglabels)/sizeof(struct siglabel);i++)
-    if(!strcmp(name, siglabels[i].name))
+  for (unsigned i = 0; i < ARRAY_SIZE(siglabels); ++i) {
+    if (strcmp(name, siglabels[i].name) == 0) {
       return siglabels[i].number;
+    }
+  }
   return -1;
 }
 
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, 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
@@ -96,7 +96,7 @@
   if (fd == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
       warning("Could not create Perfdata save file: %s: %s\n",
-              destfile, strerror(errno));
+              destfile, os::strerror(errno));
     }
   } else {
     for (size_t remaining = size; remaining > 0;) {
@@ -105,7 +105,7 @@
       if (nbytes == OS_ERR) {
         if (PrintMiscellaneous && Verbose) {
           warning("Could not write Perfdata save file: %s: %s\n",
-                  destfile, strerror(errno));
+                  destfile, os::strerror(errno));
         }
         break;
       }
@@ -117,7 +117,7 @@
     int result = ::_close(fd);
     if (PrintMiscellaneous && Verbose) {
       if (result == OS_ERR) {
-        warning("Could not close %s: %s\n", destfile, strerror(errno));
+        warning("Could not close %s: %s\n", destfile, os::strerror(errno));
       }
     }
   }
@@ -497,7 +497,7 @@
     if (PrintMiscellaneous && Verbose) {
       if (errno != ENOENT) {
         warning("Could not unlink shared memory backing"
-                " store file %s : %s\n", path, strerror(errno));
+                " store file %s : %s\n", path, os::strerror(errno));
       }
     }
   }
@@ -1358,7 +1358,7 @@
     if (ret_code == OS_ERR) {
       if (PrintMiscellaneous && Verbose) {
         warning("Could not get status information from file %s: %s\n",
-            filename, strerror(errno));
+            filename, os::strerror(errno));
       }
       CloseHandle(fmh);
       CloseHandle(fh);
@@ -1553,7 +1553,7 @@
   //
   if (::stat(filename, &statbuf) == OS_ERR) {
     if (PrintMiscellaneous && Verbose) {
-      warning("stat %s failed: %s\n", filename, strerror(errno));
+      warning("stat %s failed: %s\n", filename, os::strerror(errno));
     }
     THROW_MSG_0(vmSymbols::java_io_IOException(),
                 "Could not determine PerfMemory size");
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 #include "interpreter/interpreter.hpp"
 #include "jvm_windows.h"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "mutex_windows.inline.hpp"
 #include "nativeInst_x86.hpp"
 #include "os_share_windows.hpp"
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,9 @@
 #include "code/debugInfoRec.hpp"
 #include "compiler/compileLog.hpp"
 #include "compiler/compilerDirectives.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "runtime/timerTrace.hpp"
 
 typedef enum {
   _t_compile,
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 #include "ci/ciMemberName.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecode.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/compilationPolicy.hpp"
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 #include "c1/c1_IR.hpp"
 #include "c1/c1_InstructionPrinter.hpp"
 #include "c1/c1_Optimizer.hpp"
+#include "memory/resourceArea.hpp"
 #include "utilities/bitMap.inline.hpp"
 
 
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,6 +32,7 @@
 #include "c1/c1_LinearScan.hpp"
 #include "c1/c1_ValueStack.hpp"
 #include "code/vmreg.inline.hpp"
+#include "runtime/timerTrace.hpp"
 #include "utilities/bitMap.inline.hpp"
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "c1/c1_ValueMap.hpp"
 #include "c1/c1_ValueSet.hpp"
 #include "c1/c1_ValueStack.hpp"
+#include "memory/resourceArea.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "compiler/compileLog.hpp"
 
--- a/hotspot/src/share/vm/c1/c1_ValueType.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueType.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "ci/ciArray.hpp"
 #include "ci/ciInstance.hpp"
 #include "ci/ciNullObject.hpp"
+#include "memory/resourceArea.hpp"
 
 
 // predefined types
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
 #include "interpreter/linkResolver.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/methodData.hpp"
 #include "oops/objArrayKlass.hpp"
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,4 +1,5 @@
-/* Copyright (c) 2013, 2016, 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,6 +29,7 @@
 #include "ci/ciKlass.hpp"
 #include "ci/ciUtilities.hpp"
 #include "compiler/compileBroker.hpp"
+#include "gc/shared/referencePendingListLocker.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -574,7 +576,7 @@
     Method* method = parse_method(CHECK);
     if (had_error()) return;
     /* just copied from Method, to build interpret data*/
-    if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
+    if (ReferencePendingListLocker::is_locked_by_self()) {
       return;
     }
     // To be properly initialized, some profiling in the MDO needs the
--- a/hotspot/src/share/vm/ci/ciSignature.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciSignature.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "ci/ciSignature.hpp"
 #include "ci/ciUtilities.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/signature.hpp"
 
--- a/hotspot/src/share/vm/ci/ciType.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciType.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "ci/ciType.hpp"
 #include "ci/ciUtilities.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 
 ciType* ciType::_basic_types[T_CONFLICT+1];
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 #include "interpreter/bytecode.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "opto/compile.hpp"
 #include "opto/node.hpp"
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -5372,12 +5372,12 @@
       }
     }
 
-    if (log_is_enabled(Info, classresolve))  {
+    if (log_is_enabled(Debug, classresolve))  {
       ResourceMark rm;
       // print out the superclass.
       const char * from = ik->external_name();
       if (ik->java_super() != NULL) {
-        log_info(classresolve)("%s %s (super)",
+        log_debug(classresolve)("%s %s (super)",
                    from,
                    ik->java_super()->external_name());
       }
@@ -5388,7 +5388,7 @@
         for (int i = 0; i < length; i++) {
           const Klass* const k = local_interfaces->at(i);
           const char * to = k->external_name();
-          log_info(classresolve)("%s %s (interface)", from, to);
+          log_debug(classresolve)("%s %s (interface)", from, to);
         }
       }
     }
@@ -5698,15 +5698,16 @@
   }
 
   if (!is_internal()) {
-    if (TraceClassLoadingPreorder) {
-      tty->print("[Loading %s",
-        _class_name->as_klass_external_name());
-
+    if (log_is_enabled(Debug, classload, preorder)){
+      ResourceMark rm(THREAD);
+      outputStream* log = Log(classload, preorder)::debug_stream();
+      log->print("%s", _class_name->as_klass_external_name());
       if (stream->source() != NULL) {
-        tty->print(" from %s", stream->source());
+        log->print(" source: %s", stream->source());
       }
-      tty->print_cr("]");
+      log->cr();
     }
+
 #if INCLUDE_CDS
     if (DumpLoadedClassList != NULL && stream->source() != NULL && classlist_file->is_open()) {
       // Only dump the classes that can be stored into CDS archive
--- a/hotspot/src/share/vm/classfile/classFileStream.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileStream.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/classFileStream.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "memory/resourceArea.hpp"
 
 const bool ClassFileStream::verify = true;
 const bool ClassFileStream::no_verification = false;
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -44,6 +44,7 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
@@ -226,11 +227,12 @@
   return NULL;
 }
 
-ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() {
+ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append) : ClassPathEntry() {
   _zip = zip;
   char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
   strcpy(copy, zip_name);
   _zip_name = copy;
+  _is_boot_append = is_boot_append;
 }
 
 ClassPathZipEntry::~ClassPathZipEntry() {
@@ -274,11 +276,79 @@
   return buffer;
 }
 
+#if INCLUDE_CDS
+u1* ClassPathZipEntry::open_versioned_entry(const char* name, jint* filesize, TRAPS) {
+  u1* buffer = NULL;
+  if (!_is_boot_append) {
+    assert(DumpSharedSpaces, "Should be called only for non-boot entries during dump time");
+    // We presume default is multi-release enabled
+    const char* multi_ver = Arguments::get_property("jdk.util.jar.enableMultiRelease");
+    const char* verstr = Arguments::get_property("jdk.util.jar.version");
+    bool is_multi_ver = (multi_ver == NULL ||
+                         strcmp(multi_ver, "true") == 0 ||
+                         strcmp(multi_ver, "force")  == 0) &&
+                         is_multiple_versioned(THREAD);
+    // command line version setting
+    int version = 0;
+    const int base_version = 8; // JDK8
+    int cur_ver = JDK_Version::current().major_version();
+    if (verstr != NULL) {
+      version = atoi(verstr);
+      if (version < base_version || version > cur_ver) {
+        is_multi_ver = false;
+        // print out warning, do not use assertion here since it will continue to look
+        // for proper version.
+        warning("JDK%d is not supported in multiple version jars", version);
+      }
+    }
+
+    if (is_multi_ver) {
+      int n;
+      char entry_name[JVM_MAXPATHLEN];
+      if (version > 0) {
+        n = jio_snprintf(entry_name, sizeof(entry_name), "META-INF/versions/%d/%s", version, name);
+        entry_name[n] = '\0';
+        buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL);
+        if (buffer == NULL) {
+          warning("Could not find %s in %s, try to find highest version instead", entry_name, _zip_name);
+        }
+      }
+      if (buffer == NULL) {
+        for (int i = cur_ver; i >= base_version; i--) {
+          n = jio_snprintf(entry_name, sizeof(entry_name), "META-INF/versions/%d/%s", i, name);
+          entry_name[n] = '\0';
+          buffer = open_entry((const char*)entry_name, filesize, false, CHECK_NULL);
+          if (buffer != NULL) {
+            break;
+          }
+        }
+      }
+    }
+  }
+  return buffer;
+}
+
+bool ClassPathZipEntry::is_multiple_versioned(TRAPS) {
+  assert(DumpSharedSpaces, "called only at dump time");
+  jint size;
+  char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, false, CHECK_false);
+  if (buffer != NULL) {
+    if (strstr(buffer, "Multi-Release: true") != NULL) {
+      return true;
+    }
+  }
+  return false;
+}
+#endif // INCLUDE_CDS
+
 ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
   jint filesize;
-  const u1* buffer = open_entry(name, &filesize, false, CHECK_NULL);
+  u1* buffer = open_versioned_entry(name, &filesize, CHECK_NULL);
   if (buffer == NULL) {
-    return NULL;
+    buffer = open_entry(name, &filesize, false, CHECK_NULL);
+    if (buffer == NULL) {
+      return NULL;
+    }
   }
   if (UsePerfData) {
     ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
@@ -466,7 +536,7 @@
 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();
+    outputStream* out = Log(classpath)::info_stream();
     if (msg) {
       out->print("%s", msg);
     }
@@ -558,7 +628,7 @@
     char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
     strncpy(path, &class_path[start], end - start);
     path[end - start] = '\0';
-    update_class_path_entry_list(path, false, mark_append_entry, false);
+    update_class_path_entry_list(path, false, mark_append_entry, false, bootstrap_search);
 
     // Check on the state of the boot loader's append path
     if (mark_append_entry && (_first_append_entry == NULL)) {
@@ -582,7 +652,8 @@
 }
 
 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
-                                                     bool throw_exception, TRAPS) {
+                                                     bool throw_exception,
+                                                     bool is_boot_append, TRAPS) {
   JavaThread* thread = JavaThread::current();
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFREG) == S_IFREG) {
@@ -611,7 +682,7 @@
         zip = (*ZipOpen)(canonical_path, &error_msg);
       }
       if (zip != NULL && error_msg == NULL) {
-        new_entry = new ClassPathZipEntry(zip, path);
+        new_entry = new ClassPathZipEntry(zip, path, is_boot_append);
       } else {
         ResourceMark rm(thread);
         char *msg;
@@ -644,7 +715,7 @@
 
 // Create a class path zip entry for a given path (return NULL if not found
 // or zip/JAR file cannot be opened)
-ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path) {
+ClassPathZipEntry* ClassLoader::create_class_path_zip_entry(const char *path, bool is_boot_append) {
   // check for a regular file
   struct stat st;
   if (os::stat(path, &st) == 0) {
@@ -662,7 +733,7 @@
         }
         if (zip != NULL && error_msg == NULL) {
           // create using canonical path
-          return new ClassPathZipEntry(zip, canonical_path);
+          return new ClassPathZipEntry(zip, canonical_path, is_boot_append);
         }
       }
     }
@@ -720,11 +791,11 @@
 }
 
 void ClassLoader::add_to_list(const char *apath) {
-  update_class_path_entry_list((char*)apath, false, false, false);
+  update_class_path_entry_list((char*)apath, false, false, false, false);
 }
 
 void ClassLoader::prepend_to_list(const char *apath) {
-  update_class_path_entry_list((char*)apath, false, false, true);
+  update_class_path_entry_list((char*)apath, false, false, true, false);
 }
 
 // Returns true IFF the file/dir exists and the entry was successfully created.
@@ -732,13 +803,14 @@
                                                bool check_for_duplicates,
                                                bool mark_append_entry,
                                                bool prepend_entry,
+                                               bool is_boot_append,
                                                bool throw_exception) {
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // File or directory found
     ClassPathEntry* new_entry = NULL;
     Thread* THREAD = Thread::current();
-    new_entry = create_class_path_entry(path, &st, throw_exception, CHECK_(false));
+    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, CHECK_(false));
     if (new_entry == NULL) {
       return false;
     }
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -104,16 +104,19 @@
  private:
   jzfile* _zip;              // The zip archive
   const char*   _zip_name;   // Name of zip archive
+  bool _is_boot_append;      // entry coming from -Xbootclasspath/a
  public:
   bool is_jrt()            { return false; }
   bool is_jar_file() const { return true;  }
   const char* name() const { return _zip_name; }
   JImageFile* jimage() const { return NULL; }
-  ClassPathZipEntry(jzfile* zip, const char* zip_name);
+  ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append);
   ~ClassPathZipEntry();
   u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
+  u1* open_versioned_entry(const char* name, jint* filesize, TRAPS) NOT_CDS_RETURN_(NULL);
   ClassFileStream* open_stream(const char* name, TRAPS);
   void contents_do(void f(const char* name, void* context), void* context);
+  bool is_multiple_versioned(TRAPS) NOT_CDS_RETURN_(false);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
 };
@@ -223,7 +226,8 @@
   static void load_zip_library();
   static void load_jimage_library();
   static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
-                                                 bool throw_exception, TRAPS);
+                                                 bool throw_exception,
+                                                 bool is_boot_append, TRAPS);
 
  public:
 
@@ -249,6 +253,7 @@
                                            bool check_for_duplicates,
                                            bool mark_append_entry,
                                            bool prepend_entry,
+                                           bool is_boot_append,
                                            bool throw_exception=true);
   static void print_bootclasspath();
 
@@ -394,7 +399,7 @@
   static void prepend_to_list(ClassPathEntry* new_entry);
 
   // creates a class path zip entry (returns NULL if JAR file cannot be opened)
-  static ClassPathZipEntry* create_class_path_zip_entry(const char *apath);
+  static ClassPathZipEntry* create_class_path_zip_entry(const char *apath, bool is_boot_append);
 
   // add a path to class path list
   static void add_to_list(const char* apath);
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -60,6 +60,7 @@
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -357,7 +358,7 @@
 
   if (log_is_enabled(Debug, classloaderdata)) {
     ResourceMark rm;
-    outputStream* log = LogHandle(classloaderdata)::debug_stream();
+    outputStream* log = Log(classloaderdata)::debug_stream();
     log->print(": unload loader data " INTPTR_FORMAT, p2i(this));
     log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()),
                loader_name());
@@ -717,7 +718,7 @@
   }
 
   ResourceMark rm;
-  outputStream* log = LogHandle(classloaderdata)::debug_stream();
+  outputStream* log = Log(classloaderdata)::debug_stream();
   log->print("create class loader data " INTPTR_FORMAT, p2i(cld));
   log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()),
              cld->loader_name());
@@ -859,7 +860,7 @@
       array->push(curr);
 
       if (log_is_enabled(Debug, classloaderdata)) {
-        outputStream* log = LogHandle(classloaderdata)::debug_stream();
+        outputStream* log = Log(classloaderdata)::debug_stream();
         log->print("found new CLD: ");
         curr->print_value_on(log);
         log->cr();
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -437,7 +437,7 @@
       _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
       if (log_is_enabled(Debug, defaultmethods)) {
         ResourceMark rm;
-        outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+        outputStream* logstream = Log(defaultmethods)::debug_stream();
         _exception_message->print_value_on(logstream);
         logstream->cr();
       }
@@ -663,7 +663,7 @@
   if (log_is_enabled(Debug, defaultmethods)) {
     log_debug(defaultmethods)("Slots that need filling:");
     ResourceMark rm;
-    outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+    outputStream* logstream = Log(defaultmethods)::debug_stream();
     streamIndentor si(logstream);
     for (int i = 0; i < slots->length(); ++i) {
       logstream->indent();
@@ -799,7 +799,7 @@
     log_debug(defaultmethods)("%s %s requires default method processing",
                               klass->is_interface() ? "Interface" : "Class",
                               klass->name()->as_klass_external_name());
-    PrintHierarchy printer(LogHandle(defaultmethods)::debug_stream());
+    PrintHierarchy printer(Log(defaultmethods)::debug_stream());
     printer.run(klass);
   }
 
@@ -809,7 +809,7 @@
   for (int i = 0; i < empty_slots->length(); ++i) {
     EmptyVtableSlot* slot = empty_slots->at(i);
     if (log_is_enabled(Debug, defaultmethods)) {
-      outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+      outputStream* logstream = Log(defaultmethods)::debug_stream();
       streamIndentor si(logstream, 2);
       logstream->indent().print("Looking for default methods for slot ");
       slot->print_on(logstream);
@@ -917,7 +917,7 @@
 
       if (log_is_enabled(Debug, defaultmethods)) {
         ResourceMark rm;
-        outputStream* logstream = LogHandle(defaultmethods)::debug_stream();
+        outputStream* logstream = Log(defaultmethods)::debug_stream();
         logstream->print("for slot: ");
         slot->print_on(logstream);
         logstream->cr();
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -29,6 +29,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "memory/iterator.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
 #include "runtime/orderAccess.inline.hpp"
@@ -137,7 +138,7 @@
   }
   if (log_is_enabled(Trace, protectiondomain)) {
     ResourceMark rm;
-    outputStream* log = LogHandle(protectiondomain)::trace_stream();
+    outputStream* log = Log(protectiondomain)::trace_stream();
     print_count(log);
   }
 }
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -515,22 +515,6 @@
   return result;
 }
 
-unsigned int java_lang_String::hash_string(oop java_string) {
-  int          length = java_lang_String::length(java_string);
-  // Zero length string doesn't necessarily hash to zero.
-  if (length == 0) {
-    return StringTable::hash_string((jchar*) NULL, 0);
-  }
-
-  typeArrayOop value  = java_lang_String::value(java_string);
-  bool      is_latin1 = java_lang_String::is_latin1(java_string);
-  if (is_latin1) {
-    return StringTable::hash_string(value->byte_at_addr(0), length);
-  } else {
-    return StringTable::hash_string(value->char_at_addr(0), length);
-  }
-}
-
 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
   oop          obj    = java_string();
   typeArrayOop value  = java_lang_String::value(obj);
@@ -1473,6 +1457,12 @@
   compute_offset(_ngroups_offset,     k, vmSymbols::ngroups_name(),     vmSymbols::int_signature());
 }
 
+
+void java_lang_Throwable::compute_offsets() {
+  Klass* k = SystemDictionary::Throwable_klass();
+  compute_offset(depth_offset, k, vmSymbols::depth_name(), vmSymbols::int_signature());
+}
+
 oop java_lang_Throwable::unassigned_stacktrace() {
   InstanceKlass* ik = SystemDictionary::Throwable_klass();
   address addr = ik->static_field_addr(static_unassigned_stacktrace_offset);
@@ -1492,11 +1482,13 @@
   throwable->release_obj_field_put(backtrace_offset, value);
 }
 
-
-oop java_lang_Throwable::message(oop throwable) {
-  return throwable->obj_field(detailMessage_offset);
-}
-
+int java_lang_Throwable::depth(oop throwable) {
+  return throwable->int_field(depth_offset);
+}
+
+void java_lang_Throwable::set_depth(oop throwable, int value) {
+  throwable->int_field_put(depth_offset, value);
+}
 
 oop java_lang_Throwable::message(Handle throwable) {
   return throwable->obj_field(detailMessage_offset);
@@ -1546,10 +1538,12 @@
   return method != NULL && (method->constants()->version() == version);
 }
 
+
 // This class provides a simple wrapper over the internal structure of
 // exception backtrace to insulate users of the backtrace from needing
 // to know what it looks like.
 class BacktraceBuilder: public StackObj {
+ friend class BacktraceIterator;
  private:
   Handle          _backtrace;
   objArrayOop     _head;
@@ -1560,8 +1554,6 @@
   int             _index;
   NoSafepointVerifier _nsv;
 
- public:
-
   enum {
     trace_methods_offset = java_lang_Throwable::trace_methods_offset,
     trace_bcis_offset    = java_lang_Throwable::trace_bcis_offset,
@@ -1594,6 +1586,8 @@
     return cprefs;
   }
 
+ public:
+
   // constructor for new backtrace
   BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) {
     expand(CHECK);
@@ -1679,9 +1673,68 @@
 
 };
 
+struct BacktraceElement : public StackObj {
+  int _method_id;
+  int _bci;
+  int _version;
+  int _cpref;
+  Handle _mirror;
+  BacktraceElement(Handle mirror, int mid, int version, int bci, int cpref) :
+                   _mirror(mirror), _method_id(mid), _version(version), _bci(bci), _cpref(cpref) {}
+};
+
+class BacktraceIterator : public StackObj {
+  int _index;
+  objArrayHandle  _result;
+  objArrayHandle  _mirrors;
+  typeArrayHandle _methods;
+  typeArrayHandle _bcis;
+  typeArrayHandle _cprefs;
+
+  void init(objArrayHandle result, Thread* thread) {
+    // Get method id, bci, version and mirror from chunk
+    _result = result;
+    if (_result.not_null()) {
+      _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result));
+      _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result));
+      _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result));
+      _cprefs = typeArrayHandle(thread, BacktraceBuilder::get_cprefs(_result));
+      _index = 0;
+    }
+  }
+ public:
+  BacktraceIterator(objArrayHandle result, Thread* thread) {
+    init(result, thread);
+    assert(_methods.is_null() || _methods->length() == java_lang_Throwable::trace_chunk_size, "lengths don't match");
+  }
+
+  BacktraceElement next(Thread* thread) {
+    BacktraceElement e (Handle(thread, _mirrors->obj_at(_index)),
+                        _methods->short_at(_index),
+                        Backtrace::version_at(_bcis->int_at(_index)),
+                        Backtrace::bci_at(_bcis->int_at(_index)),
+                        _cprefs->short_at(_index));
+    _index++;
+
+    if (_index >= java_lang_Throwable::trace_chunk_size) {
+      int next_offset = java_lang_Throwable::trace_next_offset;
+      // Get next chunk
+      objArrayHandle result (thread, objArrayOop(_result->obj_at(next_offset)));
+      init(result, thread);
+    }
+    return e;
+  }
+
+  bool repeat() {
+    return _result.not_null() && _mirrors->obj_at(_index) != NULL;
+  }
+};
+
+
 // Print stack trace element to resource allocated buffer
-char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
-                                  int method_id, int version, int bci, int cpref) {
+static void print_stack_element_to_stream(outputStream* st, Handle mirror, int method_id,
+                                          int version, int bci, int cpref) {
+  ResourceMark rm;
 
   // Get strings and string lengths
   InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
@@ -1752,13 +1805,6 @@
     }
   }
 
-  return buf;
-}
-
-void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror,
-                                              int method_id, int version, int bci, int cpref) {
-  ResourceMark rm;
-  char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref);
   st->print_cr("%s", buf);
 }
 
@@ -1767,11 +1813,7 @@
   int method_id = method->orig_method_idnum();
   int version = method->constants()->version();
   int cpref = method->name_index();
-  print_stack_element(st, mirror, method_id, version, bci, cpref);
-}
-
-const char* java_lang_Throwable::no_stack_trace_message() {
-  return "\t<<no stack trace available>>";
+  print_stack_element_to_stream(st, mirror, method_id, version, bci, cpref);
 }
 
 /**
@@ -1788,32 +1830,17 @@
   while (throwable.not_null()) {
     objArrayHandle result (THREAD, objArrayOop(backtrace(throwable())));
     if (result.is_null()) {
-      st->print_raw_cr(no_stack_trace_message());
+      st->print_raw_cr("\t<<no stack trace available>>");
       return;
     }
-
-    while (result.not_null()) {
-      // Get method id, bci, version and mirror from chunk
-      typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result));
-      typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result));
-      objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result));
-      typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result));
-
-      int length = methods()->length();
-      for (int index = 0; index < length; index++) {
-        Handle mirror(THREAD, mirrors->obj_at(index));
-        // NULL mirror means end of stack trace
-        if (mirror.is_null()) goto handle_cause;
-        int method = methods->short_at(index);
-        int version = Backtrace::version_at(bcis->int_at(index));
-        int bci = Backtrace::bci_at(bcis->int_at(index));
-        int cpref = cprefs->short_at(index);
-        print_stack_element(st, mirror, method, version, bci, cpref);
-      }
-      result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
+    BacktraceIterator iter(result, THREAD);
+
+    while (iter.repeat()) {
+      BacktraceElement bte = iter.next(THREAD);
+      print_stack_element_to_stream(st, bte._mirror, bte._method_id, bte._version, bte._bci, bte._cpref);
     }
-  handle_cause:
     {
+      // Call getCause() which doesn't necessarily return the _cause field.
       EXCEPTION_MARK;
       JavaValue cause(T_OBJECT);
       JavaCalls::call_virtual(&cause,
@@ -1865,6 +1892,7 @@
 
   int max_depth = MaxJavaStackTraceDepth;
   JavaThread* thread = (JavaThread*)THREAD;
+
   BacktraceBuilder bt(CHECK);
 
   // If there is no Java frame just return the method that was being called
@@ -1872,6 +1900,8 @@
   if (!thread->has_last_Java_frame()) {
     if (max_depth >= 1 && method() != NULL) {
       bt.push(method(), 0, CHECK);
+      log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), 1);
+      set_depth(throwable(), 1);
       set_backtrace(throwable(), bt.backtrace());
     }
     return;
@@ -1979,8 +2009,11 @@
     total_count++;
   }
 
+  log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), total_count);
+
   // Put completed stack trace into throwable object
   set_backtrace(throwable(), bt.backtrace());
+  set_depth(throwable(), total_count);
 }
 
 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method) {
@@ -2034,94 +2067,60 @@
   // methods as preallocated errors aren't created by "java" code.
 
   // fill in as much stack trace as possible
-  typeArrayOop methods = BacktraceBuilder::get_methods(backtrace);
-  int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth);
   int chunk_count = 0;
-
   for (;!st.at_end(); st.next()) {
     bt.push(st.method(), st.bci(), CHECK);
     chunk_count++;
 
     // Bail-out for deep stacks
-    if (chunk_count >= max_chunks) break;
+    if (chunk_count >= trace_chunk_size) break;
   }
+  set_depth(throwable(), chunk_count);
+  log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), chunk_count);
 
   // We support the Throwable immutability protocol defined for Java 7.
   java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
   assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
 }
 
-
-int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) {
-  if (throwable == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+void java_lang_Throwable::get_stack_trace_elements(Handle throwable,
+                                                   objArrayHandle stack_trace_array_h, TRAPS) {
+
+  if (throwable.is_null() || stack_trace_array_h.is_null()) {
+    THROW(vmSymbols::java_lang_NullPointerException());
   }
-  objArrayOop chunk = objArrayOop(backtrace(throwable));
-  int depth = 0;
-  if (chunk != NULL) {
-    // Iterate over chunks and count full ones
-    while (true) {
-      objArrayOop next = objArrayOop(chunk->obj_at(trace_next_offset));
-      if (next == NULL) break;
-      depth += trace_chunk_size;
-      chunk = next;
-    }
-    assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check");
-    // Count element in remaining partial chunk.  NULL value for mirror
-    // marks the end of the stack trace elements that are saved.
-    objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
-    assert(mirrors != NULL, "sanity check");
-    for (int i = 0; i < mirrors->length(); i++) {
-      if (mirrors->obj_at(i) == NULL) break;
-      depth++;
-    }
-  }
-  return depth;
-}
-
-
-oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) {
-  if (throwable == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
-  }
-  if (index < 0) {
-    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
+
+  assert(stack_trace_array_h->is_objArray(), "Stack trace array should be an array of StackTraceElenent");
+
+  if (stack_trace_array_h->length() != depth(throwable())) {
+    THROW(vmSymbols::java_lang_IndexOutOfBoundsException());
   }
-  // Compute how many chunks to skip and index into actual chunk
-  objArrayOop chunk = objArrayOop(backtrace(throwable));
-  int skip_chunks = index / trace_chunk_size;
-  int chunk_index = index % trace_chunk_size;
-  while (chunk != NULL && skip_chunks > 0) {
-    chunk = objArrayOop(chunk->obj_at(trace_next_offset));
-        skip_chunks--;
-  }
-  if (chunk == NULL) {
-    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
+
+  objArrayHandle result(THREAD, objArrayOop(backtrace(throwable())));
+  BacktraceIterator iter(result, THREAD);
+
+  int index = 0;
+  while (iter.repeat()) {
+    BacktraceElement bte = iter.next(THREAD);
+
+    Handle stack_trace_element(THREAD, stack_trace_array_h->obj_at(index++));
+
+    if (stack_trace_element.is_null()) {
+      THROW(vmSymbols::java_lang_NullPointerException());
+    }
+
+    InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(bte._mirror()));
+    methodHandle method (THREAD, holder->method_with_orig_idnum(bte._method_id, bte._version));
+
+    java_lang_StackTraceElement::fill_in(stack_trace_element, holder,
+                                         method,
+                                         bte._version,
+                                         bte._bci,
+                                         bte._cpref, CHECK);
   }
-  // Get method id, bci, version, mirror and cpref from chunk
-  typeArrayOop methods = BacktraceBuilder::get_methods(chunk);
-  typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk);
-  objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
-  typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk);
-
-  assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
-
-  int method = methods->short_at(chunk_index);
-  int version = Backtrace::version_at(bcis->int_at(chunk_index));
-  int bci = Backtrace::bci_at(bcis->int_at(chunk_index));
-  int cpref = cprefs->short_at(chunk_index);
-  Handle mirror(THREAD, mirrors->obj_at(chunk_index));
-
-  // Chunk can be partial full
-  if (mirror.is_null()) {
-    THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
-  }
-  oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0);
-  return element;
-}
-
-oop java_lang_StackTraceElement::create(Handle mirror, int method_id,
-                                        int version, int bci, int cpref, TRAPS) {
+}
+
+oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) {
   // Allocate java.lang.StackTraceElement instance
   Klass* k = SystemDictionary::StackTraceElement_klass();
   assert(k != NULL, "must be loaded in 1.4+");
@@ -2132,37 +2131,45 @@
 
   Handle element = ik->allocate_instance_handle(CHECK_0);
 
+  int cpref = method->name_index();
+  int version = method->constants()->version();
+  fill_in(element, method->method_holder(), method, version, bci, cpref, CHECK_0);
+  return element();
+}
+
+void java_lang_StackTraceElement::fill_in(Handle element,
+                                          InstanceKlass* holder, const methodHandle& method,
+                                          int version, int bci, int cpref, TRAPS) {
+  assert(element->is_a(SystemDictionary::StackTraceElement_klass()), "sanity check");
+
   // Fill in class name
   ResourceMark rm(THREAD);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
   const char* str = holder->external_name();
-  oop classname = StringTable::intern((char*) str, CHECK_0);
+  oop classname = StringTable::intern((char*) str, CHECK);
   java_lang_StackTraceElement::set_declaringClass(element(), classname);
 
-  Method* method = holder->method_with_orig_idnum(method_id, version);
-
   // The method can be NULL if the requested class version is gone
-  Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
+  Symbol* sym = !method.is_null() ? method->name() : holder->constants()->symbol_at(cpref);
 
   // Fill in method name
-  oop methodname = StringTable::intern(sym, CHECK_0);
+  oop methodname = StringTable::intern(sym, CHECK);
   java_lang_StackTraceElement::set_methodName(element(), methodname);
 
   // Fill in module name and version
   ModuleEntry* module = holder->module();
   if (module->is_named()) {
-    oop module_name = StringTable::intern(module->name(), CHECK_0);
+    oop module_name = StringTable::intern(module->name(), CHECK);
     java_lang_StackTraceElement::set_moduleName(element(), module_name);
     oop module_version;
     if (module->version() != NULL) {
-      module_version = StringTable::intern(module->version(), CHECK_0);
+      module_version = StringTable::intern(module->version(), CHECK);
     } else {
       module_version = NULL;
     }
     java_lang_StackTraceElement::set_moduleVersion(element(), module_version);
   }
 
-  if (!version_matches(method, version)) {
+  if (!version_matches(method(), version)) {
     // The method was redefined, accurate line number information isn't available
     java_lang_StackTraceElement::set_fileName(element(), NULL);
     java_lang_StackTraceElement::set_lineNumber(element(), -1);
@@ -2171,20 +2178,12 @@
     Symbol* source = Backtrace::get_source_file_name(holder, version);
     if (ShowHiddenFrames && source == NULL)
       source = vmSymbols::unknown_class_name();
-    oop filename = StringTable::intern(source, CHECK_0);
+    oop filename = StringTable::intern(source, CHECK);
     java_lang_StackTraceElement::set_fileName(element(), filename);
 
     int line_number = Backtrace::get_line_number(method, bci);
     java_lang_StackTraceElement::set_lineNumber(element(), line_number);
   }
-  return element();
-}
-
-oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) {
-  Handle mirror (THREAD, method->method_holder()->java_mirror());
-  int method_id = method->orig_method_idnum();
-  int cpref = method->name_index();
-  return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
 }
 
 Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
@@ -3629,8 +3628,8 @@
 GrowableArray<Klass*>* java_lang_Class::_fixup_module_field_list = NULL;
 int java_lang_Throwable::backtrace_offset;
 int java_lang_Throwable::detailMessage_offset;
-int java_lang_Throwable::cause_offset;
 int java_lang_Throwable::stackTrace_offset;
+int java_lang_Throwable::depth_offset;
 int java_lang_Throwable::static_unassigned_stacktrace_offset;
 int java_lang_reflect_AccessibleObject::override_offset;
 int java_lang_reflect_Method::clazz_offset;
@@ -3841,7 +3840,6 @@
   // Throwable Class
   java_lang_Throwable::backtrace_offset  = java_lang_Throwable::hc_backtrace_offset  * x + header;
   java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
-  java_lang_Throwable::cause_offset      = java_lang_Throwable::hc_cause_offset      * x + header;
   java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
   java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset *  x;
 
@@ -3894,6 +3892,7 @@
 void JavaClasses::compute_offsets() {
   // java_lang_Class::compute_offsets was called earlier in bootstrap
   java_lang_ClassLoader::compute_offsets();
+  java_lang_Throwable::compute_offsets();
   java_lang_Thread::compute_offsets();
   java_lang_ThreadGroup::compute_offsets();
   java_lang_invoke_MethodHandle::compute_offsets();
@@ -4048,8 +4047,8 @@
 
   CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, backtrace, "Ljava/lang/Object;");
   CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, detailMessage, "Ljava/lang/String;");
-  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, cause, "Ljava/lang/Throwable;");
   CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;");
+  CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, depth, "I");
 
   // Boxed primitive objects (java_lang_boxing_object)
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -155,11 +155,6 @@
   }
 
   static unsigned int hash_code(oop java_string);
-  static unsigned int latin1_hash_code(typeArrayOop value, int len);
-
-  // This is the string hash code used by the StringTable, which may be
-  // the same as String.hashCode or an alternate hash code.
-  static unsigned int hash_string(oop java_string);
 
   static bool equals(oop java_string, jchar* chars, int len);
   static bool equals(oop str1, oop str2);
@@ -456,6 +451,7 @@
 
 class java_lang_Throwable: AllStatic {
   friend class BacktraceBuilder;
+  friend class BacktraceIterator;
 
  private:
   // Offsets
@@ -481,16 +477,12 @@
 
   static int backtrace_offset;
   static int detailMessage_offset;
-  static int cause_offset;
   static int stackTrace_offset;
+  static int depth_offset;
   static int static_unassigned_stacktrace_offset;
 
-  // Printing
-  static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci, int cpref);
   // StackTrace (programmatic access, new since 1.4)
   static void clear_stacktrace(oop throwable);
-  // No stack trace available
-  static const char* no_stack_trace_message();
   // Stacktrace (post JDK 1.7.0 to allow immutability protocol to be followed)
   static void set_stacktrace(oop throwable, oop st_element_array);
   static oop unassigned_stacktrace();
@@ -499,19 +491,20 @@
   // Backtrace
   static oop backtrace(oop throwable);
   static void set_backtrace(oop throwable, oop value);
+  static int depth(oop throwable);
+  static void set_depth(oop throwable, int value);
   // Needed by JVMTI to filter out this internal field.
   static int get_backtrace_offset() { return backtrace_offset;}
   static int get_detailMessage_offset() { return detailMessage_offset;}
   // Message
-  static oop message(oop throwable);
   static oop message(Handle throwable);
   static void set_message(oop throwable, oop value);
   static Symbol* detail_message(oop throwable);
-  static void print_stack_element(outputStream *st, Handle mirror, int method,
-                                  int version, int bci, int cpref);
   static void print_stack_element(outputStream *st, const methodHandle& method, int bci);
   static void print_stack_usage(Handle stream);
 
+  static void compute_offsets();
+
   // Allocate space for backtrace (created but stack trace not filled in)
   static void allocate_backtrace(Handle throwable, TRAPS);
   // Fill in current stack trace for throwable with preallocated backtrace (no GC)
@@ -520,8 +513,7 @@
   static void fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS);
   static void fill_in_stack_trace(Handle throwable, const methodHandle& method = methodHandle());
   // Programmatic access to stack trace
-  static oop  get_stack_trace_element(oop throwable, int index, TRAPS);
-  static int  get_stack_trace_depth(oop throwable, TRAPS);
+  static void get_stack_trace_elements(Handle throwable, objArrayHandle stack_trace, TRAPS);
   // Printing
   static void print(Handle throwable, outputStream* st);
   static void print_stack_trace(Handle throwable, outputStream* st);
@@ -1333,7 +1325,6 @@
   static int fileName_offset;
   static int lineNumber_offset;
 
- public:
   // Setters
   static void set_moduleName(oop element, oop value);
   static void set_moduleVersion(oop element, oop value);
@@ -1342,10 +1333,13 @@
   static void set_fileName(oop element, oop value);
   static void set_lineNumber(oop element, int value);
 
+ public:
   // Create an instance of StackTraceElement
-  static oop create(Handle mirror, int method, int version, int bci, int cpref, TRAPS);
   static oop create(const methodHandle& method, int bci, TRAPS);
 
+  static void fill_in(Handle element, InstanceKlass* holder, const methodHandle& method,
+                      int version, int bci, int cpref, TRAPS);
+
   // Debugging
   friend class JavaClasses;
 };
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -111,13 +111,14 @@
       if (klass != NULL &&
           klass->class_loader_data()->is_unloading()) {
         probe->set_klass(NULL);
-        if (TraceLoaderConstraints) {
+        if (log_is_enabled(Info, constraints)) {
           ResourceMark rm;
-          tty->print_cr("[Purging class object from constraint for name %s,"
+          outputStream* out = Log(classload, constraints)::info_stream();
+          out->print_cr("purging class object from constraint for name %s,"
                      " loader list:",
                      probe->name()->as_C_string());
           for (int i = 0; i < probe->num_loaders(); i++) {
-            tty->print_cr("[   [%d]: %s", i,
+            out->print_cr("    [%d]: %s", i,
                           probe->loader_data(i)->loader_name());
           }
         }
@@ -126,9 +127,10 @@
       int n = 0;
       while (n < probe->num_loaders()) {
         if (probe->loader_data(n)->is_unloading()) {
-            if (TraceLoaderConstraints) {
+            if (log_is_enabled(Info, classload, constraints)) {
               ResourceMark rm;
-              tty->print_cr("[Purging loader %s from constraint for name %s",
+              outputStream* out = Log(classload, constraints)::info_stream();
+              out->print_cr("purging loader %s from constraint for name %s",
                             probe->loader_data(n)->loader_name(),
                             probe->name()->as_C_string()
                             );
@@ -140,11 +142,12 @@
           probe->set_loader_data(n, probe->loader_data(num));
           probe->set_loader_data(num, NULL);
 
-            if (TraceLoaderConstraints) {
+            if (log_is_enabled(Info, classload, constraints)) {
               ResourceMark rm;
-              tty->print_cr("[New loader list:");
+              outputStream* out = Log(classload, constraints)::info_stream();
+              out->print_cr("new loader list:");
               for (int i = 0; i < probe->num_loaders(); i++) {
-                tty->print_cr("[   [%d]: %s", i,
+                out->print_cr("    [%d]: %s", i,
                               probe->loader_data(i)->loader_name());
               }
             }
@@ -156,9 +159,10 @@
       }
       // Check whether entry should be purged
       if (probe->num_loaders() < 2) {
-            if (TraceLoaderConstraints) {
+            if (log_is_enabled(Info, classload, constraints)) {
               ResourceMark rm;
-              tty->print("[Purging complete constraint for name %s\n",
+              outputStream* out = Log(classload, constraints)::info_stream();
+              out->print_cr("purging complete constraint for name %s",
                          probe->name()->as_C_string());
             }
 
@@ -227,10 +231,11 @@
         p->set_klass(klass);
         p->set_next(bucket(index));
         set_entry(index, p);
-        if (TraceLoaderConstraints) {
+        if (log_is_enabled(Info, classload, constraints)) {
           ResourceMark rm;
-          tty->print("[Adding new constraint for name: %s, loader[0]: %s,"
-                     " loader[1]: %s ]\n",
+          outputStream* out = Log(classload, constraints)::info_stream();
+          out->print_cr("adding new constraint for name: %s, loader[0]: %s,"
+                     " loader[1]: %s",
                      class_name->as_C_string(),
                      SystemDictionary::loader_name(class_loader1()),
                      SystemDictionary::loader_name(class_loader2())
@@ -240,10 +245,11 @@
         /* constraint already imposed */
         if ((*pp1)->klass() == NULL) {
           (*pp1)->set_klass(klass);
-          if (TraceLoaderConstraints) {
+          if (log_is_enabled(Info, classload, constraints)) {
             ResourceMark rm;
-            tty->print("[Setting class object in existing constraint for"
-                       " name: %s and loader %s ]\n",
+            outputStream* out = Log(classload, constraints)::info_stream();
+            out->print_cr("setting class object in existing constraint for"
+                       " name: %s and loader %s",
                        class_name->as_C_string(),
                        SystemDictionary::loader_name(class_loader1())
                        );
@@ -261,8 +267,9 @@
     }
   }
 
-  if (failure_code != 0 && TraceLoaderConstraints) {
+  if (failure_code != 0 && log_is_enabled(Info, classload, constraints)) {
     ResourceMark rm;
+    outputStream* out = Log(classload, constraints)::info_stream();
     const char* reason = "";
     switch(failure_code) {
     case 1: reason = "the class objects presented by loader[0] and loader[1]"
@@ -273,8 +280,8 @@
               " the stored class object in the constraint"; break;
     default: reason = "unknown reason code";
     }
-    tty->print("[Failed to add constraint for name: %s, loader[0]: %s,"
-               " loader[1]: %s, Reason: %s ]\n",
+    out->print_cr("failed to add constraint for name: %s, loader[0]: %s,"
+               " loader[1]: %s, Reason: %s",
                class_name->as_C_string(),
                SystemDictionary::loader_name(class_loader1()),
                SystemDictionary::loader_name(class_loader2()),
@@ -293,10 +300,11 @@
                                                    Symbol* name) {
   LoaderConstraintEntry* p = *(find_loader_constraint(name, loader));
   if (p && p->klass() != NULL && p->klass() != k()) {
-    if (TraceLoaderConstraints) {
+    if (log_is_enabled(Info, classload, constraints)) {
       ResourceMark rm;
-      tty->print("[Constraint check failed for name %s, loader %s: "
-                 "the presented class object differs from that stored ]\n",
+      outputStream* out = Log(classload, constraints)::info_stream();
+      out->print_cr("constraint check failed for name %s, loader %s: "
+                 "the presented class object differs from that stored",
                  name->as_C_string(),
                  SystemDictionary::loader_name(loader()));
     }
@@ -304,10 +312,11 @@
   } else {
     if (p && p->klass() == NULL) {
       p->set_klass(k());
-      if (TraceLoaderConstraints) {
+      if (log_is_enabled(Info, classload, constraints)) {
         ResourceMark rm;
-        tty->print("[Updating constraint for name %s, loader %s, "
-                   "by setting class object ]\n",
+        outputStream* out = Log(classload, constraints)::info_stream();
+        out->print_cr("updating constraint for name %s, loader %s, "
+                   "by setting class object",
                    name->as_C_string(),
                    SystemDictionary::loader_name(loader()));
       }
@@ -353,13 +362,14 @@
   int num = p->num_loaders();
   p->set_loader(num, loader());
   p->set_num_loaders(num + 1);
-  if (TraceLoaderConstraints) {
+  if (log_is_enabled(Info, classload, constraints)) {
     ResourceMark rm;
-    tty->print("[Extending constraint for name %s by adding loader[%d]: %s %s",
+    outputStream* out = Log(classload, constraints)::info_stream();
+    out->print_cr("extending constraint for name %s by adding loader[%d]: %s %s",
                p->name()->as_C_string(),
                num,
                SystemDictionary::loader_name(loader()),
-               (p->klass() == NULL ? " and setting class object ]\n" : " ]\n")
+               (p->klass() == NULL ? " and setting class object" : "")
                );
   }
   if (p->klass() == NULL) {
@@ -392,18 +402,19 @@
     p1->set_num_loaders(num + 1);
   }
 
-  if (TraceLoaderConstraints) {
+  if (log_is_enabled(Info, classload, constraints)) {
     ResourceMark rm;
-    tty->print_cr("[Merged constraints for name %s, new loader list:",
+    outputStream* out = Log(classload, constraints)::info_stream();
+    out->print_cr("merged constraints for name %s, new loader list:",
                   p1->name()->as_C_string()
                   );
 
     for (int i = 0; i < p1->num_loaders(); i++) {
-      tty->print_cr("[   [%d]: %s", i,
+      out->print_cr("    [%d]: %s", i,
                     p1->loader_data(i)->loader_name());
     }
     if (p1->klass() == NULL) {
-      tty->print_cr("[... and setting class object]");
+      out->print_cr("... and setting class object");
     }
   }
 
@@ -473,7 +484,6 @@
 // Called with the system dictionary lock held
 void LoaderConstraintTable::print() {
   ResourceMark rm;
-
   assert_locked_or_safepoint(SystemDictionary_lock);
   tty->print_cr("Java loader constraints (entries=%d)", _loader_constraint_size);
   for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
--- a/hotspot/src/share/vm/classfile/modules.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/modules.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -36,6 +36,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
@@ -480,7 +481,7 @@
   }
 
   if (log_is_enabled(Debug, modules)) {
-    outputStream* logst = LogHandle(modules)::debug_stream();
+    outputStream* logst = Log(modules)::debug_stream();
     logst->print("define_module(): creation of module: %s, version: %s, location: %s, ",
                  module_name, module_version != NULL ? module_version : "NULL",
                  module_location != NULL ? module_location : "NULL");
@@ -789,7 +790,7 @@
 
   if (log_is_enabled(Debug, modules)) {
     ResourceMark rm(THREAD);
-    outputStream* logst = LogHandle(modules)::debug_stream();
+    outputStream* logst = Log(modules)::debug_stream();
     Klass* klass = java_lang_Class::as_Klass(mirror);
     oop module_name = java_lang_reflect_Module::name(module);
     if (module_name != NULL) {
--- a/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -29,6 +29,7 @@
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/metaspaceShared.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/arguments.hpp"
 #include "utilities/ostream.hpp"
 
@@ -74,7 +75,7 @@
 
 void SharedPathsMiscInfo::print_path(int type, const char* path) {
   ResourceMark rm;
-  outputStream* out = LogHandle(classpath)::info_stream();
+  outputStream* out = Log(classpath)::info_stream();
   switch (type) {
   case BOOT:
     out->print("Expecting BOOT path=%s", path);
--- a/hotspot/src/share/vm/classfile/stringTable.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,6 +32,7 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -94,15 +95,27 @@
 CompactHashtable<oop, char> StringTable::_shared_table;
 
 // Pick hashing algorithm
-template<typename T>
-unsigned int StringTable::hash_string(const T* s, int len) {
+unsigned int StringTable::hash_string(const jchar* s, int len) {
   return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
                                     java_lang_String::hash_code(s, len);
 }
 
-// Explicit instantiation for all supported types.
-template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
-template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
+unsigned int StringTable::hash_string(oop string) {
+  EXCEPTION_MARK;
+  if (string == NULL) {
+    return hash_string((jchar*)NULL, 0);
+  }
+  ResourceMark rm(THREAD);
+  // All String oops are hashed as unicode
+  int length;
+  jchar* chars = java_lang_String::as_unicode_string(string, length, THREAD);
+  if (chars != NULL) {
+    return hash_string(chars, length);
+  } else {
+    vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
+    return 0;
+  }
+}
 
 oop StringTable::lookup_shared(jchar* name, int len) {
   // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
@@ -398,7 +411,7 @@
     for ( ; p != NULL; p = p->next()) {
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
-      unsigned int h = java_lang_String::hash_string(s);
+      unsigned int h = hash_string(s);
       guarantee(p->hash() == h, "broken hash in string table entry");
       guarantee(the_table()->hash_to_index(h) == i,
                 "wrong index in string table");
@@ -498,7 +511,7 @@
     return _verify_fail_done;
   }
 
-  unsigned int h = java_lang_String::hash_string(str);
+  unsigned int h = hash_string(str);
   if (e_ptr->hash() != h) {
     if (mesg_mode == _verify_with_mesgs) {
       tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "
--- a/hotspot/src/share/vm/classfile/stringTable.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/stringTable.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -111,7 +111,8 @@
   // Hashing algorithm, used as the hash value used by the
   //     StringTable for bucket selection and comparison (stored in the
   //     HashtableEntry structures).  This is used in the String.intern() method.
-  template<typename T> static unsigned int hash_string(const T* s, int len);
+  static unsigned int hash_string(const jchar* s, int len);
+  static unsigned int hash_string(oop string);
 
   // Internal test.
   static void test_alt_hash() PRODUCT_RETURN;
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,6 +32,7 @@
 #include "gc/shared/gcLocker.inline.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -160,6 +161,11 @@
 // Create a new table and using alternate hash code, populate the new table
 // with the existing strings.   Set flag to use the alternate hash code afterwards.
 void SymbolTable::rehash_table() {
+  if (DumpSharedSpaces) {
+    tty->print_cr("Warning: rehash_table should not be called while dumping archive");
+    return;
+  }
+
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   // This should never happen with -Xshare:dump but it might in testing mode.
   if (DumpSharedSpaces) return;
@@ -201,6 +207,11 @@
 
 Symbol* SymbolTable::lookup_shared(const char* name,
                                    int len, unsigned int hash) {
+  if (use_alternate_hashcode()) {
+    // hash_code parameter may use alternate hashing algorithm but the shared table
+    // always uses the same original hash code.
+    hash = hash_shared_symbol(name, len);
+  }
   return _shared_table.lookup(name, hash, len);
 }
 
@@ -234,6 +245,10 @@
            java_lang_String::hash_code((const jbyte*)s, len);
 }
 
+unsigned int SymbolTable::hash_shared_symbol(const char* s, int len) {
+  return java_lang_String::hash_code((const jbyte*)s, len);
+}
+
 
 // We take care not to be blocking while holding the
 // SymbolTable_lock. Otherwise, the system might deadlock, since the
@@ -536,7 +551,7 @@
     HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
     for ( ; p != NULL; p = p->next()) {
       Symbol* s = (Symbol*)(p->literal());
-      unsigned int fixed_hash = hash_symbol((char*)s->bytes(), s->utf8_length());
+      unsigned int fixed_hash =  hash_shared_symbol((char*)s->bytes(), s->utf8_length());
       assert(fixed_hash == p->hash(), "must not rehash during dumping");
       ch_table.add(fixed_hash, s);
     }
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -175,6 +175,7 @@
   }
 
   static unsigned int hash_symbol(const char* s, int len);
+  static unsigned int hash_shared_symbol(const char* s, int len);
 
   static Symbol* lookup(const char* name, int len, TRAPS);
   // lookup only, won't add. Also calculate hash.
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -45,6 +45,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/filemap.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/klass.inline.hpp"
@@ -67,6 +68,7 @@
 #include "runtime/signature.hpp"
 #include "services/classLoadingService.hpp"
 #include "services/threadService.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ticks.hpp"
 #if INCLUDE_CDS
@@ -435,7 +437,7 @@
   if (log_is_enabled(Debug, protectiondomain)) {
     ResourceMark rm;
     // Print out trace information
-    outputStream* log = LogHandle(protectiondomain)::debug_stream();
+    outputStream* log = Log(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);
@@ -1650,6 +1652,8 @@
 
   }
 
+  TRACE_KLASS_DEFINITION(k, THREAD);
+
 }
 
 // Support parallel classloading
--- a/hotspot/src/share/vm/classfile/verificationType.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -61,7 +61,7 @@
     Klass* obj = SystemDictionary::resolve_or_fail(
         name(), Handle(THREAD, klass->class_loader()),
         Handle(THREAD, klass->protection_domain()), true, CHECK_false);
-    if (log_is_enabled(Info, classresolve)) {
+    if (log_is_enabled(Debug, classresolve)) {
       Verifier::trace_class_resolution(obj, klass());
     }
 
@@ -80,7 +80,7 @@
       Klass* from_class = SystemDictionary::resolve_or_fail(
           from.name(), Handle(THREAD, klass->class_loader()),
           Handle(THREAD, klass->protection_domain()), true, CHECK_false);
-      if (log_is_enabled(Info, classresolve)) {
+      if (log_is_enabled(Debug, classresolve)) {
         Verifier::trace_class_resolution(from_class, klass());
       }
       return InstanceKlass::cast(from_class)->is_subclass_of(this_class());
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -33,6 +33,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "interpreter/bytecodeStream.hpp"
+#include "logging/log.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
@@ -106,9 +107,9 @@
   const char* resolve = resolve_class->external_name();
   // print in a single call to reduce interleaving between threads
   if (source_file != NULL) {
-    log_info(classresolve)("%s %s %s (verification)", verify, resolve, source_file);
+    log_debug(classresolve)("%s %s %s (verification)", verify, resolve, source_file);
   } else {
-    log_info(classresolve)("%s %s (verification)", verify, resolve);
+    log_debug(classresolve)("%s %s (verification)", verify, resolve);
   }
 }
 
@@ -176,9 +177,7 @@
     if (can_failover && !HAS_PENDING_EXCEPTION &&
         (exception_name == vmSymbols::java_lang_VerifyError() ||
          exception_name == vmSymbols::java_lang_ClassFormatError())) {
-      if (VerboseVerification) {
-        tty->print_cr("Fail over class verification to old verifier for: %s", klassName);
-      }
+      log_info(verification)("Fail over class verification to old verifier for: %s", klassName);
       log_info(classinit)("Fail over class verification to old verifier for: %s", klassName);
       exception_name = inference_verify(
         klass, message_buffer, message_buffer_len, THREAD);
@@ -192,10 +191,10 @@
   }
 
   if (log_is_enabled(Info, classinit)){
-    log_end_verification(LogHandle(classinit)::info_stream(), klassName, exception_name, THREAD);
+    log_end_verification(Log(classinit)::info_stream(), klassName, exception_name, THREAD);
   }
-  if (VerboseVerification){
-    log_end_verification(tty, klassName, exception_name, THREAD);
+  if (log_is_enabled(Info, verification)){
+    log_end_verification(Log(verification)::info_stream(), klassName, exception_name, THREAD);
   }
 
   if (HAS_PENDING_EXCEPTION) {
@@ -206,7 +205,7 @@
     ResourceMark rm(THREAD);
     instanceKlassHandle kls =
       SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false);
-    if (log_is_enabled(Info, classresolve)) {
+    if (log_is_enabled(Debug, classresolve)) {
       Verifier::trace_class_resolution(kls(), klass());
     }
 
@@ -269,9 +268,7 @@
   }
 
   ResourceMark rm(THREAD);
-  if (VerboseVerification) {
-    tty->print_cr("Verifying class %s with old format", klass->external_name());
-  }
+  log_info(verification)("Verifying class %s with old format", klass->external_name());
 
   jclass cls = (jclass) JNIHandles::make_local(env, klass->java_mirror());
   jint result;
@@ -583,10 +580,7 @@
 }
 
 void ClassVerifier::verify_class(TRAPS) {
-  if (VerboseVerification) {
-    tty->print_cr("Verifying class %s with new format",
-      _klass->external_name());
-  }
+  log_info(verification)("Verifying class %s with new format", _klass->external_name());
 
   Array<Method*>* methods = _klass->methods();
   int num_methods = methods->length();
@@ -606,10 +600,7 @@
   }
 
   if (was_recursively_verified()){
-    if (VerboseVerification){
-      tty->print_cr("Recursive verification detected for: %s",
-                    _klass->external_name());
-    }
+    log_info(verification)("Recursive verification detected for: %s", _klass->external_name());
     log_info(classinit)("Recursive verification detected for: %s",
                         _klass->external_name());
   }
@@ -618,9 +609,7 @@
 void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
   HandleMark hm(THREAD);
   _method = m;   // initialize _method
-  if (VerboseVerification) {
-    tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string());
-  }
+  log_info(verification)("Verifying method %s", m->name_and_sig_as_C_string());
 
 // For clang, the only good constant format string is a literal constant format string.
 #define bad_type_msg "Bad type on operand stack in %s"
@@ -667,8 +656,9 @@
   StackMapTable stackmap_table(&reader, &current_frame, max_locals, max_stack,
                                code_data, code_length, CHECK_VERIFY(this));
 
-  if (VerboseVerification) {
-    stackmap_table.print_on(tty);
+  if (log_is_enabled(Info, verification)) {
+    ResourceMark rm(THREAD);
+    stackmap_table.print_on(Log(verification)::info_stream());
   }
 
   RawBytecodeStream bcs(m);
@@ -708,12 +698,11 @@
       VerificationType type, type2;
       VerificationType atype;
 
-#ifndef PRODUCT
-      if (VerboseVerification) {
-        current_frame.print_on(tty);
-        tty->print_cr("offset = %d,  opcode = %s", bci, Bytecodes::name(opcode));
+      if (log_is_enabled(Info, verification)) {
+        ResourceMark rm(THREAD);
+        current_frame.print_on(Log(verification)::info_stream());
+        log_info(verification)("offset = %d,  opcode = %s", bci, Bytecodes::name(opcode));
       }
-#endif
 
       // Make sure wide instruction is in correct format
       if (bcs.is_wide()) {
@@ -2005,7 +1994,7 @@
     name, Handle(THREAD, loader), Handle(THREAD, protection_domain),
     true, THREAD);
 
-  if (log_is_enabled(Info, classresolve)) {
+  if (log_is_enabled(Debug, classresolve)) {
     instanceKlassHandle cur_class = current_class();
     Verifier::trace_class_resolution(kls, cur_class());
   }
@@ -2533,11 +2522,10 @@
             verify_error(ErrorContext::bad_code(bci),
               "Bad <init> method call from after the start of a try block");
             return;
-          } else if (VerboseVerification) {
-            ResourceMark rm;
-            tty->print_cr(
-              "Survived call to ends_in_athrow(): %s",
-              current_class()->name()->as_C_string());
+          } else if (log_is_enabled(Info, verification)) {
+            ResourceMark rm(THREAD);
+            log_info(verification)("Survived call to ends_in_athrow(): %s",
+                                          current_class()->name()->as_C_string());
           }
         }
       }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -102,7 +102,6 @@
   template(java_security_SecureClassLoader,           "java/security/SecureClassLoader")          \
   template(java_net_URL,                              "java/net/URL")                             \
   template(java_util_jar_Manifest,                    "java/util/jar/Manifest")                   \
-  template(impliesCreateAccessControlContext_name,    "impliesCreateAccessControlContext")        \
   template(java_io_OutputStream,                      "java/io/OutputStream")                     \
   template(java_io_Reader,                            "java/io/Reader")                           \
   template(java_io_BufferedReader,                    "java/io/BufferedReader")                   \
@@ -327,7 +326,6 @@
   template(java_lang_StackFrameInfo,                  "java/lang/StackFrameInfo")                 \
   template(java_lang_LiveStackFrameInfo,              "java/lang/LiveStackFrameInfo")             \
   template(java_lang_StackStreamFactory_AbstractStackWalker, "java/lang/StackStreamFactory$AbstractStackWalker") \
-  template(doStackWalk_name,                          "doStackWalk")                              \
   template(doStackWalk_signature,                     "(JIIII)Ljava/lang/Object;")                \
   template(asPrimitive_name,                          "asPrimitive")                              \
   template(asPrimitive_int_signature,                 "(I)Ljava/lang/LiveStackFrame$PrimitiveValue;") \
@@ -378,14 +376,13 @@
   template(type_name,                                 "type")                                     \
   template(findNative_name,                           "findNative")                               \
   template(deadChild_name,                            "deadChild")                                \
-  template(addClass_name,                             "addClass")                                 \
-  template(throwIllegalAccessError_name,              "throwIllegalAccessError")                  \
   template(getFromClass_name,                         "getFromClass")                             \
   template(dispatch_name,                             "dispatch")                                 \
   template(getSystemClassLoader_name,                 "getSystemClassLoader")                     \
   template(fillInStackTrace_name,                     "fillInStackTrace")                         \
   template(getCause_name,                             "getCause")                                 \
   template(initCause_name,                            "initCause")                                \
+  template(depth_name,                                "depth")                                    \
   template(setProperty_name,                          "setProperty")                              \
   template(getProperty_name,                          "getProperty")                              \
   template(context_name,                              "context")                                  \
@@ -473,10 +470,6 @@
   template(url_code_signer_array_void_signature,      "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
   template(module_entry_name,                         "module_entry")                             \
                                                                                                   \
-  /* non-intrinsic name/signature pairs: */                                                       \
-  template(register_method_name,                      "register")                                 \
-  do_alias(register_method_signature,         object_void_signature)                              \
-                                                                                                  \
   /* name symbols needed by intrinsics */                                                         \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
                                                                                                   \
--- a/hotspot/src/share/vm/code/codeBlob.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -31,6 +31,7 @@
 #include "interpreter/bytecode.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/heap.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"
 #include "runtime/handles.inline.hpp"
--- a/hotspot/src/share/vm/code/compiledIC.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/code/compiledIC.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -33,6 +33,7 @@
 #include "interpreter/linkResolver.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
--- a/hotspot/src/share/vm/code/dependencies.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -30,6 +30,7 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "code/dependencies.hpp"
 #include "compiler/compileLog.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "runtime/handles.hpp"
--- a/hotspot/src/share/vm/code/nmethod.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -36,6 +36,7 @@
 #include "compiler/directivesParser.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/bytecode.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/methodData.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
@@ -1321,7 +1322,7 @@
 
   // Break cycle between nmethod & method
   if (log_is_enabled(Trace, classunload)) {
-    outputStream* log = LogHandle(classunload)::trace_stream();
+    outputStream* log = Log(classunload)::trace_stream();
     log->print_cr("making nmethod " INTPTR_FORMAT
                   " unloadable, Method*(" INTPTR_FORMAT
                   "), cause(" INTPTR_FORMAT ")",
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -32,8 +32,10 @@
 #include "compiler/compileLog.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "compiler/directivesParser.hpp"
+#include "gc/shared/referencePendingListLocker.hpp"
 #include "interpreter/linkResolver.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
@@ -48,6 +50,7 @@
 #include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/sweeper.hpp"
+#include "runtime/timerTrace.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
@@ -901,7 +904,7 @@
   // the pending list lock or a 3-way deadlock may occur
   // between the reference handler thread, a GC (instigated
   // by a compiler thread), and compiled method registration.
-  if (InstanceRefKlass::owns_pending_list_lock(JavaThread::current())) {
+  if (ReferencePendingListLocker::is_locked_by_self()) {
     return;
   }
 
--- a/hotspot/src/share/vm/compiler/compileTask.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -27,6 +27,7 @@
 #include "compiler/compileLog.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerDirectives.hpp"
+#include "memory/resourceArea.hpp"
 
 CompileTask*  CompileTask::_task_free_list = NULL;
 #ifdef ASSERT
--- a/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -28,6 +28,7 @@
 #include "compiler/abstractCompiler.hpp"
 #include "compiler/compilerDirectives.hpp"
 #include "compiler/compilerOracle.hpp"
+#include "memory/resourceArea.hpp"
 
 CompilerDirectives::CompilerDirectives() :_match(NULL), _next(NULL), _ref_count(0) {
   _c1_store = new DirectiveSet(this);
--- a/hotspot/src/share/vm/compiler/directivesParser.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/directivesParser.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -26,6 +26,7 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/directivesParser.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/os.hpp"
 #include <string.h>
 
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,6 +28,7 @@
 #include "compiler/disassembler.hpp"
 #include "gc/shared/cardTableModRefBS.hpp"
 #include "gc/shared/collectedHeap.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fprofiler.hpp"
 #include "runtime/handles.inline.hpp"
--- a/hotspot/src/share/vm/compiler/methodLiveness.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/methodLiveness.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -30,6 +30,8 @@
 #include "interpreter/bytecode.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/timerTrace.hpp"
 #include "utilities/bitMap.inline.hpp"
 
 // The MethodLiveness class performs a simple liveness analysis on a method
--- a/hotspot/src/share/vm/compiler/methodMatcher.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/compiler/methodMatcher.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "compiler/methodMatcher.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 
 // The JVM specification defines the allowed characters.
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -30,7 +30,6 @@
 #include "gc/shared/blockOffsetTable.inline.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/liveRange.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "gc/shared/spaceDecorator.hpp"
 #include "memory/allocation.inline.hpp"
@@ -501,7 +500,7 @@
 
 void CompactibleFreeListSpace::reportFreeListStatistics(const char* title) const {
   assert_lock_strong(&_freelistLock);
-  LogHandle(gc, freelist, stats) log;
+  Log(gc, freelist, stats) log;
   if (!log.is_debug()) {
     return;
   }
@@ -1931,11 +1930,6 @@
   if (blk->_ptr == NULL) {
     refillLinearAllocBlock(blk);
   }
-  if (PrintMiscellaneous && Verbose) {
-    if (blk->_word_size == 0) {
-      warning("CompactibleFreeListSpace(prologue):: Linear allocation failure");
-    }
-  }
 }
 
 void
@@ -2205,7 +2199,7 @@
       }
     }
     if (res == 0) {
-      LogHandle(gc, verify) log;
+      Log(gc, verify) log;
       log.error("Livelock: no rank reduction!");
       log.error(" Current:  addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n"
                 " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n",
@@ -2379,14 +2373,14 @@
 
 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
   assert_lock_strong(&_freelistLock);
-  LogHandle(gc, freelist, census) log;
-  if (!log.is_debug()) {
+  LogTarget(Debug, gc, freelist, census) log;
+  if (!log.is_enabled()) {
     return;
   }
   AdaptiveFreeList<FreeChunk> total;
-  log.debug("end sweep# " SIZE_FORMAT, sweep_count);
+  log.print("end sweep# " SIZE_FORMAT, sweep_count);
   ResourceMark rm;
-  outputStream* out = log.debug_stream();
+  outputStream* out = log.stream();
   AdaptiveFreeList<FreeChunk>::print_labels_on(out, "size");
   size_t total_free = 0;
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
@@ -2408,8 +2402,8 @@
     total.set_split_deaths(total.split_deaths() + fl->split_deaths());
   }
   total.print_on(out, "TOTAL");
-  log.debug("Total free in indexed lists " SIZE_FORMAT " words", total_free);
-  log.debug("growth: %8.5f  deficit: %8.5f",
+  log.print("Total free in indexed lists " SIZE_FORMAT " words", total_free);
+  log.print("growth: %8.5f  deficit: %8.5f",
             (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/
                     (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0),
             (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
@@ -2541,7 +2535,7 @@
         _blocks_to_claim[i].sample(
           MAX2(CMSOldPLABMin,
           MIN2(CMSOldPLABMax,
-               _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
+               _global_num_blocks[i]/_global_num_workers[i]/CMSOldPLABNumRefills)));
       }
       // Reset counters for next round
       _global_num_workers[i] = 0;
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -502,7 +502,7 @@
   {
     MutexLockerEx x(_markBitMap.lock(), Mutex::_no_safepoint_check_flag);
     if (!_markBitMap.allocate(_span)) {
-      warning("Failed to allocate CMS Bit Map");
+      log_warning(gc)("Failed to allocate CMS Bit Map");
       return;
     }
     assert(_markBitMap.covers(_span), "_markBitMap inconsistency?");
@@ -513,7 +513,7 @@
   }
 
   if (!_markStack.allocate(MarkStackSize)) {
-    warning("Failed to allocate CMS Marking Stack");
+    log_warning(gc)("Failed to allocate CMS Marking Stack");
     return;
   }
 
@@ -527,8 +527,7 @@
       _conc_workers = new YieldingFlexibleWorkGang("CMS Thread",
                                  ConcGCThreads, true);
       if (_conc_workers == NULL) {
-        warning("GC/CMS: _conc_workers allocation failure: "
-              "forcing -CMSConcurrentMTEnabled");
+        log_warning(gc)("GC/CMS: _conc_workers allocation failure: forcing -CMSConcurrentMTEnabled");
         CMSConcurrentMTEnabled = false;
       } else {
         _conc_workers->initialize_workers();
@@ -559,7 +558,7 @@
         && num_queues > 0) {
       _task_queues = new OopTaskQueueSet(num_queues);
       if (_task_queues == NULL) {
-        warning("task_queues allocation failure.");
+        log_warning(gc)("task_queues allocation failure.");
         return;
       }
       _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues, mtGC);
@@ -567,7 +566,7 @@
       for (i = 0; i < num_queues; i++) {
         PaddedOopTaskQueue *q = new PaddedOopTaskQueue();
         if (q == NULL) {
-          warning("work_queue allocation failure.");
+          log_warning(gc)("work_queue allocation failure.");
           return;
         }
         _task_queues->register_queue(i, q);
@@ -694,7 +693,7 @@
 // At a promotion failure dump information on block layout in heap
 // (cms old generation).
 void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
-  LogHandle(gc, promotion) log;
+  Log(gc, promotion) log;
   if (log.is_trace()) {
     ResourceMark rm;
     cmsSpace()->dump_at_safepoint_with_locks(collector(), log.trace_stream());
@@ -753,7 +752,7 @@
     size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
     assert(desired_capacity >= capacity(), "invalid expansion size");
     size_t expand_bytes = MAX2(desired_capacity - capacity(), MinHeapDeltaBytes);
-    LogHandle(gc) log;
+    Log(gc) log;
     if (log.is_trace()) {
       size_t desired_capacity = (size_t)(used() / ((double) 1 - desired_free_percentage));
       log.trace("From compute_new_size: ");
@@ -1118,7 +1117,7 @@
   // ------------------------------------------------------------------
   // Print out lots of information which affects the initiation of
   // a collection.
-  LogHandle(gc) log;
+  Log(gc) log;
   if (log.is_trace() && stats().valid()) {
     log.trace("CMSCollector shouldConcurrentCollect: ");
     ResourceMark rm;
@@ -1413,7 +1412,7 @@
     if (_foregroundGCShouldWait) {
       // We are going to be waiting for action for the CMS thread;
       // it had better not be gone (for instance at shutdown)!
-      assert(ConcurrentMarkSweepThread::cmst() != NULL,
+      assert(ConcurrentMarkSweepThread::cmst() != NULL && !ConcurrentMarkSweepThread::cmst()->has_terminated(),
              "CMS thread must be running");
       // Wait here until the background collector gives us the go-ahead
       ConcurrentMarkSweepThread::clear_CMS_flag(
@@ -1519,7 +1518,7 @@
 
   gch->pre_full_gc_dump(gc_timer);
 
-  GCTraceTime(Trace, gc) t("CMS:MSC");
+  GCTraceTime(Trace, gc, phases) t("CMS:MSC");
 
   // Temporarily widen the span of the weak reference processing to
   // the entire heap.
@@ -1606,7 +1605,7 @@
 }
 
 void CMSCollector::print_eden_and_survivor_chunk_arrays() {
-  LogHandle(gc, heap) log;
+  Log(gc, heap) log;
   if (!log.is_trace()) {
     return;
   }
@@ -2222,7 +2221,7 @@
   bool do_bit(size_t offset) {
     HeapWord* addr = _marks->offsetToHeapWord(offset);
     if (!_marks->isMarked(addr)) {
-      LogHandle(gc, verify) log;
+      Log(gc, verify) log;
       ResourceMark rm;
       oop(addr)->print_on(log.error_stream());
       log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
@@ -2235,7 +2234,7 @@
 };
 
 bool CMSCollector::verify_after_remark() {
-  GCTraceTime(Info, gc, verify) tm("Verifying CMS Marking.");
+  GCTraceTime(Info, gc, phases, verify) tm("Verifying CMS Marking.");
   MutexLockerEx ml(verification_mark_bm()->lock(), Mutex::_no_safepoint_check_flag);
   static bool init = false;
 
@@ -2287,17 +2286,16 @@
     // all marking, then check if the new marks-vector is
     // a subset of the CMS marks-vector.
     verify_after_remark_work_1();
-  } else if (CMSRemarkVerifyVariant == 2) {
+  } else {
+    guarantee(CMSRemarkVerifyVariant == 2, "Range checking for CMSRemarkVerifyVariant should guarantee 1 or 2");
     // In this second variant of verification, we flag an error
     // (i.e. an object reachable in the new marks-vector not reachable
     // in the CMS marks-vector) immediately, also indicating the
     // identify of an object (A) that references the unmarked object (B) --
     // presumably, a mutation to A failed to be picked up by preclean/remark?
     verify_after_remark_work_2();
-  } else {
-    warning("Unrecognized value " UINTX_FORMAT " for CMSRemarkVerifyVariant",
-            CMSRemarkVerifyVariant);
-  }
+  }
+
   return true;
 }
 
@@ -2349,7 +2347,7 @@
   VerifyMarkedClosure vcl(markBitMap());
   verification_mark_bm()->iterate(&vcl);
   if (vcl.failed()) {
-    LogHandle(gc, verify) log;
+    Log(gc, verify) log;
     log.error("Failed marking verification after remark");
     ResourceMark rm;
     gch->print_on(log.error_stream());
@@ -2820,7 +2818,7 @@
   // CMS collection cycle.
   setup_cms_unloading_and_verification_state();
 
-  GCTraceTime(Trace, gc) ts("checkpointRootsInitialWork", _gc_timer_cm);
+  GCTraceTime(Trace, gc, phases) ts("checkpointRootsInitialWork", _gc_timer_cm);
 
   // Reset all the PLAB chunk arrays if necessary.
   if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
@@ -3650,7 +3648,7 @@
     // XXX FIX ME!!! YSR
     size_t loops = 0, workdone = 0, cumworkdone = 0, waited = 0;
     while (!(should_abort_preclean() ||
-             ConcurrentMarkSweepThread::should_terminate())) {
+             ConcurrentMarkSweepThread::cmst()->should_terminate())) {
       workdone = preclean_work(CMSPrecleanRefLists2, CMSPrecleanSurvivors2);
       cumworkdone += workdone;
       loops++;
@@ -4104,8 +4102,6 @@
       // expect it to be false and set to true
       FlagSetting fl(gch->_is_gc_active, false);
 
-      GCTraceTime(Trace, gc) tm("Pause Scavenge Before Remark", _gc_timer_cm);
-
       gch->do_collection(true,                      // full (i.e. force, see below)
                          false,                     // !clear_all_soft_refs
                          0,                         // size
@@ -4123,7 +4119,7 @@
 }
 
 void CMSCollector::checkpointRootsFinalWork() {
-  GCTraceTime(Trace, gc) tm("checkpointRootsFinalWork", _gc_timer_cm);
+  GCTraceTime(Trace, gc, phases) tm("checkpointRootsFinalWork", _gc_timer_cm);
 
   assert(haveFreelistLocks(), "must have free list locks");
   assert_lock_strong(bitMapLock());
@@ -4173,10 +4169,10 @@
     // the most recent young generation GC, minus those cleaned up by the
     // concurrent precleaning.
     if (CMSParallelRemarkEnabled) {
-      GCTraceTime(Debug, gc) t("Rescan (parallel)", _gc_timer_cm);
+      GCTraceTime(Debug, gc, phases) t("Rescan (parallel)", _gc_timer_cm);
       do_remark_parallel();
     } else {
-      GCTraceTime(Debug, gc) t("Rescan (non-parallel)", _gc_timer_cm);
+      GCTraceTime(Debug, gc, phases) t("Rescan (non-parallel)", _gc_timer_cm);
       do_remark_non_parallel();
     }
   }
@@ -4184,7 +4180,7 @@
   verify_overflow_empty();
 
   {
-    GCTraceTime(Trace, gc) ts("refProcessingWork", _gc_timer_cm);
+    GCTraceTime(Trace, gc, phases) ts("refProcessingWork", _gc_timer_cm);
     refProcessingWork();
   }
   verify_work_stacks_empty();
@@ -4907,7 +4903,7 @@
                               NULL,  // space is set further below
                               &_markBitMap, &_markStack, &mrias_cl);
   {
-    GCTraceTime(Trace, gc) t("Grey Object Rescan", _gc_timer_cm);
+    GCTraceTime(Trace, gc, phases) t("Grey Object Rescan", _gc_timer_cm);
     // Iterate over the dirty cards, setting the corresponding bits in the
     // mod union table.
     {
@@ -4941,7 +4937,7 @@
     Universe::verify();
   }
   {
-    GCTraceTime(Trace, gc) t("Root Rescan", _gc_timer_cm);
+    GCTraceTime(Trace, gc, phases) t("Root Rescan", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -4963,7 +4959,7 @@
   }
 
   {
-    GCTraceTime(Trace, gc) t("Visit Unhandled CLDs", _gc_timer_cm);
+    GCTraceTime(Trace, gc, phases) t("Visit Unhandled CLDs", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -4982,7 +4978,7 @@
   }
 
   {
-    GCTraceTime(Trace, gc) t("Dirty Klass Scan", _gc_timer_cm);
+    GCTraceTime(Trace, gc, phases) t("Dirty Klass Scan", _gc_timer_cm);
 
     verify_work_stacks_empty();
 
@@ -5186,7 +5182,7 @@
                                 _span, &_markBitMap, &_markStack,
                                 &cmsKeepAliveClosure, false /* !preclean */);
   {
-    GCTraceTime(Debug, gc) t("Weak Refs Processing", _gc_timer_cm);
+    GCTraceTime(Debug, gc, phases) t("Reference Processing", _gc_timer_cm);
 
     ReferenceProcessorStats stats;
     if (rp->processing_is_mt()) {
@@ -5228,7 +5224,7 @@
 
   if (should_unload_classes()) {
     {
-      GCTraceTime(Debug, gc) t("Class Unloading", _gc_timer_cm);
+      GCTraceTime(Debug, gc, phases) t("Class Unloading", _gc_timer_cm);
 
       // Unload classes and purge the SystemDictionary.
       bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
@@ -5241,13 +5237,13 @@
     }
 
     {
-      GCTraceTime(Debug, gc) t("Scrub Symbol Table", _gc_timer_cm);
+      GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer_cm);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
 
     {
-      GCTraceTime(Debug, gc) t("Scrub String Table", _gc_timer_cm);
+      GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer_cm);
       // Delete entries for dead interned strings.
       StringTable::unlink(&_is_alive_closure);
     }
@@ -5657,13 +5653,13 @@
   ReservedSpace brs(ReservedSpace::allocation_align_size_up(
                      (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
   if (!brs.is_reserved()) {
-    warning("CMS bit map allocation failure");
+    log_warning(gc)("CMS bit map allocation failure");
     return false;
   }
   // For now we'll just commit all of the bit map up front.
   // Later on we'll try to be more parsimonious with swap.
   if (!_virtual_space.initialize(brs, brs.size())) {
-    warning("CMS bit map backing store failure");
+    log_warning(gc)("CMS bit map backing store failure");
     return false;
   }
   assert(_virtual_space.committed_size() == brs.size(),
@@ -5749,11 +5745,11 @@
   ReservedSpace rs(ReservedSpace::allocation_align_size_up(
                    size * sizeof(oop)));
   if (!rs.is_reserved()) {
-    warning("CMSMarkStack allocation failure");
+    log_warning(gc)("CMSMarkStack allocation failure");
     return false;
   }
   if (!_virtual_space.initialize(rs, rs.size())) {
-    warning("CMSMarkStack backing store failure");
+    log_warning(gc)("CMSMarkStack backing store failure");
     return false;
   }
   assert(_virtual_space.committed_size() == rs.size(),
@@ -5878,7 +5874,7 @@
   if (_span.contains(addr)) {
     _verification_bm->mark(addr);
     if (!_cms_bm->isMarked(addr)) {
-      LogHandle(gc, verify) log;
+      Log(gc, verify) log;
       ResourceMark rm;
       oop(addr)->print_on(log.error_stream());
       log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
@@ -6659,7 +6655,7 @@
     // Oop lies in _span and isn't yet grey or black
     _verification_bm->mark(addr);            // now grey
     if (!_cms_bm->isMarked(addr)) {
-      LogHandle(gc, verify) log;
+      Log(gc, verify) log;
       ResourceMark rm;
       oop(addr)->print_on(log.error_stream());
       log.error(" (" INTPTR_FORMAT " should have been marked)", p2i(addr));
@@ -7047,13 +7043,13 @@
 }
 
 void SweepClosure::print_on(outputStream* st) const {
-  tty->print_cr("_sp = [" PTR_FORMAT "," PTR_FORMAT ")",
-                p2i(_sp->bottom()), p2i(_sp->end()));
-  tty->print_cr("_limit = " PTR_FORMAT, p2i(_limit));
-  tty->print_cr("_freeFinger = " PTR_FORMAT, p2i(_freeFinger));
-  NOT_PRODUCT(tty->print_cr("_last_fc = " PTR_FORMAT, p2i(_last_fc));)
-  tty->print_cr("_inFreeRange = %d, _freeRangeInFreeLists = %d, _lastFreeRangeCoalesced = %d",
-                _inFreeRange, _freeRangeInFreeLists, _lastFreeRangeCoalesced);
+  st->print_cr("_sp = [" PTR_FORMAT "," PTR_FORMAT ")",
+               p2i(_sp->bottom()), p2i(_sp->end()));
+  st->print_cr("_limit = " PTR_FORMAT, p2i(_limit));
+  st->print_cr("_freeFinger = " PTR_FORMAT, p2i(_freeFinger));
+  NOT_PRODUCT(st->print_cr("_last_fc = " PTR_FORMAT, p2i(_last_fc));)
+  st->print_cr("_inFreeRange = %d, _freeRangeInFreeLists = %d, _lastFreeRangeCoalesced = %d",
+               _inFreeRange, _freeRangeInFreeLists, _lastFreeRangeCoalesced);
 }
 
 #ifndef PRODUCT
@@ -7066,8 +7062,10 @@
   assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
          "sweep _limit out of bounds");
   if (inFreeRange()) {
-    warning("inFreeRange() should have been reset; dumping state of SweepClosure");
-    print();
+    Log(gc, sweep) log;
+    log.error("inFreeRange() should have been reset; dumping state of SweepClosure");
+    ResourceMark rm;
+    print_on(log.error_stream());
     ShouldNotReachHere();
   }
 
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -28,7 +28,7 @@
 #include "gc/cms/concurrentMarkSweepThread.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
-#include "oops/instanceRefKlass.hpp"
+#include "gc/shared/referencePendingListLocker.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -42,16 +42,10 @@
 
 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::_cmst = NULL;
 CMSCollector* ConcurrentMarkSweepThread::_collector         = NULL;
-bool ConcurrentMarkSweepThread::_should_terminate           = false;
 int  ConcurrentMarkSweepThread::_CMS_flag                   = CMS_nil;
 
 volatile jint ConcurrentMarkSweepThread::_pending_yields    = 0;
 
-SurrogateLockerThread* ConcurrentMarkSweepThread::_slt      = NULL;
-SurrogateLockerThread::SLT_msg_type
-     ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty;
-Monitor* ConcurrentMarkSweepThread::_sltMonitor             = NULL;
-
 ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector)
   : ConcurrentGCThread() {
   assert(UseConcMarkSweepGC,  "UseConcMarkSweepGC should be set");
@@ -62,88 +56,58 @@
 
   set_name("CMS Main Thread");
 
-  if (os::create_thread(this, os::cgc_thread)) {
-    // An old comment here said: "Priority should be just less
-    // than that of VMThread".  Since the VMThread runs at
-    // NearMaxPriority, the old comment was inaccurate, but
-    // changing the default priority to NearMaxPriority-1
-    // could change current behavior, so the default of
-    // NearMaxPriority stays in place.
-    //
-    // Note that there's a possibility of the VMThread
-    // starving if UseCriticalCMSThreadPriority is on.
-    // That won't happen on Solaris for various reasons,
-    // but may well happen on non-Solaris platforms.
-    int native_prio;
-    if (UseCriticalCMSThreadPriority) {
-      native_prio = os::java_to_os_priority[CriticalPriority];
-    } else {
-      native_prio = os::java_to_os_priority[NearMaxPriority];
-    }
-    os::set_native_priority(this, native_prio);
-
-    if (!DisableStartThread) {
-      os::start_thread(this);
-    }
-  }
-  _sltMonitor = SLT_lock;
+  // An old comment here said: "Priority should be just less
+  // than that of VMThread".  Since the VMThread runs at
+  // NearMaxPriority, the old comment was inaccurate, but
+  // changing the default priority to NearMaxPriority-1
+  // could change current behavior, so the default of
+  // NearMaxPriority stays in place.
+  //
+  // Note that there's a possibility of the VMThread
+  // starving if UseCriticalCMSThreadPriority is on.
+  // That won't happen on Solaris for various reasons,
+  // but may well happen on non-Solaris platforms.
+  create_and_start(UseCriticalCMSThreadPriority ? CriticalPriority : NearMaxPriority);
 }
 
-void ConcurrentMarkSweepThread::run() {
+void ConcurrentMarkSweepThread::run_service() {
   assert(this == cmst(), "just checking");
 
-  initialize_in_thread();
-  // From this time Thread::current() should be working.
-  assert(this == Thread::current(), "just checking");
   if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) {
-    warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
+    log_warning(gc)("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
   }
-  // Wait until Universe::is_fully_initialized()
+
   {
-    CMSLoopCountWarn loopX("CMS::run", "waiting for "
-                           "Universe::is_fully_initialized()", 2);
     MutexLockerEx x(CGC_lock, true);
     set_CMS_flag(CMS_cms_wants_token);
-    // Wait until Universe is initialized and all initialization is completed.
-    while (!is_init_completed() && !Universe::is_fully_initialized() &&
-           !_should_terminate) {
-      CGC_lock->wait(true, 200);
-      loopX.tick();
-    }
+    assert(is_init_completed() && Universe::is_fully_initialized(), "ConcurrentGCThread::run() should have waited for this.");
+
     // Wait until the surrogate locker thread that will do
     // pending list locking on our behalf has been created.
     // We cannot start the SLT thread ourselves since we need
     // to be a JavaThread to do so.
     CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2);
-    while (_slt == NULL && !_should_terminate) {
+    while (!ReferencePendingListLocker::is_initialized() && !should_terminate()) {
       CGC_lock->wait(true, 200);
       loopY.tick();
     }
     clear_CMS_flag(CMS_cms_wants_token);
   }
 
-  while (!_should_terminate) {
+  while (!should_terminate()) {
     sleepBeforeNextCycle();
-    if (_should_terminate) break;
+    if (should_terminate()) break;
     GCIdMark gc_id_mark;
     GCCause::Cause cause = _collector->_full_gc_requested ?
       _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
     _collector->collect_in_background(cause);
   }
-  assert(_should_terminate, "just checking");
+
   // Check that the state of any protocol for synchronization
   // between background (CMS) and foreground collector is "clean"
   // (i.e. will not potentially block the foreground collector,
   // requiring action by us).
   verify_ok_to_terminate();
-  // Signal that it is terminated
-  {
-    MutexLockerEx mu(Terminator_lock,
-                     Mutex::_no_safepoint_check_flag);
-    assert(_cmst == this, "Weird!");
-    _cmst = NULL;
-    Terminator_lock->notify();
-  }
 }
 
 #ifndef PRODUCT
@@ -157,39 +121,24 @@
 
 // create and start a new ConcurrentMarkSweep Thread for given CMS generation
 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) {
-  if (!_should_terminate) {
-    assert(cmst() == NULL, "start() called twice?");
-    ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector);
-    assert(cmst() == th, "Where did the just-created CMS thread go?");
-    return th;
-  }
-  return NULL;
+  guarantee(_cmst == NULL, "start() called twice!");
+  ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector);
+  assert(_cmst == th, "Where did the just-created CMS thread go?");
+  return th;
 }
 
-void ConcurrentMarkSweepThread::stop() {
-  // it is ok to take late safepoints here, if needed
-  {
-    MutexLockerEx x(Terminator_lock);
-    _should_terminate = true;
-  }
-  { // Now post a notify on CGC_lock so as to nudge
-    // CMS thread(s) that might be slumbering in
-    // sleepBeforeNextCycle.
-    MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
-    CGC_lock->notify_all();
-  }
-  { // Now wait until (all) CMS thread(s) have exited
-    MutexLockerEx x(Terminator_lock);
-    while(cmst() != NULL) {
-      Terminator_lock->wait();
-    }
-  }
+void ConcurrentMarkSweepThread::stop_service() {
+  // Now post a notify on CGC_lock so as to nudge
+  // CMS thread(s) that might be slumbering in
+  // sleepBeforeNextCycle.
+  MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
+  CGC_lock->notify_all();
 }
 
 void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) {
   assert(tc != NULL, "Null ThreadClosure");
-  if (_cmst != NULL) {
-    tc->do_thread(_cmst);
+  if (cmst() != NULL && !cmst()->has_terminated()) {
+    tc->do_thread(cmst());
   }
   assert(Universe::is_fully_initialized(),
          "Called too early, make sure heap is fully initialized");
@@ -202,8 +151,8 @@
 }
 
 void ConcurrentMarkSweepThread::print_all_on(outputStream* st) {
-  if (_cmst != NULL) {
-    _cmst->print_on(st);
+  if (cmst() != NULL && !cmst()->has_terminated()) {
+    cmst()->print_on(st);
     st->cr();
   }
   if (_collector != NULL) {
@@ -278,7 +227,7 @@
 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
   MutexLockerEx x(CGC_lock,
                   Mutex::_no_safepoint_check_flag);
-  if (_should_terminate || _collector->_full_gc_requested) {
+  if (should_terminate() || _collector->_full_gc_requested) {
     return;
   }
   set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
@@ -307,7 +256,7 @@
 
   unsigned int loop_count = 0;
 
-  while(!_should_terminate) {
+  while(!should_terminate()) {
     double now_time = os::elapsedTime();
     long wait_time_millis;
 
@@ -327,7 +276,7 @@
     {
       MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
 
-      if (_should_terminate || _collector->_full_gc_requested) {
+      if (should_terminate() || _collector->_full_gc_requested) {
         return;
       }
       set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
@@ -358,13 +307,13 @@
 
     // Too many loops warning
     if(++loop_count == 0) {
-      warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
+      log_warning(gc)("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
     }
   }
 }
 
 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
-  while (!_should_terminate) {
+  while (!should_terminate()) {
     if(CMSWaitDuration >= 0) {
       // Wait until the next synchronous GC, a concurrent full gc
       // request or a timeout, whichever is earlier.
@@ -381,15 +330,3 @@
     // and wait some more
   }
 }
-
-// Note: this method, although exported by the ConcurrentMarkSweepThread,
-// which is a non-JavaThread, can only be called by a JavaThread.
-// Currently this is done at vm creation time (post-vm-init) by the
-// main/Primordial (Java)Thread.
-// XXX Consider changing this in the future to allow the CMS thread
-// itself to create this thread?
-void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) {
-  assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC");
-  assert(_slt == NULL, "SLT already created");
-  _slt = SurrogateLockerThread::make(THREAD);
-}
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -37,17 +37,10 @@
   friend class VMStructs;
   friend class ConcurrentMarkSweepGeneration;   // XXX should remove friendship
   friend class CMSCollector;
- public:
-  virtual void run();
 
  private:
-  static ConcurrentMarkSweepThread*     _cmst;
-  static CMSCollector*                  _collector;
-  static SurrogateLockerThread*         _slt;
-  static SurrogateLockerThread::SLT_msg_type _sltBuffer;
-  static Monitor*                       _sltMonitor;
-
-  static bool _should_terminate;
+  static ConcurrentMarkSweepThread* _cmst;
+  static CMSCollector*              _collector;
 
   enum CMS_flag_type {
     CMS_nil             = NoBits,
@@ -72,13 +65,13 @@
   // debugging
   void verify_ok_to_terminate() const PRODUCT_RETURN;
 
+  void run_service();
+  void stop_service();
+
  public:
   // Constructor
   ConcurrentMarkSweepThread(CMSCollector* collector);
 
-  static void makeSurrogateLockerThread(TRAPS);
-  static SurrogateLockerThread* slt() { return _slt; }
-
   static void threads_do(ThreadClosure* tc);
 
   // Printing
@@ -91,8 +84,6 @@
 
   // Create and start the CMS Thread, or stop it on shutdown
   static ConcurrentMarkSweepThread* start(CMSCollector* collector);
-  static void stop();
-  static bool should_terminate() { return _should_terminate; }
 
   // Synchronization using CMS token
   static void synchronize(bool is_cms_thread);
@@ -170,7 +161,7 @@
   inline void tick() {
     _ticks++;
     if (CMSLoopWarn && _ticks % _threshold == 0) {
-      warning("%s has looped " INTX_FORMAT " times %s", _src, _ticks, _msg);
+      log_warning(gc)("%s has looped " INTX_FORMAT " times %s", _src, _ticks, _msg);
     }
   }
 };
--- a/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parCardTableModRefBS.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -161,15 +161,6 @@
   }
 }
 
-
-// If you want a talkative process_chunk_boundaries,
-// then #define NOISY(x) x
-#ifdef NOISY
-#error "Encountered a global preprocessor flag, NOISY, which might clash with local definition to follow"
-#else
-#define NOISY(x)
-#endif
-
 void
 CardTableModRefBSForCTRS::
 process_chunk_boundaries(Space* sp,
@@ -197,10 +188,6 @@
   assert(start_chunk_index >= lowest_non_clean_base_chunk_index, "Bounds error.");
   uintptr_t cur_chunk_index   = start_chunk_index - lowest_non_clean_base_chunk_index;
 
-  NOISY(tty->print_cr("===========================================================================");)
-  NOISY(tty->print_cr(" process_chunk_boundary: Called with [" PTR_FORMAT "," PTR_FORMAT ")",
-                      chunk_mr.start(), chunk_mr.end());)
-
   // First, set "our" lowest_non_clean entry, which would be
   // used by the thread scanning an adjoining left chunk with
   // a non-array object straddling the mutual boundary.
@@ -239,36 +226,18 @@
       }
     }
     if (first_dirty_card != NULL) {
-      NOISY(tty->print_cr(" LNC: Found a dirty card at " PTR_FORMAT " in current chunk",
-                    first_dirty_card);)
       assert(cur_chunk_index < lowest_non_clean_chunk_size, "Bounds error.");
       assert(lowest_non_clean[cur_chunk_index] == NULL,
              "Write exactly once : value should be stable hereafter for this round");
       lowest_non_clean[cur_chunk_index] = first_dirty_card;
-    } NOISY(else {
-      tty->print_cr(" LNC: Found no dirty card in current chunk; leaving LNC entry NULL");
-      // In the future, we could have this thread look for a non-NULL value to copy from its
-      // right neighbor (up to the end of the first object).
-      if (last_card_of_cur_chunk < last_card_of_first_obj) {
-        tty->print_cr(" LNC: BEWARE!!! first obj straddles past right end of chunk:\n"
-                      "   might be efficient to get value from right neighbor?");
-      }
-    })
+    }
   } else {
     // In this case we can help our neighbor by just asking them
     // to stop at our first card (even though it may not be dirty).
-    NOISY(tty->print_cr(" LNC: first block is not a non-array object; setting LNC to first card of current chunk");)
     assert(lowest_non_clean[cur_chunk_index] == NULL, "Write once : value should be stable hereafter");
     jbyte* first_card_of_cur_chunk = byte_for(chunk_mr.start());
     lowest_non_clean[cur_chunk_index] = first_card_of_cur_chunk;
   }
-  NOISY(tty->print_cr(" process_chunk_boundary: lowest_non_clean[" INTPTR_FORMAT "] = " PTR_FORMAT
-                "   which corresponds to the heap address " PTR_FORMAT,
-                cur_chunk_index, lowest_non_clean[cur_chunk_index],
-                (lowest_non_clean[cur_chunk_index] != NULL)
-                ? addr_for(lowest_non_clean[cur_chunk_index])
-                : NULL);)
-  NOISY(tty->print_cr("---------------------------------------------------------------------------");)
 
   // Next, set our own max_to_do, which will strictly/exclusively bound
   // the highest address that we will scan past the right end of our chunk.
@@ -285,8 +254,6 @@
         || oop(last_block)->is_objArray()  // last_block is an array (precisely marked)
         || oop(last_block)->is_typeArray()) {
       max_to_do = chunk_mr.end();
-      NOISY(tty->print_cr(" process_chunk_boundary: Last block on this card is not a non-array object;\n"
-                         "   max_to_do left at " PTR_FORMAT, max_to_do);)
     } else {
       assert(last_block < chunk_mr.end(), "Tautology");
       // It is a non-array object that straddles the right boundary of this chunk.
@@ -301,9 +268,6 @@
         // subsequent cards still in this chunk must have been made
         // precisely; we can cap processing at the end of our chunk.
         max_to_do = chunk_mr.end();
-        NOISY(tty->print_cr(" process_chunk_boundary: Head of last object on this card is not dirty;\n"
-                            "   max_to_do left at " PTR_FORMAT,
-                            max_to_do);)
       } else {
         // The last object must be considered dirty, and extends onto the
         // following chunk.  Look for a dirty card in that chunk that will
@@ -323,8 +287,6 @@
              cur <= last_card_of_last_obj; cur++) {
           const jbyte val = *cur;
           if (card_will_be_scanned(val)) {
-            NOISY(tty->print_cr(" Found a non-clean card " PTR_FORMAT " with value 0x%x",
-                                cur, (int)val);)
             limit_card = cur; break;
           } else {
             assert(!card_may_have_been_dirty(val), "Error: card can't be skipped");
@@ -333,10 +295,6 @@
         if (limit_card != NULL) {
           max_to_do = addr_for(limit_card);
           assert(limit_card != NULL && max_to_do != NULL, "Error");
-          NOISY(tty->print_cr(" process_chunk_boundary: Found a dirty card at " PTR_FORMAT
-                        "   max_to_do set at " PTR_FORMAT " which is before end of last block in chunk: "
-                        PTR_FORMAT " + " PTR_FORMAT " = " PTR_FORMAT,
-                        limit_card, max_to_do, last_block, last_block_size, (last_block+last_block_size));)
         } else {
           // The following is a pessimistic value, because it's possible
           // that a dirty card on a subsequent chunk has been cleared by
@@ -346,10 +304,6 @@
           limit_card = last_card_of_last_obj;
           max_to_do = last_block + last_block_size;
           assert(limit_card != NULL && max_to_do != NULL, "Error");
-          NOISY(tty->print_cr(" process_chunk_boundary: Found no dirty card before end of last block in chunk\n"
-                              "   Setting limit_card to " PTR_FORMAT
-                              " and max_to_do " PTR_FORMAT " + " PTR_FORMAT " = " PTR_FORMAT,
-                              limit_card, last_block, last_block_size, max_to_do);)
         }
         assert(0 < cur_chunk_index+1 && cur_chunk_index+1 < lowest_non_clean_chunk_size,
                "Bounds error.");
@@ -382,7 +336,6 @@
                  "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
                  p2i(sp->used_region().start()), p2i(sp->used_region().end()),
                  p2i(used.start()), p2i(used.end()));
-          NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");)
           last_chunk_index_to_check = last_chunk_index;
         }
         for (uintptr_t lnc_index = cur_chunk_index + 1;
@@ -392,9 +345,6 @@
           if (lnc_card != NULL) {
             // we can stop at the first non-NULL entry we find
             if (lnc_card <= limit_card) {
-              NOISY(tty->print_cr(" process_chunk_boundary: LNC card " PTR_FORMAT " is lower than limit_card " PTR_FORMAT,
-                                  "   max_to_do will be lowered to " PTR_FORMAT " from " PTR_FORMAT,
-                                  lnc_card, limit_card, addr_for(lnc_card), max_to_do);)
               limit_card = lnc_card;
               max_to_do = addr_for(limit_card);
               assert(limit_card != NULL && max_to_do != NULL, "Error");
@@ -410,9 +360,6 @@
     assert(max_to_do != NULL, "OOPS 2!");
   } else {
     max_to_do = used.end();
-    NOISY(tty->print_cr(" process_chunk_boundary: Last chunk of this space;\n"
-                  "   max_to_do left at " PTR_FORMAT,
-                  max_to_do);)
   }
   assert(max_to_do != NULL, "OOPS 3!");
   // Now we can set the closure we're using so it doesn't to beyond
@@ -421,11 +368,8 @@
 #ifndef PRODUCT
   dcto_cl->set_last_bottom(max_to_do);
 #endif
-  NOISY(tty->print_cr("===========================================================================\n");)
 }
 
-#undef NOISY
-
 void
 CardTableModRefBSForCTRS::
 get_LNC_array_for_space(Space* sp,
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -233,11 +233,15 @@
     if (word_sz * 100 < ParallelGCBufferWastePct * plab->word_sz()) {
       // Is small enough; abandon this buffer and start a new one.
       plab->retire();
-      size_t buf_size = plab->word_sz();
+      // The minimum size has to be twice SurvivorAlignmentInBytes to
+      // allow for padding used in the alignment of 1 word.  A padding
+      // of 1 is too small for a filler word so the padding size will
+      // be increased by SurvivorAlignmentInBytes.
+      size_t min_usable_size = 2 * static_cast<size_t>(SurvivorAlignmentInBytes >> LogHeapWordSize);
+      size_t buf_size = MAX2(plab->word_sz(), min_usable_size);
       HeapWord* buf_space = sp->par_allocate(buf_size);
       if (buf_space == NULL) {
-        const size_t min_bytes =
-          PLAB::min_size() << LogHeapWordSize;
+        const size_t min_bytes = MAX2(PLAB::min_size(), min_usable_size) << LogHeapWordSize;
         size_t free_bytes = sp->free();
         while(buf_space == NULL && free_bytes >= min_bytes) {
           buf_size = free_bytes >> LogHeapWordSize;
@@ -253,7 +257,10 @@
         // Note that we cannot compare buf_size < word_sz below
         // because of AlignmentReserve (see PLAB::allocate()).
         assert(obj != NULL || plab->words_remaining() < word_sz,
-               "Else should have been able to allocate");
+               "Else should have been able to allocate requested object size "
+               SIZE_FORMAT ", PLAB size " SIZE_FORMAT ", SurvivorAlignmentInBytes "
+               SIZE_FORMAT ", words_remaining " SIZE_FORMAT,
+               word_sz, buf_size, SurvivorAlignmentInBytes, plab->words_remaining());
         // It's conceivable that we may be able to use the
         // buffer we just grabbed for subsequent small requests
         // even if not for this one.
@@ -391,7 +398,7 @@
 }
 
 void ParScanThreadStateSet::print_termination_stats() {
-  LogHandle(gc, task, stats) log;
+  Log(gc, task, stats) log;
   if (!log.is_debug()) {
     return;
   }
@@ -423,7 +430,7 @@
   if (!log_develop_is_enabled(Trace, gc, task, stats)) {
     return;
   }
-  LogHandle(gc, task, stats) log;
+  Log(gc, task, stats) log;
   ResourceMark rm;
   outputStream* st = log.trace_stream();
   print_taskqueue_stats_hdr(st);
@@ -901,7 +908,7 @@
     size_policy->minor_collection_begin();
   }
 
-  GCTraceTime(Trace, gc) t1("ParNew", NULL, gch->gc_cause());
+  GCTraceTime(Trace, gc, phases) t1("ParNew", NULL, gch->gc_cause());
 
   age_table()->clear();
   to()->clear(SpaceDecorator::Mangle);
--- a/hotspot/src/share/vm/gc/cms/parOopClosures.inline.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parOopClosures.inline.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -82,18 +82,19 @@
     if ((HeapWord*)obj < _boundary) {
 #ifndef PRODUCT
       if (_g->to()->is_in_reserved(obj)) {
-        tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p2i(p));
+        Log(gc) log;
+        log.error("Scanning field (" PTR_FORMAT ") twice?", p2i(p));
         GenCollectedHeap* gch = GenCollectedHeap::heap();
         Space* sp = gch->space_containing(p);
         oop obj = oop(sp->block_start(p));
         assert((HeapWord*)obj < (HeapWord*)p, "Error");
-        tty->print_cr("Object: " PTR_FORMAT, p2i((void *)obj));
-        tty->print_cr("-------");
-        obj->print();
-        tty->print_cr("-----");
-        tty->print_cr("Heap:");
-        tty->print_cr("-----");
-        gch->print();
+        log.error("Object: " PTR_FORMAT, p2i((void *)obj));
+        log.error("-------");
+        obj->print_on(log.error_stream());
+        log.error("-----");
+        log.error("Heap:");
+        log.error("-----");
+        gch->print_on(log.error_stream());
         ShouldNotReachHere();
       }
 #endif
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -38,27 +38,17 @@
 // Methods in abstract class VM_CMS_Operation
 //////////////////////////////////////////////////////////
 void VM_CMS_Operation::acquire_pending_list_lock() {
-  // The caller may block while communicating
-  // with the SLT thread in order to acquire/release the PLL.
-  SurrogateLockerThread* slt = ConcurrentMarkSweepThread::slt();
-  if (slt != NULL) {
-    slt->manipulatePLL(SurrogateLockerThread::acquirePLL);
-  } else {
-    SurrogateLockerThread::report_missing_slt();
-  }
+  _pending_list_locker.lock();
 }
 
 void VM_CMS_Operation::release_and_notify_pending_list_lock() {
-  // The caller may block while communicating
-  // with the SLT thread in order to acquire/release the PLL.
-  ConcurrentMarkSweepThread::slt()->
-    manipulatePLL(SurrogateLockerThread::releaseAndNotifyPLL);
+  _pending_list_locker.unlock();
 }
 
 void VM_CMS_Operation::verify_before_gc() {
   if (VerifyBeforeGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    GCTraceTime(Info, gc, verify) tm("Verify Before", _collector->_gc_timer_cm);
+    GCTraceTime(Info, gc, phases, verify) tm("Verify Before", _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -70,7 +60,7 @@
 void VM_CMS_Operation::verify_after_gc() {
   if (VerifyAfterGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    GCTraceTime(Info, gc, verify) tm("Verify After", _collector->_gc_timer_cm);
+    GCTraceTime(Info, gc, phases, verify) tm("Verify After", _collector->_gc_timer_cm);
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -95,7 +85,7 @@
   assert(!ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
          "Possible deadlock");
 
-  if (needs_pll()) {
+  if (needs_pending_list_lock()) {
     acquire_pending_list_lock();
   }
   // Get the Heap_lock after the pending_list_lock.
@@ -103,7 +93,7 @@
   if (lost_race()) {
     assert(_prologue_succeeded == false, "Initialized in c'tor");
     Heap_lock->unlock();
-    if (needs_pll()) {
+    if (needs_pending_list_lock()) {
       release_and_notify_pending_list_lock();
     }
   } else {
@@ -120,7 +110,7 @@
 
   // Release the Heap_lock first.
   Heap_lock->unlock();
-  if (needs_pll()) {
+  if (needs_pending_list_lock()) {
     release_and_notify_pending_list_lock();
   }
 }
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -28,6 +28,7 @@
 #include "gc/cms/concurrentMarkSweepGeneration.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcId.hpp"
+#include "gc/shared/referencePendingListLocker.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "runtime/vm_operations.hpp"
 
@@ -51,6 +52,9 @@
 class CMSCollector;
 
 class VM_CMS_Operation: public VM_Operation {
+ private:
+  ReferencePendingListLocker _pending_list_locker;
+
  protected:
   CMSCollector*  _collector;                 // associated collector
   bool           _prologue_succeeded;     // whether doit_prologue succeeded
@@ -73,7 +77,7 @@
   virtual const CMSCollector::CollectorState legal_state() const = 0;
 
   // Whether the pending list lock needs to be held
-  virtual const bool needs_pll() const = 0;
+  virtual const bool needs_pending_list_lock() const = 0;
 
   // Execute operations in the context of the caller,
   // prior to execution of the vm operation itself.
@@ -105,7 +109,7 @@
     return CMSCollector::InitialMarking;
   }
 
-  virtual const bool needs_pll() const {
+  virtual const bool needs_pending_list_lock() const {
     return false;
   }
 };
@@ -122,7 +126,7 @@
     return CMSCollector::FinalMarking;
   }
 
-  virtual const bool needs_pll() const {
+  virtual const bool needs_pending_list_lock() const {
     return true;
   }
 };
--- a/hotspot/src/share/vm/gc/cms/vmStructs_cms.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/vmStructs_cms.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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,14 +51,12 @@
            declare_type(ConcurrentMarkSweepGeneration,CardGeneration)     \
            declare_type(CompactibleFreeListSpace,     CompactibleSpace)   \
            declare_type(ConcurrentMarkSweepThread,    NamedThread)        \
-           declare_type(SurrogateLockerThread, JavaThread)                \
   declare_toplevel_type(CMSCollector)                                     \
   declare_toplevel_type(CMSBitMap)                                        \
   declare_toplevel_type(FreeChunk)                                        \
   declare_toplevel_type(Metablock)                                        \
   declare_toplevel_type(ConcurrentMarkSweepThread*)                       \
   declare_toplevel_type(ConcurrentMarkSweepGeneration*)                   \
-  declare_toplevel_type(SurrogateLockerThread*)                           \
   declare_toplevel_type(CompactibleFreeListSpace*)                        \
   declare_toplevel_type(CMSCollector*)                                    \
   declare_toplevel_type(AFLBinaryTreeDictionary)                          \
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -145,7 +145,6 @@
   verify();
 }
 
-
 void CollectionSetChooser::add_region(HeapRegion* hr) {
   assert(!hr->is_pinned(),
          "Pinned region shouldn't be added to the collection set (index %u)", hr->hrm_index());
@@ -210,4 +209,67 @@
   _front = 0;
   _end = 0;
   _remaining_reclaimable_bytes = 0;
+}
+
+class ParKnownGarbageHRClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
+  CSetChooserParUpdater _cset_updater;
+
+public:
+  ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
+                           uint chunk_size) :
+    _g1h(G1CollectedHeap::heap()),
+    _cset_updater(hrSorted, true /* parallel */, chunk_size) { }
+
+  bool doHeapRegion(HeapRegion* r) {
+    // Do we have any marking information for this region?
+    if (r->is_marked()) {
+      // We will skip any region that's currently used as an old GC
+      // alloc region (we should not consider those for collection
+      // before we fill them up).
+      if (_cset_updater.should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
+        _cset_updater.add_region(r);
+      }
+    }
+    return false;
+  }
 };
+
+class ParKnownGarbageTask: public AbstractGangTask {
+  CollectionSetChooser* _hrSorted;
+  uint _chunk_size;
+  G1CollectedHeap* _g1;
+  HeapRegionClaimer _hrclaimer;
+
+public:
+  ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size, uint n_workers) :
+      AbstractGangTask("ParKnownGarbageTask"),
+      _hrSorted(hrSorted), _chunk_size(chunk_size),
+      _g1(G1CollectedHeap::heap()), _hrclaimer(n_workers) {}
+
+  void work(uint worker_id) {
+    ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
+    _g1->heap_region_par_iterate(&parKnownGarbageCl, worker_id, &_hrclaimer);
+  }
+};
+
+uint CollectionSetChooser::calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) const {
+  assert(n_workers > 0, "Active gc workers should be greater than 0");
+  const uint overpartition_factor = 4;
+  const uint min_chunk_size = MAX2(n_regions / n_workers, 1U);
+  return MAX2(n_regions / (n_workers * overpartition_factor), min_chunk_size);
+}
+
+void CollectionSetChooser::rebuild(WorkGang* workers, uint n_regions) {
+  clear();
+
+  uint n_workers = workers->active_workers();
+
+  uint chunk_size = calculate_parallel_work_chunk_size(n_workers, n_regions);
+  prepare_for_par_region_addition(n_workers, n_regions, chunk_size);
+
+  ParKnownGarbageTask par_known_garbage_task(this, chunk_size, n_workers);
+  workers->run_task(&par_known_garbage_task);
+
+  sort_regions();
+}
--- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -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
@@ -65,6 +65,9 @@
   // The sum of reclaimable bytes over all the regions in the CSet chooser.
   size_t _remaining_reclaimable_bytes;
 
+  // Calculate and return chunk size (in number of regions) for parallel
+  // addition of regions
+  uint calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) const;
 public:
 
   // Return the current candidate region to be considered for
@@ -132,6 +135,8 @@
 
   void clear();
 
+  void rebuild(WorkGang* workers, uint n_regions);
+
   // Return the number of candidate regions that remain to be collected.
   uint remaining_regions() { return _end - _front; }
 
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -27,11 +27,13 @@
 #include "gc/g1/concurrentG1RefineThread.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
+#include "gc/g1/g1Predictions.hpp"
 #include "runtime/java.hpp"
 
-ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
+ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictor) :
   _threads(NULL),
   _sample_thread(NULL),
+  _predictor_sigma(predictor->sigma()),
   _hot_card_cache(g1h)
 {
   // Ergonomically select initial concurrent refinement parameters
@@ -49,10 +51,12 @@
     FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2);
   }
   set_red_zone(MAX2(G1ConcRefinementRedZone, yellow_zone()));
+
 }
 
 ConcurrentG1Refine* ConcurrentG1Refine::create(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure, jint* ecode) {
-  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h);
+  G1CollectorPolicy* policy = g1h->g1_policy();
+  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(g1h, &policy->predictor());
   if (cg1r == NULL) {
     *ecode = JNI_ENOMEM;
     vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
@@ -155,3 +159,43 @@
   _sample_thread->print_on(st);
   st->cr();
 }
+
+void ConcurrentG1Refine::adjust(double update_rs_time,
+                                double update_rs_processed_buffers,
+                                double goal_ms) {
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+
+  if (G1UseAdaptiveConcRefinement) {
+    const int k_gy = 3, k_gr = 6;
+    const double inc_k = 1.1, dec_k = 0.9;
+
+    size_t g = green_zone();
+    if (update_rs_time > goal_ms) {
+      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 = (size_t)MAX2(g * inc_k, g + 1.0);
+      }
+    }
+    // Change the refinement threads params
+    set_green_zone(g);
+    set_yellow_zone(g * k_gy);
+    set_red_zone(g * k_gr);
+    reinitialize_threads();
+
+    size_t processing_threshold_delta = MAX2<size_t>(green_zone() * _predictor_sigma, 1);
+    size_t processing_threshold = MIN2(green_zone() + processing_threshold_delta,
+                                    yellow_zone());
+    // Change the barrier params
+    dcqs.set_process_completed_threshold((int)processing_threshold);
+    dcqs.set_max_completed_queue((int)red_zone());
+  }
+
+  size_t curr_queue_size = dcqs.completed_buffers_num();
+  if (curr_queue_size >= yellow_zone()) {
+    dcqs.set_completed_queue_padding(curr_queue_size);
+  } else {
+    dcqs.set_completed_queue_padding(0);
+  }
+  dcqs.notify_if_necessary();
+}
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -35,6 +35,7 @@
 class ConcurrentG1RefineThread;
 class G1CollectedHeap;
 class G1HotCardCache;
+class G1Predictions;
 class G1RegionToSpaceMapper;
 class G1RemSet;
 class DirtyCardQueue;
@@ -67,13 +68,15 @@
 
   size_t _thread_threshold_step;
 
+  double _predictor_sigma;
+
   // We delay the refinement of 'hot' cards using the hot card cache.
   G1HotCardCache _hot_card_cache;
 
   // Reset the threshold step value based of the current zone boundaries.
   void reset_threshold_step();
 
-  ConcurrentG1Refine(G1CollectedHeap* g1h);
+  ConcurrentG1Refine(G1CollectedHeap* g1h, const G1Predictions* predictions);
 
  public:
   ~ConcurrentG1Refine();
@@ -85,6 +88,8 @@
   void init(G1RegionToSpaceMapper* card_counts_storage);
   void stop();
 
+  void adjust(double update_rs_time, double update_rs_processed_buffers, double goal_ms);
+
   void reinitialize_threads();
 
   // Iterate over all concurrent refinement threads
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -76,9 +76,8 @@
 }
 
 void ConcurrentG1RefineThread::wait_for_completed_buffers() {
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
-  while (!_should_terminate && !is_active()) {
+  while (!should_terminate() && !is_active()) {
     _monitor->wait(Mutex::_no_safepoint_check_flag);
   }
 }
@@ -109,22 +108,13 @@
   }
 }
 
-void ConcurrentG1RefineThread::run() {
-  initialize_in_thread();
-  wait_for_universe_init();
-
-  run_service();
-
-  terminate();
-}
-
 void ConcurrentG1RefineThread::run_service() {
   _vtime_start = os::elapsedVTime();
 
-  while (!_should_terminate) {
+  while (!should_terminate()) {
     // Wait for work
     wait_for_completed_buffers();
-    if (_should_terminate) {
+    if (should_terminate()) {
       break;
     }
 
@@ -135,7 +125,12 @@
     {
       SuspendibleThreadSetJoiner sts_join;
 
-      do {
+      while (!should_terminate()) {
+        if (sts_join.should_yield()) {
+          sts_join.yield();
+          continue;             // Re-check for termination after yield delay.
+        }
+
         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.
@@ -147,17 +142,23 @@
         if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
           _next->activate();
         }
-      } while (dcqs.apply_closure_to_completed_buffer(_refine_closure,
-                                                      _worker_id + _worker_id_offset,
-                                                      _deactivation_threshold,
-                                                      false /* during_pause */));
 
-      deactivate();
-      log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                            _worker_id, _deactivation_threshold,
-                            dcqs.completed_buffers_num());
+        // Process the next buffer, if there are enough left.
+        if (!dcqs.apply_closure_to_completed_buffer(_refine_closure,
+                                                    _worker_id + _worker_id_offset,
+                                                    _deactivation_threshold,
+                                                    false /* during_pause */)) {
+          break; // Deactivate, number of buffers fell below threshold.
+        }
+      }
     }
 
+    deactivate();
+    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
+                          ", current: " SIZE_FORMAT,
+                          _worker_id, _deactivation_threshold,
+                          dcqs.completed_buffers_num());
+
     if (os::supports_vtime()) {
       _vtime_accum = (os::elapsedVTime() - _vtime_start);
     } else {
@@ -168,23 +169,6 @@
   log_debug(gc, refine)("Stopping %d", _worker_id);
 }
 
-void ConcurrentG1RefineThread::stop() {
-  // it is ok to take late safepoints here, if needed
-  {
-    MutexLockerEx mu(Terminator_lock);
-    _should_terminate = true;
-  }
-
-  stop_service();
-
-  {
-    MutexLockerEx mu(Terminator_lock);
-    while (!_has_terminated) {
-      Terminator_lock->wait();
-    }
-  }
-}
-
 void ConcurrentG1RefineThread::stop_service() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   _monitor->notify();
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -72,7 +72,6 @@
   void stop_service();
 
 public:
-  virtual void run();
   // Constructor
   ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
                            CardTableEntryClosure* refine_closure,
@@ -84,9 +83,6 @@
   double vtime_accum() { return _vtime_accum; }
 
   ConcurrentG1Refine* cg1r() { return _cg1r;     }
-
-  // shutdown
-  void stop();
 };
 
 #endif // SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/classLoaderData.hpp"
 #include "gc/g1/concurrentMarkThread.inline.hpp"
+#include "gc/g1/g1Analytics.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1MMUTracker.hpp"
@@ -41,9 +42,6 @@
 
 // The CM thread is created when the G1 garbage collector is used
 
-SurrogateLockerThread*
-     ConcurrentMarkThread::_slt = NULL;
-
 ConcurrentMarkThread::ConcurrentMarkThread(G1ConcurrentMark* cm) :
   ConcurrentGCThread(),
   _cm(cm),
@@ -82,60 +80,59 @@
 
 // Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
 void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) {
+  const G1Analytics* analytics = g1_policy->analytics();
   if (g1_policy->adaptive_young_list_length()) {
     double now = os::elapsedTime();
-    double prediction_ms = remark ? g1_policy->predict_remark_time_ms()
-                                  : g1_policy->predict_cleanup_time_ms();
+    double prediction_ms = remark ? analytics->predict_remark_time_ms()
+                                  : analytics->predict_cleanup_time_ms();
     G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
     jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms);
     os::sleep(this, sleep_time_ms, false);
   }
 }
 
-class GCConcPhaseTimer : StackObj {
+class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc, marking)> {
   G1ConcurrentMark* _cm;
 
  public:
-  GCConcPhaseTimer(G1ConcurrentMark* cm, const char* title) : _cm(cm) {
-    _cm->register_concurrent_phase_start(title);
+  G1ConcPhaseTimer(G1ConcurrentMark* cm, const char* title) :
+     GCTraceConcTimeImpl<LogLevel::Info,  LogTag::_gc, LogTag::_marking>(title),
+     _cm(cm) {
+    _cm->gc_timer_cm()->register_gc_concurrent_start(title);
   }
 
-  ~GCConcPhaseTimer() {
-    _cm->register_concurrent_phase_end();
+  ~G1ConcPhaseTimer() {
+    _cm->gc_timer_cm()->register_gc_concurrent_end();
   }
 };
 
-void ConcurrentMarkThread::run() {
-  initialize_in_thread();
-  wait_for_universe_init();
-
-  run_service();
-
-  terminate();
-}
-
 void ConcurrentMarkThread::run_service() {
   _vtime_start = os::elapsedVTime();
 
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   G1CollectorPolicy* g1_policy = g1h->g1_policy();
 
-  while (!_should_terminate) {
+  while (!should_terminate()) {
     // wait until started is set.
     sleepBeforeNextCycle();
-    if (_should_terminate) {
-      _cm->root_regions()->cancel_scan();
+    if (should_terminate()) {
       break;
     }
 
+    GCIdMark gc_id_mark;
+
+    cm()->concurrent_cycle_start();
+
     assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
+
+    GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
     {
       ResourceMark rm;
       HandleMark   hm;
       double cycle_start = os::elapsedVTime();
 
       {
-        GCConcPhaseTimer(_cm, "Concurrent Clearing of Claimed Marks");
+        G1ConcPhaseTimer t(_cm, "Concurrent Clear Claimed Marks");
         ClassLoaderDataGraph::clear_claimed_marks();
       }
 
@@ -148,22 +145,22 @@
       // correctness issue.
 
       {
-        GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning");
-        _cm->scanRootRegions();
+        G1ConcPhaseTimer t(_cm, "Concurrent Scan Root Regions");
+        _cm->scan_root_regions();
       }
 
       // It would be nice to use the GCTraceConcTime class here but
       // the "end" logging is inside the loop and not at the end of
       // a scope. Mimicking the same log output as GCTraceConcTime instead.
       jlong mark_start = os::elapsed_counter();
-      log_info(gc)("Concurrent Mark (%.3fs)", TimeHelper::counter_to_seconds(mark_start));
+      log_info(gc, marking)("Concurrent Mark (%.3fs)", TimeHelper::counter_to_seconds(mark_start));
 
       int iter = 0;
       do {
         iter++;
         if (!cm()->has_aborted()) {
-          GCConcPhaseTimer(_cm, "Concurrent Mark");
-          _cm->markFromRoots();
+          G1ConcPhaseTimer t(_cm, "Concurrent Mark From Roots");
+          _cm->mark_from_roots();
         }
 
         double mark_end_time = os::elapsedVTime();
@@ -171,18 +168,18 @@
         _vtime_mark_accum += (mark_end_time - cycle_start);
         if (!cm()->has_aborted()) {
           delay_to_keep_mmu(g1_policy, true /* remark */);
-          log_info(gc)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
-                       TimeHelper::counter_to_seconds(mark_start),
-                       TimeHelper::counter_to_seconds(mark_end),
-                       TimeHelper::counter_to_millis(mark_end - mark_start));
+          log_info(gc, marking)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
+                                TimeHelper::counter_to_seconds(mark_start),
+                                TimeHelper::counter_to_seconds(mark_end),
+                                TimeHelper::counter_to_millis(mark_end - mark_start));
 
           CMCheckpointRootsFinalClosure final_cl(_cm);
           VM_CGC_Operation op(&final_cl, "Pause Remark", true /* needs_pll */);
           VMThread::execute(&op);
         }
         if (cm()->restart_for_overflow()) {
-          log_debug(gc)("Restarting conc marking because of MS overflow in remark (restart #%d).", iter);
-          log_info(gc)("Concurrent Mark restart for overflow");
+          log_debug(gc, marking)("Restarting Concurrent Marking because of Mark Stack Overflow in Remark (Iteration #%d).", iter);
+          log_info(gc, marking)("Concurrent Mark Restart due to overflow");
         }
       } while (cm()->restart_for_overflow());
 
@@ -216,11 +213,9 @@
         // place, it would wait for us to process the regions
         // reclaimed by cleanup.
 
-        GCTraceConcTime(Info, gc) tt("Concurrent Cleanup");
-        GCConcPhaseTimer(_cm, "Concurrent Cleanup");
-
+        G1ConcPhaseTimer t(_cm, "Concurrent Complete Cleanup");
         // Now do the concurrent cleanup operation.
-        _cm->completeCleanup();
+        _cm->complete_cleanup();
 
         // Notify anyone who's waiting that there are no more free
         // regions coming. We have to do this before we join the STS
@@ -265,7 +260,7 @@
         if (!cm()->has_aborted()) {
           g1_policy->record_concurrent_mark_cleanup_completed();
         } else {
-          log_info(gc)("Concurrent Mark abort");
+          log_info(gc, marking)("Concurrent Mark Abort");
         }
       }
 
@@ -274,8 +269,8 @@
       // We may have aborted just before the remark. Do not bother clearing the
       // bitmap then, as it has been done during mark abort.
       if (!cm()->has_aborted()) {
-        GCConcPhaseTimer(_cm, "Concurrent Bitmap Clearing");
-        _cm->clearNextBitmap();
+        G1ConcPhaseTimer t(_cm, "Concurrent Cleanup for Next Mark");
+        _cm->cleanup_for_next_mark();
       } else {
         assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear");
       }
@@ -288,25 +283,11 @@
     {
       SuspendibleThreadSetJoiner sts_join;
       g1h->increment_old_marking_cycles_completed(true /* concurrent */);
-      g1h->register_concurrent_cycle_end();
+
+      cm()->concurrent_cycle_end();
     }
   }
-}
-
-void ConcurrentMarkThread::stop() {
-  {
-    MutexLockerEx ml(Terminator_lock);
-    _should_terminate = true;
-  }
-
-  stop_service();
-
-  {
-    MutexLockerEx ml(Terminator_lock);
-    while (!_has_terminated) {
-      Terminator_lock->wait();
-    }
-  }
+  _cm->root_regions()->cancel_scan();
 }
 
 void ConcurrentMarkThread::stop_service() {
@@ -320,7 +301,7 @@
   assert(!in_progress(), "should have been cleared");
 
   MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
-  while (!started() && !_should_terminate) {
+  while (!started() && !should_terminate()) {
     CGC_lock->wait(Mutex::_no_safepoint_check_flag);
   }
 
@@ -328,16 +309,3 @@
     set_in_progress();
   }
 }
-
-// Note: As is the case with CMS - this method, although exported
-// by the ConcurrentMarkThread, which is a non-JavaThread, can only
-// be called by a JavaThread. Currently this is done at vm creation
-// time (post-vm-init) by the main/Primordial (Java)Thread.
-// XXX Consider changing this in the future to allow the CM thread
-// itself to create this thread?
-void ConcurrentMarkThread::makeSurrogateLockerThread(TRAPS) {
-  assert(UseG1GC, "SLT thread needed only for concurrent GC");
-  assert(THREAD->is_Java_thread(), "must be a Java thread");
-  assert(_slt == NULL, "SLT already created");
-  _slt = SurrogateLockerThread::make(THREAD);
-}
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -38,13 +38,8 @@
 
   double _vtime_start;  // Initial virtual time.
   double _vtime_accum;  // Accumulated virtual time.
-
   double _vtime_mark_accum;
 
- public:
-  virtual void run();
-
- private:
   G1ConcurrentMark*                _cm;
 
   enum State {
@@ -61,15 +56,10 @@
   void run_service();
   void stop_service();
 
-  static SurrogateLockerThread*         _slt;
-
  public:
   // Constructor
   ConcurrentMarkThread(G1ConcurrentMark* cm);
 
-  static void makeSurrogateLockerThread(TRAPS);
-  static SurrogateLockerThread* slt() { return _slt; }
-
   // Total virtual time so far for this thread and concurrent marking tasks.
   double vtime_accum();
   // Marking virtual time so far this thread and concurrent marking tasks.
@@ -93,9 +83,6 @@
   // as the CM thread might take some time to wake up before noticing
   // that started() is set and set in_progress().
   bool during_cycle()      { return !idle(); }
-
-  // shutdown
-  void stop();
 };
 
 #endif // SHARE_VM_GC_G1_CONCURRENTMARKTHREAD_HPP
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -110,44 +110,6 @@
   }
 }
 
-bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
-                                   bool consume,
-                                   uint worker_i) {
-  bool res = true;
-  if (_buf != NULL) {
-    res = apply_closure_to_buffer(cl, _buf, _index, _sz,
-                                  consume,
-                                  worker_i);
-    if (res && consume) {
-      _index = _sz;
-    }
-  }
-  return res;
-}
-
-bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
-                                             void** buf,
-                                             size_t index, size_t sz,
-                                             bool consume,
-                                             uint worker_i) {
-  if (cl == NULL) return true;
-  size_t limit = byte_index_to_index(sz);
-  for (size_t i = byte_index_to_index(index); i < limit; ++i) {
-    jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
-    if (card_ptr != NULL) {
-      // Set the entry to null, so we don't do it again (via the test
-      // above) if we reconsider this buffer.
-      if (consume) {
-        buf[i] = NULL;
-      }
-      if (!cl->do_card_ptr(card_ptr, worker_i)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
   PtrQueueSet(notify_when_complete),
   _mut_process_closure(NULL),
@@ -188,22 +150,57 @@
   t->dirty_card_queue().handle_zero_index();
 }
 
-bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
+bool DirtyCardQueueSet::apply_closure_to_buffer(CardTableEntryClosure* cl,
+                                                BufferNode* node,
+                                                bool consume,
+                                                uint worker_i) {
+  if (cl == NULL) return true;
+  bool result = true;
+  void** buf = BufferNode::make_buffer_from_node(node);
+  size_t limit = DirtyCardQueue::byte_index_to_index(buffer_size());
+  size_t i = DirtyCardQueue::byte_index_to_index(node->index());
+  for ( ; i < limit; ++i) {
+    jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
+    assert(card_ptr != NULL, "invariant");
+    if (!cl->do_card_ptr(card_ptr, worker_i)) {
+      result = false;           // Incomplete processing.
+      break;
+    }
+  }
+  if (consume) {
+    size_t new_index = DirtyCardQueue::index_to_byte_index(i);
+    assert(new_index <= buffer_size(), "invariant");
+    node->set_index(new_index);
+  }
+  return result;
+}
+
+#ifndef ASSERT
+#define assert_fully_consumed(node, buffer_size)
+#else
+#define assert_fully_consumed(node, buffer_size)                \
+  do {                                                          \
+    size_t _afc_index = (node)->index();                        \
+    size_t _afc_size = (buffer_size);                           \
+    assert(_afc_index == _afc_size,                             \
+           "Buffer was not fully consumed as claimed: index: "  \
+           SIZE_FORMAT ", size: " SIZE_FORMAT,                  \
+            _afc_index, _afc_size);                             \
+  } while (0)
+#endif // ASSERT
+
+bool DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
   guarantee(_free_ids != NULL, "must be");
 
-  // claim a par id
-  uint worker_i = _free_ids->claim_par_id();
+  uint worker_i = _free_ids->claim_par_id(); // temporarily claim an id
+  bool result = apply_closure_to_buffer(_mut_process_closure, node, true, worker_i);
+  _free_ids->release_par_id(worker_i); // release the id
 
-  bool b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
-                                                   _sz, true, worker_i);
-  if (b) {
+  if (result) {
+    assert_fully_consumed(node, buffer_size());
     Atomic::inc(&_processed_buffers_mut);
   }
-
-  // release the id
-  _free_ids->release_par_id(worker_i);
-
-  return b;
+  return result;
 }
 
 
@@ -239,49 +236,31 @@
   if (nd == NULL) {
     return false;
   } else {
-    void** buf = BufferNode::make_buffer_from_node(nd);
-    size_t index = nd->index();
-    if (DirtyCardQueue::apply_closure_to_buffer(cl,
-                                                buf, index, _sz,
-                                                true, worker_i)) {
+    if (apply_closure_to_buffer(cl, nd, true, worker_i)) {
+      assert_fully_consumed(nd, buffer_size());
       // Done with fully processed buffer.
-      deallocate_buffer(buf);
+      deallocate_buffer(nd);
       Atomic::inc(&_processed_buffers_rs_thread);
-      return true;
     } else {
       // Return partially processed buffer to the queue.
-      enqueue_complete_buffer(buf, index);
-      return false;
+      guarantee(!during_pause, "Should never stop early");
+      enqueue_complete_buffer(nd);
     }
-  }
-}
-
-void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
-  BufferNode* nd = _completed_buffers_head;
-  while (nd != NULL) {
-    bool b =
-      DirtyCardQueue::apply_closure_to_buffer(cl,
-                                              BufferNode::make_buffer_from_node(nd),
-                                              0, _sz, false);
-    guarantee(b, "Should not stop early.");
-    nd = nd->next();
+    return true;
   }
 }
 
 void DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
   BufferNode* nd = _cur_par_buffer_node;
   while (nd != NULL) {
-    BufferNode* next = (BufferNode*)nd->next();
-    BufferNode* actual = (BufferNode*)Atomic::cmpxchg_ptr((void*)next, (volatile void*)&_cur_par_buffer_node, (void*)nd);
+    BufferNode* next = nd->next();
+    void* actual = Atomic::cmpxchg_ptr(next, &_cur_par_buffer_node, nd);
     if (actual == nd) {
-      bool b =
-        DirtyCardQueue::apply_closure_to_buffer(cl,
-                                                BufferNode::make_buffer_from_node(actual),
-                                                0, _sz, false);
+      bool b = apply_closure_to_buffer(cl, nd, false);
       guarantee(b, "Should not stop early.");
       nd = next;
     } else {
-      nd = actual;
+      nd = static_cast<BufferNode*>(actual);
     }
   }
 }
@@ -304,7 +283,7 @@
   while (buffers_to_delete != NULL) {
     BufferNode* nd = buffers_to_delete;
     buffers_to_delete = nd->next();
-    deallocate_buffer(BufferNode::make_buffer_from_node(nd));
+    deallocate_buffer(nd);
   }
 
 }
@@ -320,6 +299,13 @@
   shared_dirty_card_queue()->reset();
 }
 
+void DirtyCardQueueSet::concatenate_log(DirtyCardQueue& dcq) {
+  if (!dcq.is_empty()) {
+    enqueue_complete_buffer(
+      BufferNode::make_node_from_buffer(dcq.get_buf(), dcq.get_index()));
+    dcq.reinitialize();
+  }
+}
 
 void DirtyCardQueueSet::concatenate_logs() {
   // Iterate over all the threads, if we find a partial log add it to
@@ -329,23 +315,9 @@
   _max_completed_queue = max_jint;
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   for (JavaThread* t = Threads::first(); t; t = t->next()) {
-    DirtyCardQueue& dcq = t->dirty_card_queue();
-    if (dcq.size() != 0) {
-      void** buf = dcq.get_buf();
-      // We must NULL out the unused entries, then enqueue.
-      size_t limit = dcq.byte_index_to_index(dcq.get_index());
-      for (size_t i = 0; i < limit; ++i) {
-        buf[i] = NULL;
-      }
-      enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
-      dcq.reinitialize();
-    }
+    concatenate_log(t->dirty_card_queue());
   }
-  if (_shared_dirty_card_queue.size() != 0) {
-    enqueue_complete_buffer(_shared_dirty_card_queue.get_buf(),
-                            _shared_dirty_card_queue.get_index());
-    _shared_dirty_card_queue.reinitialize();
-  }
+  concatenate_log(_shared_dirty_card_queue);
   // Restore the completed buffer queue limit.
   _max_completed_queue = save_max_completed_queue;
 }
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -37,7 +37,7 @@
 public:
   // Process the card whose card table entry is "card_ptr".  If returns
   // "false", terminate the iteration early.
-  virtual bool do_card_ptr(jbyte* card_ptr, uint worker_i = 0) = 0;
+  virtual bool do_card_ptr(jbyte* card_ptr, uint worker_i) = 0;
 };
 
 // A ptrQueue whose elements are "oops", pointers to object heads.
@@ -52,23 +52,6 @@
   // Process queue entries and release resources.
   void flush() { flush_impl(); }
 
-  // Apply the closure to all elements, and reset the index to make the
-  // buffer empty.  If a closure application returns "false", return
-  // "false" immediately, halting the iteration.  If "consume" is true,
-  // deletes processed entries from logs.
-  bool apply_closure(CardTableEntryClosure* cl,
-                     bool consume = true,
-                     uint worker_i = 0);
-
-  // Apply the closure to all elements of "buf", down to "index"
-  // (inclusive.)  If returns "false", then a closure application returned
-  // "false", and we return immediately.  If "consume" is true, entries are
-  // set to NULL as they are processed, so they will not be processed again
-  // later.
-  static bool apply_closure_to_buffer(CardTableEntryClosure* cl,
-                                      void** buf, size_t index, size_t sz,
-                                      bool consume = true,
-                                      uint worker_i = 0);
   void **get_buf() { return _buf;}
   size_t get_index() { return _index;}
   void reinitialize() { _buf = 0; _sz = 0; _index = 0;}
@@ -94,8 +77,19 @@
 
   DirtyCardQueue _shared_dirty_card_queue;
 
-  // Override.
-  bool mut_process_buffer(void** buf);
+  // Apply the closure to the elements of "node" from it's index to
+  // buffer_size.  If all closure applications return true, then
+  // returns true.  Stops processing after the first closure
+  // application that returns false, and returns false from this
+  // function.  If "consume" is true, the node's index is updated to
+  // exclude the processed elements, e.g. up to the element for which
+  // the closure returned false.
+  bool apply_closure_to_buffer(CardTableEntryClosure* cl,
+                               BufferNode* node,
+                               bool consume,
+                               uint worker_i = 0);
+
+  bool mut_process_buffer(BufferNode* node);
 
   // Protected by the _cbl_mon.
   FreeIdSet* _free_ids;
@@ -107,6 +101,9 @@
 
   // Current buffer node used for parallel iteration.
   BufferNode* volatile _cur_par_buffer_node;
+
+  void concatenate_log(DirtyCardQueue& dcq);
+
 public:
   DirtyCardQueueSet(bool notify_when_complete = true);
 
@@ -125,13 +122,18 @@
 
   static void handle_zero_index_for_thread(JavaThread* t);
 
-  // If there exists some completed buffer, pop it, then apply the
-  // specified closure to all its elements, nulling out those elements
-  // processed.  If all elements are processed, returns "true".  If no
-  // completed buffers exist, returns false.  If a completed buffer exists,
-  // but is only partially completed before a "yield" happens, the
-  // partially completed buffer (with its processed elements set to NULL)
-  // is returned to the completed buffer set, and this call returns false.
+  // If there are more than stop_at completed buffers, pop one, apply
+  // the specified closure to its active elements, and return true.
+  // Otherwise return false.
+  //
+  // A completely processed buffer is freed.  However, if a closure
+  // invocation returns false, processing is stopped and the partially
+  // processed buffer (with its index updated to exclude the processed
+  // elements, e.g. up to the element for which the closure returned
+  // false) is returned to the completed buffer set.
+  //
+  // If during_pause is true, stop_at must be zero, and the closure
+  // must never return false.
   bool apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
                                          uint worker_i,
                                          size_t stop_at,
@@ -139,13 +141,10 @@
 
   BufferNode* get_completed_buffer(size_t stop_at);
 
-  // Applies the current closure to all completed buffers,
-  // non-consumptively.
-  void apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl);
-
   void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; }
   // Applies the current closure to all completed buffers, non-consumptively.
-  // Parallel version.
+  // Can be used in parallel, all callers using the iteration state initialized
+  // by reset_for_par_iteration.
   void par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl);
 
   DirtyCardQueue* shared_dirty_card_queue() {
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -26,6 +26,7 @@
 #include "gc/g1/g1AllocRegion.inline.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 G1CollectedHeap* G1AllocRegion::_g1h = NULL;
@@ -194,44 +195,53 @@
   return (alloc_region == _dummy_region) ? NULL : alloc_region;
 }
 
-#if G1_ALLOC_REGION_TRACING
+#ifndef PRODUCT
 void G1AllocRegion::trace(const char* str, size_t min_word_size, size_t desired_word_size, size_t actual_word_size, HeapWord* result) {
   // All the calls to trace that set either just the size or the size
-  // and the result are considered part of level 2 tracing and are
-  // skipped during level 1 tracing.
-  if ((actual_word_size == 0 && result == NULL) || (G1_ALLOC_REGION_TRACING > 1)) {
-    const size_t buffer_length = 128;
-    char hr_buffer[buffer_length];
-    char rest_buffer[buffer_length];
+  // and the result are considered part of detailed tracing and are
+  // skipped during other tracing.
+
+  Log(gc, alloc, region) log;
+
+  if (!log.is_debug()) {
+    return;
+  }
 
-    HeapRegion* alloc_region = _alloc_region;
-    if (alloc_region == NULL) {
-      jio_snprintf(hr_buffer, buffer_length, "NULL");
-    } else if (alloc_region == _dummy_region) {
-      jio_snprintf(hr_buffer, buffer_length, "DUMMY");
+  bool detailed_info = log.is_trace();
+
+  if ((actual_word_size == 0 && result == NULL) || detailed_info) {
+    ResourceMark rm;
+    outputStream* out;
+    if (detailed_info) {
+      out = log.trace_stream();
     } else {
-      jio_snprintf(hr_buffer, buffer_length,
-                   HR_FORMAT, HR_FORMAT_PARAMS(alloc_region));
+      out = log.debug_stream();
     }
 
-    if (G1_ALLOC_REGION_TRACING > 1) {
-      if (result != NULL) {
-        jio_snprintf(rest_buffer, buffer_length, "min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
-                     min_word_size, desired_word_size, actual_word_size, result);
-      } else if (min_word_size != 0) {
-        jio_snprintf(rest_buffer, buffer_length, "min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
-      } else {
-        jio_snprintf(rest_buffer, buffer_length, "");
-      }
+    out->print("%s: %u ", _name, _count);
+
+    if (_alloc_region == NULL) {
+      out->print("NULL");
+    } else if (_alloc_region == _dummy_region) {
+      out->print("DUMMY");
     } else {
-      jio_snprintf(rest_buffer, buffer_length, "");
+      out->print(HR_FORMAT, HR_FORMAT_PARAMS(_alloc_region));
     }
 
-    tty->print_cr("[%s] %u %s : %s %s",
-                  _name, _count, hr_buffer, str, rest_buffer);
+    out->print(" : %s", str);
+
+    if (detailed_info) {
+      if (result != NULL) {
+        out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
+                     min_word_size, desired_word_size, actual_word_size, p2i(result));
+      } else if (min_word_size != 0) {
+        out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
+      }
+    }
+    out->cr();
   }
 }
-#endif // G1_ALLOC_REGION_TRACING
+#endif // PRODUCT
 
 G1AllocRegion::G1AllocRegion(const char* name,
                              bool bot_updates)
@@ -253,7 +263,7 @@
 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size,
                                                  bool force) {
   assert(!force, "not supported for GC alloc regions");
-  return _g1h->new_gc_alloc_region(word_size, count(), _purpose);
+  return _g1h->new_gc_alloc_region(word_size, _purpose);
 }
 
 void G1GCAllocRegion::retire_region(HeapRegion* alloc_region,
--- a/hotspot/src/share/vm/gc/g1/g1AllocRegion.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1AllocRegion.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -31,9 +31,6 @@
 
 class G1CollectedHeap;
 
-// 0 -> no tracing, 1 -> basic tracing, 2 -> basic + allocation tracing
-#define G1_ALLOC_REGION_TRACING 0
-
 // A class that holds a region that is active in satisfying allocation
 // requests, potentially issued in parallel. When the active region is
 // full it will be retired and replaced with a new one. The
@@ -213,19 +210,11 @@
   // is returned after it's been retired.
   virtual HeapRegion* release();
 
-#if G1_ALLOC_REGION_TRACING
   void trace(const char* str,
              size_t min_word_size = 0,
              size_t desired_word_size = 0,
              size_t actual_word_size = 0,
-             HeapWord* result = NULL);
-#else // G1_ALLOC_REGION_TRACING
-  void trace(const char* str,
-             size_t min_word_size = 0,
-             size_t desired_word_size = 0,
-             size_t actual_word_size = 0,
-             HeapWord* result = NULL) { }
-#endif // G1_ALLOC_REGION_TRACING
+             HeapWord* result = NULL) PRODUCT_RETURN;
 };
 
 class MutatorAllocRegion : public G1AllocRegion {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1Analytics.hpp"
+#include "gc/g1/g1Predictions.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/numberSeq.hpp"
+
+// Different defaults for different number of GC threads
+// They were chosen by running GCOld and SPECjbb on debris with different
+//   numbers of GC threads and choosing them based on the results
+
+// all the same
+static double rs_length_diff_defaults[] = {
+  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+};
+
+static double cost_per_card_ms_defaults[] = {
+  0.01, 0.005, 0.005, 0.003, 0.003, 0.002, 0.002, 0.0015
+};
+
+// all the same
+static double young_cards_per_entry_ratio_defaults[] = {
+  1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
+};
+
+static double cost_per_entry_ms_defaults[] = {
+  0.015, 0.01, 0.01, 0.008, 0.008, 0.0055, 0.0055, 0.005
+};
+
+static double cost_per_byte_ms_defaults[] = {
+  0.00006, 0.00003, 0.00003, 0.000015, 0.000015, 0.00001, 0.00001, 0.000009
+};
+
+// these should be pretty consistent
+static double constant_other_time_ms_defaults[] = {
+  5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0
+};
+
+
+static double young_other_cost_per_region_ms_defaults[] = {
+  0.3, 0.2, 0.2, 0.15, 0.15, 0.12, 0.12, 0.1
+};
+
+static double non_young_other_cost_per_region_ms_defaults[] = {
+  1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30
+};
+
+G1Analytics::G1Analytics(const G1Predictions* predictor) :
+    _predictor(predictor),
+    _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
+    _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
+    _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
+    _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _prev_collection_pause_end_ms(0.0),
+    _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_scan_hcc_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _mixed_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _mixed_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_per_byte_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _non_young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _pending_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)) {
+
+  // Seed sequences with initial values.
+  _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
+  _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
+
+  int index = MIN2(ParallelGCThreads - 1, 7u);
+
+  _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
+  _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
+  _cost_scan_hcc_seq->add(0.0);
+  _young_cards_per_entry_ratio_seq->add(young_cards_per_entry_ratio_defaults[index]);
+  _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]);
+  _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]);
+  _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]);
+  _young_other_cost_per_region_ms_seq->add(young_other_cost_per_region_ms_defaults[index]);
+  _non_young_other_cost_per_region_ms_seq->add(non_young_other_cost_per_region_ms_defaults[index]);
+
+  // start conservatively (around 50ms is about right)
+  _concurrent_mark_remark_times_ms->add(0.05);
+  _concurrent_mark_cleanup_times_ms->add(0.20);
+}
+
+double G1Analytics::get_new_prediction(TruncatedSeq const* seq) const {
+  return _predictor->get_new_prediction(seq);
+}
+
+size_t G1Analytics::get_new_size_prediction(TruncatedSeq const* seq) const {
+  return (size_t)get_new_prediction(seq);
+}
+
+int G1Analytics::num_alloc_rate_ms() const {
+  return _alloc_rate_ms_seq->num();
+}
+
+void G1Analytics::report_concurrent_mark_remark_times_ms(double ms) {
+  _concurrent_mark_remark_times_ms->add(ms);
+}
+
+void G1Analytics::report_alloc_rate_ms(double alloc_rate) {
+  _alloc_rate_ms_seq->add(alloc_rate);
+}
+
+void G1Analytics::compute_pause_time_ratio(double interval_ms, double pause_time_ms) {
+  _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum() / interval_ms;
+  if (_recent_avg_pause_time_ratio < 0.0 ||
+      (_recent_avg_pause_time_ratio - 1.0 > 0.0)) {
+    // Clip ratio between 0.0 and 1.0, and continue. This will be fixed in
+    // CR 6902692 by redoing the manner in which the ratio is incrementally computed.
+    if (_recent_avg_pause_time_ratio < 0.0) {
+      _recent_avg_pause_time_ratio = 0.0;
+    } else {
+      assert(_recent_avg_pause_time_ratio - 1.0 > 0.0, "Ctl-point invariant");
+      _recent_avg_pause_time_ratio = 1.0;
+    }
+  }
+
+  // Compute the ratio of just this last pause time to the entire time range stored
+  // in the vectors. Comparing this pause to the entire range, rather than only the
+  // most recent interval, has the effect of smoothing over a possible transient 'burst'
+  // of more frequent pauses that don't really reflect a change in heap occupancy.
+  // This reduces the likelihood of a needless heap expansion being triggered.
+  _last_pause_time_ratio =
+    (pause_time_ms * _recent_prev_end_times_for_all_gcs_sec->num()) / interval_ms;
+}
+
+void G1Analytics::report_cost_per_card_ms(double cost_per_card_ms) {
+  _cost_per_card_ms_seq->add(cost_per_card_ms);
+}
+
+void G1Analytics::report_cost_scan_hcc(double cost_scan_hcc) {
+  _cost_scan_hcc_seq->add(cost_scan_hcc);
+}
+
+void G1Analytics::report_cost_per_entry_ms(double cost_per_entry_ms, bool last_gc_was_young) {
+  if (last_gc_was_young) {
+    _cost_per_entry_ms_seq->add(cost_per_entry_ms);
+  } else {
+    _mixed_cost_per_entry_ms_seq->add(cost_per_entry_ms);
+  }
+}
+
+void G1Analytics::report_cards_per_entry_ratio(double cards_per_entry_ratio, bool last_gc_was_young) {
+  if (last_gc_was_young) {
+    _young_cards_per_entry_ratio_seq->add(cards_per_entry_ratio);
+  } else {
+    _mixed_cards_per_entry_ratio_seq->add(cards_per_entry_ratio);
+  }
+}
+
+void G1Analytics::report_rs_length_diff(double rs_length_diff) {
+  _rs_length_diff_seq->add(rs_length_diff);
+}
+
+void G1Analytics::report_cost_per_byte_ms(double cost_per_byte_ms, bool in_marking_window) {
+  if (in_marking_window) {
+    _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
+  } else {
+    _cost_per_byte_ms_seq->add(cost_per_byte_ms);
+  }
+}
+
+void G1Analytics::report_young_other_cost_per_region_ms(double other_cost_per_region_ms) {
+  _young_other_cost_per_region_ms_seq->add(other_cost_per_region_ms);
+}
+
+void G1Analytics::report_non_young_other_cost_per_region_ms(double other_cost_per_region_ms) {
+  _non_young_other_cost_per_region_ms_seq->add(other_cost_per_region_ms);
+}
+
+void G1Analytics::report_constant_other_time_ms(double constant_other_time_ms) {
+  _constant_other_time_ms_seq->add(constant_other_time_ms);
+}
+
+void G1Analytics::report_pending_cards(double pending_cards) {
+  _pending_cards_seq->add(pending_cards);
+}
+
+void G1Analytics::report_rs_lengths(double rs_lengths) {
+  _rs_lengths_seq->add(rs_lengths);
+}
+
+size_t G1Analytics::predict_rs_length_diff() const {
+  return get_new_size_prediction(_rs_length_diff_seq);
+}
+
+double G1Analytics::predict_alloc_rate_ms() const {
+  return get_new_prediction(_alloc_rate_ms_seq);
+}
+
+double G1Analytics::predict_cost_per_card_ms() const {
+  return get_new_prediction(_cost_per_card_ms_seq);
+}
+
+double G1Analytics::predict_scan_hcc_ms() const {
+  return get_new_prediction(_cost_scan_hcc_seq);
+}
+
+double G1Analytics::predict_rs_update_time_ms(size_t pending_cards) const {
+  return pending_cards * predict_cost_per_card_ms() + predict_scan_hcc_ms();
+}
+
+double G1Analytics::predict_young_cards_per_entry_ratio() const {
+  return get_new_prediction(_young_cards_per_entry_ratio_seq);
+}
+
+double G1Analytics::predict_mixed_cards_per_entry_ratio() const {
+  if (_mixed_cards_per_entry_ratio_seq->num() < 2) {
+    return predict_young_cards_per_entry_ratio();
+  } else {
+    return get_new_prediction(_mixed_cards_per_entry_ratio_seq);
+  }
+}
+
+size_t G1Analytics::predict_card_num(size_t rs_length, bool gcs_are_young) const {
+  if (gcs_are_young) {
+    return (size_t) (rs_length * predict_young_cards_per_entry_ratio());
+  } else {
+    return (size_t) (rs_length * predict_mixed_cards_per_entry_ratio());
+  }
+}
+
+double G1Analytics::predict_rs_scan_time_ms(size_t card_num, bool gcs_are_young) const {
+  if (gcs_are_young) {
+    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+  } else {
+    return predict_mixed_rs_scan_time_ms(card_num);
+  }
+}
+
+double G1Analytics::predict_mixed_rs_scan_time_ms(size_t card_num) const {
+  if (_mixed_cost_per_entry_ms_seq->num() < 3) {
+    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+  } else {
+    return card_num * get_new_prediction(_mixed_cost_per_entry_ms_seq);
+  }
+}
+
+double G1Analytics::predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) const {
+  if (_cost_per_byte_ms_during_cm_seq->num() < 3) {
+    return (1.1 * bytes_to_copy) * get_new_prediction(_cost_per_byte_ms_seq);
+  } else {
+    return bytes_to_copy * get_new_prediction(_cost_per_byte_ms_during_cm_seq);
+  }
+}
+
+double G1Analytics::predict_object_copy_time_ms(size_t bytes_to_copy, bool during_concurrent_mark) const {
+  if (during_concurrent_mark) {
+    return predict_object_copy_time_ms_during_cm(bytes_to_copy);
+  } else {
+    return bytes_to_copy * get_new_prediction(_cost_per_byte_ms_seq);
+  }
+}
+
+double G1Analytics::predict_constant_other_time_ms() const {
+  return get_new_prediction(_constant_other_time_ms_seq);
+}
+
+double G1Analytics::predict_young_other_time_ms(size_t young_num) const {
+  return young_num * get_new_prediction(_young_other_cost_per_region_ms_seq);
+}
+
+double G1Analytics::predict_non_young_other_time_ms(size_t non_young_num) const {
+  return non_young_num * get_new_prediction(_non_young_other_cost_per_region_ms_seq);
+}
+
+double G1Analytics::predict_remark_time_ms() const {
+  return get_new_prediction(_concurrent_mark_remark_times_ms);
+}
+
+double G1Analytics::predict_cleanup_time_ms() const {
+  return get_new_prediction(_concurrent_mark_cleanup_times_ms);
+}
+
+size_t G1Analytics::predict_rs_lengths() const {
+  return get_new_size_prediction(_rs_lengths_seq);
+}
+
+size_t G1Analytics::predict_pending_cards() const {
+  return get_new_size_prediction(_pending_cards_seq);
+}
+
+double G1Analytics::last_known_gc_end_time_sec() const {
+  return _recent_prev_end_times_for_all_gcs_sec->oldest();
+}
+
+void G1Analytics::update_recent_gc_times(double end_time_sec,
+                                         double pause_time_ms) {
+  _recent_gc_times_ms->add(pause_time_ms);
+  _recent_prev_end_times_for_all_gcs_sec->add(end_time_sec);
+  _prev_collection_pause_end_ms = end_time_sec * 1000.0;
+}
+
+void G1Analytics::report_concurrent_mark_cleanup_times_ms(double ms) {
+  _concurrent_mark_cleanup_times_ms->add(ms);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1Analytics.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1MEASUREMENTS_HPP
+#define SHARE_VM_GC_G1_G1MEASUREMENTS_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class TruncatedSeq;
+class G1Predictions;
+
+class G1Analytics: public CHeapObj<mtGC> {
+  const static int TruncatedSeqLength = 10;
+  const static int NumPrevPausesForHeuristics = 10;
+  const G1Predictions* _predictor;
+
+  // These exclude marking times.
+  TruncatedSeq* _recent_gc_times_ms;
+
+  TruncatedSeq* _concurrent_mark_remark_times_ms;
+  TruncatedSeq* _concurrent_mark_cleanup_times_ms;
+
+  TruncatedSeq* _alloc_rate_ms_seq;
+  double        _prev_collection_pause_end_ms;
+
+  TruncatedSeq* _rs_length_diff_seq;
+  TruncatedSeq* _cost_per_card_ms_seq;
+  TruncatedSeq* _cost_scan_hcc_seq;
+  TruncatedSeq* _young_cards_per_entry_ratio_seq;
+  TruncatedSeq* _mixed_cards_per_entry_ratio_seq;
+  TruncatedSeq* _cost_per_entry_ms_seq;
+  TruncatedSeq* _mixed_cost_per_entry_ms_seq;
+  TruncatedSeq* _cost_per_byte_ms_seq;
+  TruncatedSeq* _constant_other_time_ms_seq;
+  TruncatedSeq* _young_other_cost_per_region_ms_seq;
+  TruncatedSeq* _non_young_other_cost_per_region_ms_seq;
+
+  TruncatedSeq* _pending_cards_seq;
+  TruncatedSeq* _rs_lengths_seq;
+
+  TruncatedSeq* _cost_per_byte_ms_during_cm_seq;
+
+  // Statistics kept per GC stoppage, pause or full.
+  TruncatedSeq* _recent_prev_end_times_for_all_gcs_sec;
+
+  // The ratio of gc time to elapsed time, computed over recent pauses,
+  // and the ratio for just the last pause.
+  double _recent_avg_pause_time_ratio;
+  double _last_pause_time_ratio;
+
+  double get_new_prediction(TruncatedSeq const* seq) const;
+  size_t get_new_size_prediction(TruncatedSeq const* seq) const;
+
+public:
+  G1Analytics(const G1Predictions* predictor);
+
+  double prev_collection_pause_end_ms() const {
+    return _prev_collection_pause_end_ms;
+  }
+
+  double recent_avg_pause_time_ratio() const {
+    return _recent_avg_pause_time_ratio;
+  }
+
+  double last_pause_time_ratio() const {
+    return _last_pause_time_ratio;
+  }
+
+  uint number_of_recorded_pause_times() const {
+    return NumPrevPausesForHeuristics;
+  }
+
+  void append_prev_collection_pause_end_ms(double ms) {
+    _prev_collection_pause_end_ms += ms;
+  }
+
+  void report_concurrent_mark_remark_times_ms(double ms);
+  void report_concurrent_mark_cleanup_times_ms(double ms);
+  void report_alloc_rate_ms(double alloc_rate);
+  void report_cost_per_card_ms(double cost_per_card_ms);
+  void report_cost_scan_hcc(double cost_scan_hcc);
+  void report_cost_per_entry_ms(double cost_per_entry_ms, bool last_gc_was_young);
+  void report_cards_per_entry_ratio(double cards_per_entry_ratio, bool last_gc_was_young);
+  void report_rs_length_diff(double rs_length_diff);
+  void report_cost_per_byte_ms(double cost_per_byte_ms, bool in_marking_window);
+  void report_young_other_cost_per_region_ms(double other_cost_per_region_ms);
+  void report_non_young_other_cost_per_region_ms(double other_cost_per_region_ms);
+  void report_constant_other_time_ms(double constant_other_time_ms);
+  void report_pending_cards(double pending_cards);
+  void report_rs_lengths(double rs_lengths);
+
+  size_t predict_rs_length_diff() const;
+
+  double predict_alloc_rate_ms() const;
+  int num_alloc_rate_ms() const;
+
+  double predict_cost_per_card_ms() const;
+
+  double predict_scan_hcc_ms() const;
+
+  double predict_rs_update_time_ms(size_t pending_cards) const;
+
+  double predict_young_cards_per_entry_ratio() const;
+
+  double predict_mixed_cards_per_entry_ratio() const;
+
+  size_t predict_card_num(size_t rs_length, bool gcs_are_young) const;
+
+  double predict_rs_scan_time_ms(size_t card_num, bool gcs_are_young) const;
+
+  double predict_mixed_rs_scan_time_ms(size_t card_num) const;
+
+  double predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) const;
+
+  double predict_object_copy_time_ms(size_t bytes_to_copy, bool during_concurrent_mark) const;
+
+  double predict_constant_other_time_ms() const;
+
+  double predict_young_other_time_ms(size_t young_num) const;
+
+  double predict_non_young_other_time_ms(size_t non_young_num) const;
+
+  double predict_remark_time_ms() const;
+
+  double predict_cleanup_time_ms() const;
+
+  size_t predict_rs_lengths() const;
+  size_t predict_pending_cards() const;
+
+  // Add a new GC of the given duration and end time to the record.
+  void update_recent_gc_times(double end_time_sec, double elapsed_ms);
+  void compute_pause_time_ratio(double interval_ms, double pause_time_ms);
+
+  double last_known_gc_end_time_sec() const;
+};
+
+#endif // SHARE_VM_GC_G1_G1MEASUREMENTS_HPP
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -34,10 +34,12 @@
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1Allocator.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1CollectionSet.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
+#include "gc/g1/g1HeapSizingPolicy.hpp"
 #include "gc/g1/g1HeapTransition.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1MarkSweep.hpp"
@@ -67,6 +69,7 @@
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/init.hpp"
@@ -566,7 +569,7 @@
     // Give a warning if we seem to be looping forever.
     if ((QueuedAllocationWarningCount > 0) &&
         (try_count % QueuedAllocationWarningCount == 0)) {
-      warning("G1CollectedHeap::mem_allocate retries %d times", try_count);
+      log_warning(gc)("G1CollectedHeap::mem_allocate retries %d times", try_count);
     }
   }
 
@@ -675,8 +678,8 @@
     // Give a warning if we seem to be looping forever.
     if ((QueuedAllocationWarningCount > 0) &&
         (try_count % QueuedAllocationWarningCount == 0)) {
-      warning("G1CollectedHeap::attempt_allocation_slow() "
-              "retries %d times", try_count);
+      log_warning(gc)("G1CollectedHeap::attempt_allocation_slow() "
+                      "retries %d times", try_count);
     }
   }
 
@@ -1091,8 +1094,8 @@
 
     if ((QueuedAllocationWarningCount > 0) &&
         (try_count % QueuedAllocationWarningCount == 0)) {
-      warning("G1CollectedHeap::attempt_allocation_humongous() "
-              "retries %d times", try_count);
+      log_warning(gc)("G1CollectedHeap::attempt_allocation_humongous() "
+                      "retries %d times", try_count);
     }
   }
 
@@ -1228,6 +1231,7 @@
   ResourceMark rm;
 
   print_heap_before_gc();
+  print_heap_regions();
   trace_heap_before_gc(gc_tracer);
 
   size_t metadata_prev_used = MetaspaceAux::used_bytes();
@@ -1302,9 +1306,9 @@
       // set between the last GC or pause and now. We need to clear the
       // incremental collection set and then start rebuilding it afresh
       // after this full GC.
-      abandon_collection_set(g1_policy()->inc_cset_head());
-      g1_policy()->clear_incremental_cset();
-      g1_policy()->stop_incremental_cset_building();
+      abandon_collection_set(collection_set()->inc_head());
+      collection_set()->clear_incremental();
+      collection_set()->stop_incremental_building();
 
       tear_down_region_sets(false /* free_list_only */);
       collector_state()->set_gcs_are_young(true);
@@ -1421,13 +1425,13 @@
       // the full GC has compacted objects and updated TAMS but not updated
       // the prev bitmap.
       if (G1VerifyBitmaps) {
-        ((G1CMBitMap*) concurrent_mark()->prevMarkBitMap())->clearAll();
+        _cm->clear_prev_bitmap(workers());
       }
       _verifier->check_bitmaps("Full GC End");
 
       // Start a new incremental collection set for the next pause
-      assert(g1_policy()->collection_set() == NULL, "must be");
-      g1_policy()->start_incremental_cset_building();
+      assert(collection_set()->head() == NULL, "must be");
+      collection_set()->start_incremental_building();
 
       clear_cset_fast_test();
 
@@ -1446,6 +1450,7 @@
       heap_transition.print();
 
       print_heap_after_gc();
+      print_heap_regions();
       trace_heap_after_gc(gc_tracer);
 
       post_full_gc_dump(gc_timer);
@@ -1741,6 +1746,7 @@
 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
   CollectedHeap(),
   _g1_policy(policy_),
+  _collection_set(this),
   _dirty_card_queue_set(false),
   _is_alive_closure_cm(this),
   _is_alive_closure_stw(this),
@@ -1765,15 +1771,12 @@
   _expand_heap_after_alloc_failure(true),
   _old_marking_cycles_started(0),
   _old_marking_cycles_completed(0),
-  _heap_summary_sent(false),
   _in_cset_fast_test(),
   _dirty_cards_region_list(NULL),
   _worker_cset_start_region(NULL),
   _worker_cset_start_region_time_stamp(NULL),
   _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
-  _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
-  _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
-  _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
+  _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()) {
 
   _workers = new WorkGang("GC Thread", ParallelGCThreads,
                           /* are_GC_task_threads */true,
@@ -1782,6 +1785,9 @@
   _verifier = new G1HeapVerifier(this);
 
   _allocator = G1Allocator::create_allocator(this);
+
+  _heap_sizing_policy = G1HeapSizingPolicy::create(this, _g1_policy->analytics());
+
   _humongous_object_threshold_in_words = humongous_threshold_for(HeapRegion::GrainWords);
 
   // Override the default _filler_array_max_size so that no humongous filler
@@ -2314,52 +2320,6 @@
   FullGCCount_lock->notify_all();
 }
 
-void G1CollectedHeap::register_concurrent_cycle_start(const Ticks& start_time) {
-  GCIdMarkAndRestore conc_gc_id_mark;
-  collector_state()->set_concurrent_cycle_started(true);
-  _gc_timer_cm->register_gc_start(start_time);
-
-  _gc_tracer_cm->report_gc_start(gc_cause(), _gc_timer_cm->gc_start());
-  trace_heap_before_gc(_gc_tracer_cm);
-  _cmThread->set_gc_id(GCId::current());
-}
-
-void G1CollectedHeap::register_concurrent_cycle_end() {
-  if (collector_state()->concurrent_cycle_started()) {
-    GCIdMarkAndRestore conc_gc_id_mark(_cmThread->gc_id());
-    if (_cm->has_aborted()) {
-      _gc_tracer_cm->report_concurrent_mode_failure();
-
-      // ConcurrentGCTimer will be ended as well.
-      _cm->register_concurrent_gc_end_and_stop_timer();
-    } else {
-      _gc_timer_cm->register_gc_end();
-    }
-
-    _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
-
-    // Clear state variables to prepare for the next concurrent cycle.
-    collector_state()->set_concurrent_cycle_started(false);
-    _heap_summary_sent = false;
-  }
-}
-
-void G1CollectedHeap::trace_heap_after_concurrent_cycle() {
-  if (collector_state()->concurrent_cycle_started()) {
-    // This function can be called when:
-    //  the cleanup pause is run
-    //  the concurrent cycle is aborted before the cleanup pause.
-    //  the concurrent cycle is aborted after the cleanup pause,
-    //   but before the concurrent cycle end has been registered.
-    // Make sure that we only send the heap information once.
-    if (!_heap_summary_sent) {
-      GCIdMarkAndRestore conc_gc_id_mark(_cmThread->gc_id());
-      trace_heap_after_gc(_gc_tracer_cm);
-      _heap_summary_sent = true;
-    }
-  }
-}
-
 void G1CollectedHeap::collect(GCCause::Cause cause) {
   assert_heap_not_locked();
 
@@ -2545,8 +2505,8 @@
   //          p threads
   // Then thread t will start at region floor ((t * n) / p)
 
-  result = g1_policy()->collection_set();
-  uint cs_size = g1_policy()->cset_region_length();
+  result = collection_set()->head();
+  uint cs_size = collection_set()->region_length();
   uint active_workers = workers()->active_workers();
 
   uint end_ind   = (cs_size * worker_i) / active_workers;
@@ -2577,7 +2537,7 @@
 }
 
 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) {
-  HeapRegion* r = g1_policy()->collection_set();
+  HeapRegion* r = collection_set()->head();
   while (r != NULL) {
     HeapRegion* next = r->next_in_collection_set();
     if (cl->doHeapRegion(r)) {
@@ -2606,7 +2566,7 @@
     }
     cur = next;
   }
-  cur = g1_policy()->collection_set();
+  cur = collection_set()->head();
   while (cur != r) {
     HeapRegion* next = cur->next_in_collection_set();
     if (cl->doHeapRegion(cur) && false) {
@@ -2716,6 +2676,14 @@
   return false; // keep some compilers happy
 }
 
+void G1CollectedHeap::print_heap_regions() const {
+  Log(gc, heap, region) log;
+  if (log.is_trace()) {
+    ResourceMark rm;
+    print_regions_on(log.trace_stream());
+  }
+}
+
 void G1CollectedHeap::print_on(outputStream* st) const {
   st->print(" %-20s", "garbage-first heap");
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
@@ -2729,18 +2697,14 @@
   uint young_regions = _young_list->length();
   st->print("%u young (" SIZE_FORMAT "K), ", young_regions,
             (size_t) young_regions * HeapRegion::GrainBytes / K);
-  uint survivor_regions = g1_policy()->recorded_survivor_regions();
+  uint survivor_regions = _young_list->survivor_length();
   st->print("%u survivors (" SIZE_FORMAT "K)", survivor_regions,
             (size_t) survivor_regions * HeapRegion::GrainBytes / K);
   st->cr();
   MetaspaceAux::print_on(st);
 }
 
-void G1CollectedHeap::print_extended_on(outputStream* st) const {
-  print_on(st);
-
-  // Print the per-region information.
-  st->cr();
+void G1CollectedHeap::print_regions_on(outputStream* st) const {
   st->print_cr("Heap Regions: E=young(eden), S=young(survivor), O=old, "
                "HS=humongous(starts), HC=humongous(continues), "
                "CS=collection set, F=free, A=archive, TS=gc time stamp, "
@@ -2750,6 +2714,13 @@
   heap_region_iterate(&blk);
 }
 
+void G1CollectedHeap::print_extended_on(outputStream* st) const {
+  print_on(st);
+
+  // Print the per-region information.
+  print_regions_on(st);
+}
+
 void G1CollectedHeap::print_on_error(outputStream* st) const {
   this->CollectedHeap::print_on_error(st);
 
@@ -2839,12 +2810,14 @@
 
   size_t eden_used_bytes = young_list->eden_used_bytes();
   size_t survivor_used_bytes = young_list->survivor_used_bytes();
+  size_t heap_used = Heap_lock->owned_by_self() ? used() : used_unlocked();
 
   size_t eden_capacity_bytes =
     (g1_policy()->young_list_target_length() * HeapRegion::GrainBytes) - survivor_used_bytes;
 
   VirtualSpaceSummary heap_summary = create_heap_space_summary();
-  return G1HeapSummary(heap_summary, used(), eden_used_bytes, eden_capacity_bytes, survivor_used_bytes, num_regions());
+  return G1HeapSummary(heap_summary, heap_used, eden_used_bytes,
+                       eden_capacity_bytes, survivor_used_bytes, num_regions());
 }
 
 G1EvacSummary G1CollectedHeap::create_g1_evac_summary(G1EvacStats* stats) {
@@ -2862,7 +2835,6 @@
   gc_tracer->report_metaspace_summary(when, metaspace_summary);
 }
 
-
 G1CollectedHeap* G1CollectedHeap::heap() {
   CollectedHeap* heap = Universe::heap();
   assert(heap != NULL, "Uninitialized access to G1CollectedHeap::heap()");
@@ -3138,10 +3110,10 @@
 }
 
 void G1CollectedHeap::print_taskqueue_stats() const {
-  if (!log_develop_is_enabled(Trace, gc, task, stats)) {
+  if (!log_is_enabled(Trace, gc, task, stats)) {
     return;
   }
-  LogHandle(gc, task, stats) log;
+  Log(gc, task, stats) log;
   ResourceMark rm;
   outputStream* st = log.trace_stream();
 
@@ -3201,15 +3173,19 @@
   wait_for_root_region_scanning();
 
   print_heap_before_gc();
+  print_heap_regions();
   trace_heap_before_gc(_gc_tracer_stw);
 
   _verifier->verify_region_sets_optional();
   _verifier->verify_dirty_young_regions();
 
-  // This call will decide whether this pause is an initial-mark
-  // pause. If it is, during_initial_mark_pause() will return true
-  // for the duration of this pause.
-  g1_policy()->decide_on_conc_mark_initiation();
+  // We should not be doing initial mark unless the conc mark thread is running
+  if (!_cmThread->should_terminate()) {
+    // This call will decide whether this pause is an initial-mark
+    // pause. If it is, during_initial_mark_pause() will return true
+    // for the duration of this pause.
+    g1_policy()->decide_on_conc_mark_initiation();
+  }
 
   // We do not allow initial-mark to be piggy-backed on a mixed GC.
   assert(!collector_state()->during_initial_mark_pause() ||
@@ -3231,7 +3207,7 @@
       // We are about to start a marking cycle, so we increment the
       // full collection counter.
       increment_old_marking_cycles_started();
-      register_concurrent_cycle_start(_gc_timer_stw->gc_start());
+      _cm->gc_tracer_cm()->set_gc_cause(gc_cause());
     }
 
     _gc_tracer_stw->report_yc_type(collector_state()->yc_type());
@@ -3253,7 +3229,7 @@
                                                                   Threads::number_of_non_daemon_threads());
     workers()->set_active_workers(active_workers);
 
-    g1_policy()->note_gc_start(active_workers);
+    g1_policy()->note_gc_start();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
     TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -3336,10 +3312,9 @@
           concurrent_mark()->checkpointRootsInitialPre();
         }
 
-        double time_remaining_ms = g1_policy()->finalize_young_cset_part(target_pause_time_ms);
-        g1_policy()->finalize_old_cset_part(time_remaining_ms);
-
-        evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
+        g1_policy()->finalize_collection_set(target_pause_time_ms);
+
+        evacuation_info.set_collectionset_regions(collection_set()->region_length());
 
         // Make sure the remembered sets are up to date. This needs to be
         // done before register_humongous_regions_with_cset(), because the
@@ -3358,7 +3333,7 @@
         _cm->verify_no_cset_oops();
 
         if (_hr_printer.is_active()) {
-          HeapRegion* hr = g1_policy()->collection_set();
+          HeapRegion* hr = collection_set()->head();
           while (hr != NULL) {
             _hr_printer.cset(hr);
             hr = hr->next_in_collection_set();
@@ -3373,7 +3348,7 @@
         // Initialize the GC alloc regions.
         _allocator->init_gc_alloc_regions(evacuation_info);
 
-        G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length());
+        G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), collection_set()->young_region_length());
         pre_evacuate_collection_set();
 
         // Actually do the work...
@@ -3382,18 +3357,18 @@
         post_evacuate_collection_set(evacuation_info, &per_thread_states);
 
         const size_t* surviving_young_words = per_thread_states.surviving_young_words();
-        free_collection_set(g1_policy()->collection_set(), evacuation_info, surviving_young_words);
+        free_collection_set(collection_set()->head(), evacuation_info, surviving_young_words);
 
         eagerly_reclaim_humongous_regions();
 
-        g1_policy()->clear_collection_set();
+        collection_set()->clear_head();
 
         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();
+        collection_set()->start_incremental_building();
 
         clear_cset_fast_test();
 
@@ -3404,10 +3379,6 @@
         assert(check_young_list_empty(false /* check_heap */),
           "young list should be empty");
 
-        g1_policy()->record_survivor_regions(_young_list->survivor_length(),
-                                             _young_list->first_survivor_region(),
-                                             _young_list->last_survivor_region());
-
         _young_list->reset_auxilary_lists();
 
         if (evacuation_failed()) {
@@ -3442,7 +3413,7 @@
         _allocator->init_mutator_alloc_region();
 
         {
-          size_t expand_bytes = g1_policy()->expansion_amount();
+          size_t expand_bytes = _heap_sizing_policy->expansion_amount();
           if (expand_bytes > 0) {
             size_t bytes_before = capacity();
             // No need for an ergo logging here,
@@ -3468,7 +3439,7 @@
         size_t total_cards_scanned = per_thread_states.total_cards_scanned();
         g1_policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned, heap_used_bytes_before_gc);
 
-        evacuation_info.set_collectionset_used_before(g1_policy()->collection_set_bytes_used_before());
+        evacuation_info.set_collectionset_used_before(collection_set()->bytes_used_before());
         evacuation_info.set_bytes_copied(g1_policy()->bytes_copied_during_gc());
 
         MemoryService::track_memory_usage();
@@ -3538,6 +3509,7 @@
     TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
 
     print_heap_after_gc();
+    print_heap_regions();
     trace_heap_after_gc(_gc_tracer_stw);
 
     // We must call G1MonitoringSupport::update_sizes() in the same scoping level
@@ -3776,11 +3748,12 @@
               "claim value %d after unlink less than initial symbol table size %d",
               SymbolTable::parallel_claimed_index(), _initial_symbol_table_size);
 
-    log_debug(gc, stringdedup)("Cleaned string and symbol table, "
-                               "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
-                               "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
-                               strings_processed(), strings_removed(),
-                               symbols_processed(), symbols_removed());
+    log_info(gc, stringtable)(
+        "Cleaned string and symbol table, "
+        "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
+        "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
+        strings_processed(), strings_removed(),
+        symbols_processed(), symbols_removed());
   }
 
   void work(uint worker_id) {
@@ -4083,14 +4056,10 @@
 
 void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
                                                      bool process_strings, bool process_symbols) {
-  {
+  { // Timing scope
     G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
     workers()->run_task(&g1_unlink_task);
   }
-
-  if (G1StringDedup::is_enabled()) {
-    G1StringDedup::unlink(is_alive);
-  }
 }
 
 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
@@ -4279,7 +4248,7 @@
     _workers(workers),
     _active_workers(n_workers)
   {
-    assert(n_workers > 0, "shouldn't call this otherwise");
+    g1h->ref_processor_stw()->set_active_mt_degree(n_workers);
   }
 
   // Executes the given task using concurrent marking worker threads.
@@ -4400,7 +4369,9 @@
     _queues(task_queues),
     _terminator(workers, _queues),
     _n_workers(workers)
-  { }
+  {
+    g1h->ref_processor_cm()->set_active_mt_degree(workers);
+  }
 
   void work(uint worker_id) {
     G1GCParPhaseTimesTracker x(_g1h->g1_policy()->phase_times(), G1GCPhaseTimes::PreserveCMReferents, worker_id);
@@ -4543,8 +4514,9 @@
     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");
+    assert(no_of_gc_workers <= rp->max_num_q(),
+           "Mismatch between the number of GC workers %u and the maximum number of Reference process queues %u",
+           no_of_gc_workers,  rp->max_num_q());
 
     G1STWRefProcTaskExecutor par_task_executor(this, per_thread_states, workers(), _task_queues, no_of_gc_workers);
     stats = rp->process_discovered_references(&is_alive,
@@ -4580,8 +4552,9 @@
 
     uint n_workers = workers()->active_workers();
 
-    assert(rp->num_q() == n_workers, "sanity");
-    assert(n_workers <= rp->max_num_q(), "sanity");
+    assert(n_workers <= rp->max_num_q(),
+           "Mismatch between the number of GC workers %u and the maximum number of Reference process queues %u",
+           n_workers,  rp->max_num_q());
 
     G1STWRefProcTaskExecutor par_task_executor(this, per_thread_states, workers(), _task_queues, n_workers);
     rp->enqueue_discovered_references(&par_task_executor);
@@ -4909,7 +4882,7 @@
     if (cur->is_young()) {
       int index = cur->young_index_in_cset();
       assert(index != -1, "invariant");
-      assert((uint) index < policy->young_cset_region_length(), "invariant");
+      assert((uint) index < collection_set()->young_region_length(), "invariant");
       size_t words_survived = surviving_young_words[index];
       cur->record_surv_words_in_group(words_survived);
 
@@ -5382,7 +5355,7 @@
   assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
   assert(alloc_region->is_eden(), "all mutator alloc regions should be eden");
 
-  g1_policy()->add_region_to_incremental_cset_lhs(alloc_region);
+  collection_set()->add_eden_region(alloc_region);
   increase_used(allocated_bytes);
   _hr_printer.retire(alloc_region);
   // We update the eden sizes here, when the region is retired,
@@ -5393,33 +5366,43 @@
 
 // Methods for the GC alloc regions
 
-HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
-                                                 uint count,
-                                                 InCSetState dest) {
+bool G1CollectedHeap::has_more_regions(InCSetState dest) {
+  if (dest.is_old()) {
+    return true;
+  } else {
+    return young_list()->survivor_length() < g1_policy()->max_survivor_regions();
+  }
+}
+
+HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, InCSetState dest) {
   assert(FreeList_lock->owned_by_self(), "pre-condition");
 
-  if (count < g1_policy()->max_regions(dest)) {
-    const bool is_survivor = (dest.is_young());
-    HeapRegion* new_alloc_region = new_region(word_size,
-                                              !is_survivor,
-                                              true /* do_expand */);
-    if (new_alloc_region != NULL) {
-      // We really only need to do this for old regions given that we
-      // should never scan survivors. But it doesn't hurt to do it
-      // for survivors too.
-      new_alloc_region->record_timestamp();
-      if (is_survivor) {
-        new_alloc_region->set_survivor();
-        _verifier->check_bitmaps("Survivor Region Allocation", new_alloc_region);
-      } else {
-        new_alloc_region->set_old();
-        _verifier->check_bitmaps("Old Region Allocation", new_alloc_region);
-      }
-      _hr_printer.alloc(new_alloc_region);
-      bool during_im = collector_state()->during_initial_mark_pause();
-      new_alloc_region->note_start_of_copying(during_im);
-      return new_alloc_region;
+  if (!has_more_regions(dest)) {
+    return NULL;
+  }
+
+  const bool is_survivor = dest.is_young();
+
+  HeapRegion* new_alloc_region = new_region(word_size,
+                                            !is_survivor,
+                                            true /* do_expand */);
+  if (new_alloc_region != NULL) {
+    // We really only need to do this for old regions given that we
+    // should never scan survivors. But it doesn't hurt to do it
+    // for survivors too.
+    new_alloc_region->record_timestamp();
+    if (is_survivor) {
+      new_alloc_region->set_survivor();
+      young_list()->add_survivor_region(new_alloc_region);
+      _verifier->check_bitmaps("Survivor Region Allocation", new_alloc_region);
+    } else {
+      new_alloc_region->set_old();
+      _verifier->check_bitmaps("Old Region Allocation", new_alloc_region);
     }
+    _hr_printer.alloc(new_alloc_region);
+    bool during_im = collector_state()->during_initial_mark_pause();
+    new_alloc_region->note_start_of_copying(during_im);
+    return new_alloc_region;
   }
   return NULL;
 }
@@ -5430,9 +5413,7 @@
   bool during_im = collector_state()->during_initial_mark_pause();
   alloc_region->note_end_of_copying(during_im);
   g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
-  if (dest.is_young()) {
-    young_list()->add_survivor_region(alloc_region);
-  } else {
+  if (dest.is_old()) {
     _old_set.add(alloc_region);
   }
   _hr_printer.retire(alloc_region);
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Mon Apr 04 13:40:18 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Thu Apr 07 09:47:48 2016 -0700
@@ -28,6 +28,7 @@
 #include "gc/g1/evacuationInfo.hpp"
 #include "gc/g1/g1AllocationContext.hpp"
 #include "gc/g1/g1BiasedArray.hpp"
+#include "gc/g1/g1CollectionSet.hpp"
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1ConcurrentMark.hpp"
 #include "gc/g1/g1HRPrinter.hpp"
@@ -65,17 +66,16 @@
 class SpaceClosure;
 class CompactibleSpaceClosure;
 class Space;
+class G1CollectionSet;
 class G1CollectorPolicy;
 class G1RemSet;
 class HeapRegionRemSetIterator;
 class G1ConcurrentMark;
 class ConcurrentMarkThread;
 class ConcurrentG1Refine;
-class ConcurrentGCTimer;
 class GenerationCounters;
 class STWGCTimer;
 class G1NewTracer;
-class G1OldTracer;
 class EvacuationFailedInfo;
 class nmethod;
 class Ticks;
@@ -83,6 +83,7 @@
 class G1Allocator;
 class G1ArchiveAllocator;
 class G1HeapVerifier;
+class G1HeapSizingPolicy;
 
 typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
@@ -268,8 +269,6 @@
   // concurrent cycles) we have completed.
   volatile uint _old_marking_cycles_completed;
 
-  bool _heap_summary_sent;
-
   // This is a non-product method that is helpful for testing. It is
   // called at the end of a GC and artificially expands the heap by
   // allocating a number of dead regions. This way we can induce very
@@ -362,6 +361,9 @@
 
   // The current policy object for the collector.
   G1CollectorPolicy* _g1_policy;
+  G1HeapSizingPolicy* _heap_sizing_policy;
+
+  G1CollectionSet _collection_set;
 
   // This is the second level of trying to allocate a new region. If
   // new_region() didn't find a region on the free_list, this call will
@@ -469,8 +471,8 @@
                                    size_t allocated_bytes);
 
   // For GC alloc regions.
-  HeapRegion* new_gc_alloc_region(size_t word_size, uint count,
-                                  InCSetState dest);
+  bool has_more_regions(InCSetState dest);
+  HeapRegion* new_gc_alloc_region(size_t word_size, InCSetState dest);
   void retire_gc_alloc_region(HeapRegion* alloc_region,
                               size_t allocated_bytes, InCSetState dest);
 
@@ -618,10 +620,6 @@
     return _old_marking_cycles_completed;
   }
 
-  void register_concurrent_cycle_start(const Ticks& start_time);
-  void register_concurrent_cycle_end();
-  void trace_heap_after_concurrent_cycle();
-
   G1HRPrinter* hr_printer() { return &_hr_printer; }
 
   // Allocates a new heap region instance.
@@ -896,9 +894,7 @@
   ReferenceProcessor* _ref_processor_stw;
 
   STWGCTimer* _gc_timer_stw;
-  ConcurrentGCTimer* _gc_timer_cm;
 
-  G1OldTracer* _gc_tracer_cm;
   G1NewTracer* _gc_tracer_stw;
 
   // During reference object discovery, the _is_alive_non_header
@@ -985,6 +981,9 @@
   // The current policy object for the collector.
   G1CollectorPolicy* g1_policy() const { return _g1_policy; }
 
+  const G1CollectionSet* collection_set() const { return &_collection_set; }
+  G1CollectionSet* collection_set() { return &_collection_set; }
+
   virtual CollectorPolicy* collector_policy() const;
 
   // Adaptive size policy.  No such thing for g1.
@@ -1029,9 +1028,6 @@
   // The Concurrent Marking reference processor...
   ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }
 
-  ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; }
-  G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; }
-
   virtual size_t capacity() const;
   virtual size_t used() const;
   // This should be called when we're not holding the heap lock. The
@@ -1285,6 +1281,12 @@
     return true;
   }
 
+  // The reference pending list lock is acquired from from the
+  // ConcurrentMarkThread.
+  virtual bool needs_reference_pending_list_locker_thread() const {
+    return true;
+  }
+
   inline bool is_in_young(const oop obj);
 
   virtual bool is_scavengable(const void* addr);
@@ -1463,7 +1465,11 @@
   G1EvacSummary create_g1_evac_summary(G1EvacStats* stats);
 
   // Printing
+private:
+  void print_heap_regions() const;
+  void print_regions_on(outputStream* st) const;
 
+public:
   virtual void print_on(outputStream* st) const;
   virtual void print_extended_on(outputStream* st) const;
   virtual void print_on_error(outputStream* st) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectionSet.cpp	Thu Apr 07 09:47:48 2016 -0700
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1CollectionSet.hpp"
+#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1CollectorState.hpp"
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/heapRegionSet.hpp"
+#include "utilities/debug.hpp"
+
+G1CollectorState* G1CollectionSet::collector_state() {
+  return _g1->collector_state();
+}
+
+G1GCPhaseTimes* G1CollectionSet::phase_times() {
+  return _policy->phase_times();
+}
+
+CollectionSetChooser* G1CollectionSet::cset_chooser() {
+  return _cset_chooser;
+}
+
+double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
+  return _policy->predict_region_elapsed_time_ms(hr, collector_state()->gcs_are_young());
+}
+
+
+G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h) :
+  _g1(g1h),
+  _policy(NULL),
+  _cset_chooser(new CollectionSetChooser()),
+  _eden_region_length(0),
+  _survivor_region_length(0),
+  _old_region_length(0),
+
+  _head(NULL),
+  _bytes_used_before(0),
+  _recorded_rs_lengths(0),
+  // Incremental CSet attributes
+  _inc_build_state(Inactive),
+  _inc_head(NULL),
+  _inc_tail(NULL),
+  _inc_bytes_used_before(0),
+  _inc_recorded_rs_lengths(0),
+  _inc_recorded_rs_lengths_diffs(0),
+  _inc_predicted_elapsed_time_ms(0.0),
+  _inc_predicted_elapsed_time_ms_diffs(0.0) {}
+
+G1CollectionSet::~G1CollectionSet() {
+  delete _cset_chooser;
+}
+
+void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
+                                          uint survivor_cset_region_length) {
+  _eden_region_length     = eden_cset_region_length;
+  _survivor_region_length = survivor_cset_region_length;
+  _old_region_length      = 0;
+}
+
+void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
+  _recorded_rs_lengths = rs_lengths;
+}
+
+// Add the heap region at the head of the non-incremental collection set
+void G1CollectionSet::add_old_region(HeapRegion* hr) {
+  assert(_inc_build_state == Active, "Precondition");
+  assert(hr->is_old(), "the region should be old");
+
+  assert(!hr->in_collection_set(), "should not already be in the CSet");
+  _g1->register_old_region_with_cset(hr);
+  hr->set_next_in_collection_set(_head);
+  _head = hr;
+  _bytes_used_before += hr->used();
+  size_t rs_length = hr->rem_set()->occupied();