changeset 29770:6415d011ad02

Merge
author duke
date Wed, 05 Jul 2017 20:27:20 +0200
parents 80e73beff5ba c6ba5f375336
children b9220497eb43
files hotspot/src/share/vm/memory/specialized_oop_closures.cpp jdk/make/Makefile jdk/src/java.base/unix/conf/arm/jvm.cfg jdk/src/java.base/unix/conf/ppc/jvm.cfg jdk/test/jdk/lambda/FDTest.java jdk/test/jdk/lambda/LambdaTranslationInInterface.java jdk/test/jdk/lambda/LambdaTranslationInnerConstructor.java jdk/test/jdk/lambda/MethodReferenceTestFDCCE.java jdk/test/jdk/lambda/MethodReferenceTestInnerDefault.java jdk/test/jdk/lambda/MethodReferenceTestInnerInstance.java jdk/test/jdk/lambda/MethodReferenceTestInnerVarArgsThis.java jdk/test/jdk/lambda/MethodReferenceTestInstance.java jdk/test/jdk/lambda/MethodReferenceTestKinds.java jdk/test/jdk/lambda/MethodReferenceTestNew.java jdk/test/jdk/lambda/MethodReferenceTestNewInner.java jdk/test/jdk/lambda/MethodReferenceTestSueCase1.java jdk/test/jdk/lambda/MethodReferenceTestSueCase2.java jdk/test/jdk/lambda/MethodReferenceTestSueCase4.java jdk/test/jdk/lambda/MethodReferenceTestSuper.java jdk/test/jdk/lambda/MethodReferenceTestSuperDefault.java jdk/test/jdk/lambda/MethodReferenceTestTypeConversion.java jdk/test/jdk/lambda/MethodReferenceTestVarArgs.java jdk/test/jdk/lambda/MethodReferenceTestVarArgsExt.java jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuper.java jdk/test/jdk/lambda/MethodReferenceTestVarArgsSuperDefault.java jdk/test/jdk/lambda/MethodReferenceTestVarArgsThis.java jdk/test/jdk/lambda/shapegen/ClassCase.java jdk/test/jdk/lambda/shapegen/Hierarchy.java jdk/test/jdk/lambda/shapegen/HierarchyGenerator.java jdk/test/jdk/lambda/shapegen/Rule.java jdk/test/jdk/lambda/shapegen/RuleGroup.java jdk/test/jdk/lambda/shapegen/TTNode.java jdk/test/jdk/lambda/shapegen/TTParser.java jdk/test/jdk/lambda/shapegen/TTShape.java make/MakeHelpers.gmk nashorn/make/Makefile nashorn/test/src/jdk/internal/dynalink/beans/CallerSensitiveTest.java nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java nashorn/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java nashorn/test/src/jdk/nashorn/api/javaaccess/Person.java nashorn/test/src/jdk/nashorn/api/javaaccess/SharedObject.java nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java nashorn/test/src/jdk/nashorn/api/scripting/InvocableTest.java nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java nashorn/test/src/jdk/nashorn/api/scripting/VariableArityTestInterface.java nashorn/test/src/jdk/nashorn/api/scripting/Window.java nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js nashorn/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js nashorn/test/src/jdk/nashorn/api/scripting/resources/witheval.js nashorn/test/src/jdk/nashorn/api/tree/ParseAPITest.java nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java nashorn/test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java nashorn/test/src/jdk/nashorn/internal/runtime/ConsStringTest.java nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java nashorn/test/src/jdk/nashorn/internal/runtime/ExceptionsNotSerializable.java nashorn/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java nashorn/test/src/jdk/nashorn/internal/runtime/LexicalBindingTest.java nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java nashorn/test/src/jdk/nashorn/internal/runtime/SourceTest.java nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java nashorn/test/src/jdk/nashorn/internal/runtime/resources/load_test.js
diffstat 866 files changed, 18293 insertions(+), 17328 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Wed Apr 08 13:12:48 2015 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 20:27:20 2017 +0200
@@ -300,3 +300,4 @@
 0c37a832458f0e0b7d2a3f1a6f69aeae311aeb18 jdk9-b55
 eb7febe45865ba6b81f2ea68082262d0708a0b22 jdk9-b56
 f25ee9f62427a9ba27418e5531a89754791a305b jdk9-b57
+6e78dd9b121037719a065fe8fb25b936babdfecb jdk9-b58
--- a/Makefile	Wed Apr 08 13:12:48 2015 -0700
+++ b/Makefile	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,200 +23,42 @@
 # questions.
 #
 
-# This must be the first rule
-default:
+###
+### This file is just a very small wrapper needed to run the real make/Init.gmk.
+### It also performs some sanity checks on make.
+###
 
-# Inclusion of this pseudo-target will cause make to execute this file
-# serially, regardless of -j. Recursively called makefiles will not be
-# affected, however. This is required for correct dependency management.
-.NOTPARALLEL:
+# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU Make.
+# /usr/ccs/bin/make lacks basically every other flow control mechanism.
+.TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU Make/gmake, this is a requirement. Check your path. 1>&2 && exit 1
 
-# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU make.
-# /usr/ccs/bin/make lacks basically every other flow control mechanism.
-.TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU make/gmake, this is a requirement. Check your path. 1>&2 && exit 1
+# The .FEATURES variable is likely to be unique for GNU Make.
+ifeq ($(.FEATURES), )
+  $(info Error: '$(MAKE)' does not seem to be GNU Make, which is a requirement.)
+  $(info Check your path, or upgrade to GNU Make 3.81 or newer.)
+  $(error Cannot continue)
+endif
 
-# Assume we have GNU make, but check version.
+# Assume we have GNU Make, but check version.
 ifeq ($(strip $(foreach v, 3.81% 3.82% 4.%, $(filter $v, $(MAKE_VERSION)))), )
-  $(error This version of GNU Make is too low ($(MAKE_VERSION)). Check your path, or upgrade to 3.81 or newer.)
+  $(info Error: This version of GNU Make is too low ($(MAKE_VERSION)).)
+  $(info Check your path, or upgrade to GNU Make 3.81 or newer.)
+  $(error Cannot continue)
+endif
+
+# In Cygwin, the MAKE variable gets prepended with the current directory if the
+# make executable is called using a Windows mixed path (c:/cygwin/bin/make.exe).
+ifneq ($(findstring :, $(MAKE)), )
+  MAKE := $(patsubst $(CURDIR)%, %, $(patsubst $(CURDIR)/%, %, $(MAKE)))
 endif
 
 # Locate this Makefile
-ifeq ($(filter /%,$(lastword $(MAKEFILE_LIST))),)
-  makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST))
+ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),)
+  makefile_path := $(CURDIR)/$(strip $(lastword $(MAKEFILE_LIST)))
 else
-  makefile_path:=$(lastword $(MAKEFILE_LIST))
-endif
-root_dir:=$(patsubst %/,%,$(dir $(makefile_path)))
-
-ifeq ($(MAIN_TARGETS), )
-  COMMAND_LINE_VARIABLES:=$(subst =command,,$(filter %=command,$(foreach var,$(.VARIABLES),$(var)=$(firstword $(origin $(var))))))
-  MAKE_CONTROL_VARIABLES:=LOG CONF SPEC JOBS TEST IGNORE_OLD_CONFIG
-  UNKNOWN_COMMAND_LINE_VARIABLES:=$(strip $(filter-out $(MAKE_CONTROL_VARIABLES), $(COMMAND_LINE_VARIABLES)))
-  ifneq ($(UNKNOWN_COMMAND_LINE_VARIABLES), )
-    $(info Note: Command line contains non-control variables: $(UNKNOWN_COMMAND_LINE_VARIABLES).)
-    $(info Make sure it is not mistyped, and that you intend to override this variable.)
-    $(info 'make help' will list known control variables)
-  endif
-endif
-
-ifneq ($(findstring qp,$(MAKEFLAGS)),)
-  # When called with -qp, assume an external part (e.g. bash completion) is trying
-  # to understand our targets.
-  # Duplication of global targets, needed before ParseConfAndSpec in case we have
-  # no configurations.
-  help:
-  # If both CONF and SPEC are unset, look for all available configurations by
-  # setting CONF to the empty string.
-  ifeq ($(SPEC), )
-    CONF?=
-  endif
+  makefile_path := $(lastword $(MAKEFILE_LIST))
 endif
-
-# ... and then we can include our helper functions
-include $(root_dir)/make/MakeHelpers.gmk
-
-$(eval $(call ParseLogLevel))
-$(eval $(call ParseConfAndSpec))
-
-# Now determine if we have zero, one or several configurations to build.
-ifeq ($(SPEC),)
-  # Since we got past ParseConfAndSpec, we must be building a global target. Do nothing.
-else
-  # In Cygwin, the MAKE variable gets messed up if the make executable is called with
-  # a Windows mixed path (c:/cygwin/bin/make.exe). If that's the case, fix it by removing
-  # the prepended root_dir.
-  ifneq ($(findstring :, $(MAKE)), )
-    MAKE := $(patsubst $(root_dir)%, %, $(MAKE))
-  endif
-
-  # We are potentially building multiple configurations.
-  # First, find out the valid targets
-  # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find
-  # available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
-  all_phony_targets := $(sort $(filter-out $(global_targets), $(strip $(shell \
-      cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) \
-      -I $(root_dir)/make/common | grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-))))
-
-  # Loop through the configurations and call the main-wrapper for each one. The wrapper
-  # target will execute with a single configuration loaded.
-  $(all_phony_targets):
-	@$(if $(TARGET_RUN),,\
-          $(foreach spec,$(SPEC),\
-            (cd $(root_dir) && $(MAKE) SPEC=$(spec) MAIN_TARGETS="$(call GetRealTarget)" \
-	    $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) main-wrapper) &&) true)
-	@echo > /dev/null
-	$(eval TARGET_RUN=true)
-
-  .PHONY: $(all_phony_targets)
-
-  ifneq ($(MAIN_TARGETS), )
-    # The wrapper target was called so we now have a single configuration. Load the spec file
-    # and call the real Main.gmk.
-    include $(SPEC)
-    include $(SRC_ROOT)/make/common/MakeBase.gmk
+topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path))))
 
-    ### Clean up from previous run
-    # Remove any build.log from a previous run, if they exist
-    ifneq (,$(BUILD_LOG))
-      ifneq (,$(BUILD_LOG_PREVIOUS))
-        # Rotate old log
-        $(shell $(RM) $(BUILD_LOG_PREVIOUS) 2> /dev/null)
-        $(shell $(MV) $(BUILD_LOG) $(BUILD_LOG_PREVIOUS) 2> /dev/null)
-      else
-        $(shell $(RM) $(BUILD_LOG) 2> /dev/null)
-      endif
-      $(shell $(RM) $(OUTPUT_ROOT)/build-trace-time.log 2> /dev/null)
-    endif
-    # Remove any javac server logs and port files. This
-    # prevents a new make run to reuse the previous servers.
-    ifneq (,$(SJAVAC_SERVER_DIR))
-      $(shell $(MKDIR) -p $(SJAVAC_SERVER_DIR) && $(RM) -rf $(SJAVAC_SERVER_DIR)/*)
-    endif
-
-    # Split out the targets requiring sequential execution. Run these targets separately
-    # from the rest so that the rest may still enjoy full parallel execution.
-    SEQUENTIAL_TARGETS := $(filter dist-clean clean% reconfigure, $(MAIN_TARGETS))
-    PARALLEL_TARGETS := $(filter-out $(SEQUENTIAL_TARGETS), $(MAIN_TARGETS))
-
-    main-wrapper:
-        ifneq ($(SEQUENTIAL_TARGETS), )
-	  (cd $(SRC_ROOT)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \
-	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(SEQUENTIAL_TARGETS))
-        endif
-        ifneq ($(PARALLEL_TARGETS), )
-	  @$(call AtMakeStart)
-	  (cd $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
-	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(PARALLEL_TARGETS) \
-	      $(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC)))
-	  @$(call AtMakeEnd)
-        endif
-
-     .PHONY: main-wrapper
-
-   endif
-endif
-
-# Here are "global" targets, i.e. targets that can be executed without specifying a single configuration.
-# If you add more global targets, please update the variable global_targets in MakeHelpers.
-
-# Helper macro to allow $(info) to properly print strings beginning with spaces.
-_:=
-
-help:
-	$(info )
-	$(info OpenJDK Makefile help)
-	$(info =====================)
-	$(info )
-	$(info Common make targets)
-	$(info $(_) make [default]         # Compile all modules in langtools, hotspot, jdk, jaxws,)
-	$(info $(_)                        # jaxp and corba, and create a runnable "exploded" image)
-	$(info $(_) make all               # Compile everything, all repos, docs and images)
-	$(info $(_) make images            # Create complete j2sdk and j2re images)
-	$(info $(_) make <phase>           # Build the specified phase and everything it depends on)
-	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
-	$(info $(_) make *-only            # Applies to most targets and disables compling the)
-	$(info $(_)                        # dependencies for the target. This is faster but may)
-	$(info $(_)                        # result in incorrect build results!)
-	$(info $(_) make docs              # Create all docs)
-	$(info $(_) make docs-javadoc      # Create just javadocs, depends on less than full docs)
-	$(info $(_) make profiles          # Create complete j2re compact profile images)
-	$(info $(_) make bootcycle-images  # Build images twice, second time with newly built JDK)
-	$(info $(_) make install           # Install the generated images locally)
-	$(info $(_) make reconfigure       # Rerun configure with the same arguments as last time)
-	$(info $(_) make help              # Give some help on using make)
-	$(info $(_) make test              # Run tests, default is all tests (see TEST below))
-	$(info )
-	$(info Targets for cleaning)
-	$(info $(_) make clean             # Remove all files generated by make, but not those)
-	$(info $(_)                        # generated by configure)
-	$(info $(_) make dist-clean        # Remove all files, including configuration)
-	$(info $(_) make clean-<outputdir> # Remove the subdir in the output dir with the name)
-	$(info $(_) make clean-<phase>     # Remove all build results related to a certain build)
-	$(info $(_)                        # phase (gensrc, java, libs, launchers))
-	$(info $(_) make clean-<module>    # Remove all build results related to a certain module)
-	$(info $(_) make clean-<module>-<phase> # Remove all build results related to a certain)
-	$(info $(_)                        # module and phase)
-	$(info )
-	$(info Targets for specific modules)
-	$(info $(_) make <module>          # Build <module> and everything it depends on.)
-	$(info $(_) make <module>-<phase>  # Compile the specified phase for the specified module)
-	$(info $(_)                        # and everything it depends on)
-	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
-	$(info )
-	$(info Make control variables)
-	$(info $(_) CONF=                  # Build all configurations (note, assignment is empty))
-	$(info $(_) CONF=<substring>       # Build the configuration(s) with a name matching)
-	$(info $(_)                        # <substring>)
-	$(info $(_) SPEC=<spec file>       # Build the configuration given by the spec file)
-	$(info $(_) LOG=<loglevel>         # Change the log level from warn to <loglevel>)
-	$(info $(_)                        # Available log levels are:)
-	$(info $(_)                        # 'warn' (default), 'info', 'debug' and 'trace')
-	$(info $(_)                        # To see executed command lines, use LOG=debug)
-	$(info $(_) JOBS=<n>               # Run <n> parallel make jobs)
-	$(info $(_)                        # Note that -jN does not work as expected!)
-	$(info $(_) IGNORE_OLD_CONFIG=true # Skip tests if spec file is up to date)
-	$(info $(_) make test TEST=<test>  # Only run the given test or tests, e.g.)
-	$(info $(_)                        # make test TEST="jdk_lang jdk_net")
-	$(info )
-
-.PHONY: help
+# ... and then we can include the real makefile
+include $(topdir)/make/Init.gmk
--- a/common/autoconf/basics.m4	Wed Apr 08 13:12:48 2015 -0700
+++ b/common/autoconf/basics.m4	Wed Jul 05 20:27:20 2017 +0200
@@ -78,7 +78,7 @@
 AC_DEFUN([BASIC_FIXUP_PATH],
 [
   # Only process if variable expands to non-empty
-  
+
   if test "x[$]$1" != x; then
     if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
       BASIC_FIXUP_PATH_CYGWIN($1)
@@ -118,7 +118,7 @@
 AC_DEFUN([BASIC_FIXUP_EXECUTABLE],
 [
   # Only process if variable expands to non-empty
-  
+
   if test "x[$]$1" != x; then
     if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
       BASIC_FIXUP_EXECUTABLE_CYGWIN($1)
@@ -459,12 +459,21 @@
   AC_MSG_RESULT([$TOPDIR])
   AC_SUBST(TOPDIR)
 
+  # Save the original version of TOPDIR for string comparisons
+  ORIGINAL_TOPDIR="$TOPDIR"
+  AC_SUBST(ORIGINAL_TOPDIR)
+
   # We can only call BASIC_FIXUP_PATH after BASIC_CHECK_PATHS_WINDOWS.
   BASIC_FIXUP_PATH(CURDIR)
   BASIC_FIXUP_PATH(TOPDIR)
   # SRC_ROOT is a traditional alias for TOPDIR.
   SRC_ROOT=$TOPDIR
 
+  # Calculate a canonical version of TOPDIR for string comparisons
+  CANONICAL_TOPDIR=$TOPDIR
+  BASIC_REMOVE_SYMBOLIC_LINKS([CANONICAL_TOPDIR])
+  AC_SUBST(CANONICAL_TOPDIR)
+
   # Locate the directory of this script.
   AUTOCONF_DIR=$TOPDIR/common/autoconf
 ])
@@ -709,18 +718,6 @@
   AC_CONFIG_FILES([$OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in])
 ])
 
-AC_DEFUN_ONCE([BASIC_SETUP_LOGGING],
-[
-  # Setup default logging of stdout and stderr to build.log in the output root.
-  BUILD_LOG='$(OUTPUT_ROOT)/build.log'
-  BUILD_LOG_PREVIOUS='$(OUTPUT_ROOT)/build.log.old'
-  BUILD_LOG_WRAPPER='$(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)'
-  AC_SUBST(BUILD_LOG)
-  AC_SUBST(BUILD_LOG_PREVIOUS)
-  AC_SUBST(BUILD_LOG_WRAPPER)
-])
-
-
 #%%% Simple tools %%%
 
 # Check if we have found a usable version of make
--- a/common/autoconf/configure.ac	Wed Apr 08 13:12:48 2015 -0700
+++ b/common/autoconf/configure.ac	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,6 @@
 
 # Continue setting up basic stuff. Most remaining code require fundamental tools.
 BASIC_SETUP_PATHS
-BASIC_SETUP_LOGGING
 
 # Check if it's a pure open build or if custom sources are to be used.
 JDKOPT_SETUP_OPEN_OR_CUSTOM
--- a/common/autoconf/generated-configure.sh	Wed Apr 08 13:12:48 2015 -0700
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 20:27:20 2017 +0200
@@ -907,9 +907,8 @@
 JVM_INTERPRETER
 JDK_VARIANT
 SET_OPENJDK
-BUILD_LOG_WRAPPER
-BUILD_LOG_PREVIOUS
-BUILD_LOG
+CANONICAL_TOPDIR
+ORIGINAL_TOPDIR
 TOPDIR
 PATH_SEP
 ZERO_ARCHDEF
@@ -3471,9 +3470,6 @@
 
 
 
-
-
-
 #%%% Simple tools %%%
 
 # Check if we have found a usable version of make
@@ -14141,6 +14137,10 @@
 $as_echo "$TOPDIR" >&6; }
 
 
+  # Save the original version of TOPDIR for string comparisons
+  ORIGINAL_TOPDIR="$TOPDIR"
+
+
   # We can only call BASIC_FIXUP_PATH after BASIC_CHECK_PATHS_WINDOWS.
 
   # Only process if variable expands to non-empty
@@ -14397,19 +14397,62 @@
   # SRC_ROOT is a traditional alias for TOPDIR.
   SRC_ROOT=$TOPDIR
 
+  # Calculate a canonical version of TOPDIR for string comparisons
+  CANONICAL_TOPDIR=$TOPDIR
+
+  if test "x$OPENJDK_BUILD_OS" != xwindows; then
+    # Follow a chain of symbolic links. Use readlink
+    # where it exists, else fall back to horribly
+    # complicated shell code.
+    if test "x$READLINK_TESTED" != yes; then
+      # On MacOSX there is a readlink tool with a different
+      # purpose than the GNU readlink tool. Check the found readlink.
+      ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
+      if test "x$ISGNU" = x; then
+        # A readlink that we do not know how to use.
+        # Are there other non-GNU readlinks out there?
+        READLINK_TESTED=yes
+        READLINK=
+      fi
+    fi
+
+    if test "x$READLINK" != x; then
+      CANONICAL_TOPDIR=`$READLINK -f $CANONICAL_TOPDIR`
+    else
+      # Save the current directory for restoring afterwards
+      STARTDIR=$PWD
+      COUNTER=0
+      sym_link_dir=`$DIRNAME $CANONICAL_TOPDIR`
+      sym_link_file=`$BASENAME $CANONICAL_TOPDIR`
+      cd $sym_link_dir
+      # Use -P flag to resolve symlinks in directories.
+      cd `$THEPWDCMD -P`
+      sym_link_dir=`$THEPWDCMD -P`
+      # Resolve file symlinks
+      while test $COUNTER -lt 20; do
+        ISLINK=`$LS -l $sym_link_dir/$sym_link_file | $GREP '\->' | $SED -e 's/.*-> \(.*\)/\1/'`
+        if test "x$ISLINK" == x; then
+          # This is not a symbolic link! We are done!
+          break
+        fi
+        # Again resolve directory symlinks since the target of the just found
+        # link could be in a different directory
+        cd `$DIRNAME $ISLINK`
+        sym_link_dir=`$THEPWDCMD -P`
+        sym_link_file=`$BASENAME $ISLINK`
+        let COUNTER=COUNTER+1
+      done
+      cd $STARTDIR
+      CANONICAL_TOPDIR=$sym_link_dir/$sym_link_file
+    fi
+  fi
+
+
+
   # Locate the directory of this script.
   AUTOCONF_DIR=$TOPDIR/common/autoconf
 
 
-  # Setup default logging of stdout and stderr to build.log in the output root.
-  BUILD_LOG='$(OUTPUT_ROOT)/build.log'
-  BUILD_LOG_PREVIOUS='$(OUTPUT_ROOT)/build.log.old'
-  BUILD_LOG_WRAPPER='$(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)'
-
-
-
-
-
 # Check if it's a pure open build or if custom sources are to be used.
 
   # Check whether --enable-openjdk-only was given.
--- a/common/autoconf/spec.gmk.in	Wed Apr 08 13:12:48 2015 -0700
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 20:27:20 2017 +0200
@@ -55,25 +55,12 @@
 # A self-referential reference to this file.
 SPEC:=@SPEC@
 
-# Specify where the spec file is.
-MAKE_ARGS="SPEC=$(SPEC)"
-
-MAKE:=@MAKE@
-
-# Pass along the verbosity and log level settings.
-ifeq (,$(findstring VERBOSE=,$(MAKE)))
-  MAKE:=$(MAKE) $(VERBOSE) VERBOSE="$(VERBOSE)" LOG_LEVEL="$(LOG_LEVEL)"
-endif
+# What make to use for main processing, after bootstrapping top-level Makefile.
+MAKE := @MAKE@
 
-# No implicit variables or rules!
-ifeq (,$(findstring -R,$(MAKE)))
-  MAKE:=$(MAKE) -R
-endif
-
-# Specify where the common include directory for makefiles is.
-ifeq (,$(findstring -I @TOPDIR@/make/common,$(MAKE)))
-  MAKE:=$(MAKE) -I @TOPDIR@/make/common
-endif
+# The default make arguments
+MAKE_ARGS = $(MAKE_LOG_FLAGS) -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
+    MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" LOG_LEVEL=$(LOG_LEVEL)
 
 OUTPUT_SYNC_SUPPORTED:=@OUTPUT_SYNC_SUPPORTED@
 OUTPUT_SYNC:=@OUTPUT_SYNC@
@@ -146,6 +133,9 @@
 
 # The top-level directory of the forest (SRC_ROOT is a traditional alias)
 TOPDIR:=@TOPDIR@
+# These two versions of TOPDIR are used in string comparisons
+ORIGINAL_TOPDIR:=@ORIGINAL_TOPDIR@
+CANONICAL_TOPDIR:=@CANONICAL_TOPDIR@
 SRC_ROOT:=@TOPDIR@
 
 OUTPUT_ROOT:=@OUTPUT_ROOT@
@@ -573,18 +563,6 @@
 XCODEBUILD=@XCODEBUILD@
 FIXPATH:=@FIXPATH@
 
-# Where the build output is stored for your convenience.
-BUILD_LOG:=@BUILD_LOG@
-BUILD_LOG_PREVIOUS:=@BUILD_LOG_PREVIOUS@
-# Disable the build log wrapper on sjavac+windows until
-# we have solved how to prevent the log wrapper to wait
-# for the background sjavac server process.
-ifeq (@ENABLE_SJAVAC@X@OPENJDK_BUILD_OS@,yesXwindows)
-  BUILD_LOG_WRAPPER:=
-else
-  BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
-endif
-
 # Build setup
 ENABLE_JFR=@ENABLE_JFR@
 ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
--- a/configure	Wed Apr 08 13:12:48 2015 -0700
+++ b/configure	Wed Jul 05 20:27:20 2017 +0200
@@ -31,4 +31,5 @@
 
 # Delegate to wrapper, forcing wrapper to believe $0 is this script by using -c.
 # This trick is needed to get autoconf to co-operate properly.
-bash -c ". $this_script_dir/common/autoconf/configure" $this_script_dir/configure CHECKME $this_script_dir "$@"
+# The ${-:+-$-} construction passes on bash options.
+bash ${-:+-$-} -c ". $this_script_dir/common/autoconf/configure" $this_script_dir/configure CHECKME $this_script_dir "$@"
--- a/corba/.hgtags	Wed Apr 08 13:12:48 2015 -0700
+++ b/corba/.hgtags	Wed Jul 05 20:27:20 2017 +0200
@@ -300,3 +300,4 @@
 734ca5311a225711b79618f3e92f47f07c82154a jdk9-b55
 ef4afd6832b00b8687832c2a36c90e43750ebe40 jdk9-b56
 d8ebf1a5b18ccbc849f5bf0f80aa3d78583eee68 jdk9-b57
+86dd5de1f5cb09073019bd629e22cfcd012d8b4b jdk9-b58
--- a/hotspot/.hgtags	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 20:27:20 2017 +0200
@@ -460,3 +460,4 @@
 be49ab55e5c498c5077bbf58c2737100d1992339 jdk9-b55
 fd2d5ec7e7b16c7bf4043a7fe7cfd8af96b819e2 jdk9-b56
 56a85ffe743d3f9d70ba25d6ce82ddd2ad1bf33c jdk9-b57
+ee878f3d6732856f7725c590312bfbe2ffa52cc7 jdk9-b58
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Wed Jul 05 20:27:20 2017 +0200
@@ -123,6 +123,7 @@
 
   private static Type intxType;
   private static Type uintxType;
+  private static Type sizetType;
   private static CIntegerType boolType;
   private Boolean sharingEnabled;
   private Boolean compressedOopsEnabled;
@@ -175,7 +176,7 @@
 
      public long getIntx() {
         if (Assert.ASSERTS_ENABLED) {
-           Assert.that(isIntx(), "not a intx flag!");
+           Assert.that(isIntx(), "not an intx flag!");
         }
         return addr.getCIntegerAt(0, intxType.getSize(), false);
      }
@@ -191,6 +192,17 @@
         return addr.getCIntegerAt(0, uintxType.getSize(), true);
      }
 
+     public boolean isSizet() {
+        return type.equals("size_t");
+     }
+
+     public long getSizet() {
+        if (Assert.ASSERTS_ENABLED) {
+           Assert.that(isSizet(), "not a size_t flag!");
+        }
+        return addr.getCIntegerAt(0, sizetType.getSize(), true);
+     }
+
      public String getValue() {
         if (isBool()) {
            return new Boolean(getBool()).toString();
@@ -198,6 +210,8 @@
            return new Long(getIntx()).toString();
         } else if (isUIntx()) {
            return new Long(getUIntx()).toString();
+        } else if (isSizet()) {
+            return new Long(getSizet()).toString();
         } else {
            return null;
         }
@@ -323,6 +337,7 @@
 
     intxType = db.lookupType("intx");
     uintxType = db.lookupType("uintx");
+    sizetType = db.lookupType("size_t");
     boolType = (CIntegerType) db.lookupType("bool");
 
     minObjAlignmentInBytes = getObjectAlignmentInBytes();
--- a/hotspot/make/linux/makefiles/gcc.make	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Wed Jul 05 20:27:20 2017 +0200
@@ -207,7 +207,7 @@
   WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type -Woverloaded-virtual
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -673,7 +673,6 @@
   void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       // With G1, don't generate the call if we statically know that the target in uninitialized
       if (!dest_uninitialized) {
@@ -719,7 +718,6 @@
     assert_different_registers(start, end, scratch);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
 
         {
--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -150,7 +150,6 @@
   assert(val == noreg || val == r0, "parameter is just for looks");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // flatten object address if needed
--- a/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/c2_globals_ppc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2014 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -49,7 +49,7 @@
 define_pd_global(intx, MinJumpTableSize,             10);
 define_pd_global(intx, INTPRESSURE,                  25);
 define_pd_global(intx, InteriorEntryAlignment,       16);
-define_pd_global(intx, NewSizeThreadIncrease,        ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, RegisterCostAreaRatio,        16000);
 define_pd_global(bool, UseTLAB,                      true);
 define_pd_global(bool, ResizeTLAB,                   true);
@@ -85,14 +85,14 @@
 define_pd_global(intx, CodeCacheExpansionSize,       64*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 define_pd_global(uintx, CodeCacheMinBlockLength,     4);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
 
 define_pd_global(bool,  TrapBasedRangeChecks,        true);
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,                ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012, 2013 SAP AG. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -56,7 +56,7 @@
 define_pd_global(bool, UseMembar,             false);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // Default max size of CMS young gen, per GC worker thread.
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // Default max size of CMS young gen, per GC worker thread.
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -608,7 +608,6 @@
   void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1) {
     BarrierSet* const bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -665,7 +664,6 @@
     BarrierSet* const bs = Universe::heap()->barrier_set();
 
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           if (branchToEnd) {
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -66,7 +66,6 @@
 
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // Load and record the previous value.
--- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,10 +53,10 @@
 define_pd_global(intx, CodeCacheExpansionSize,       32*K );
 define_pd_global(uintx, CodeCacheMinBlockLength,     1);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
-define_pd_global(uintx, MetaspaceSize,               12*M );
+define_pd_global(size_t, MetaspaceSize,              12*M );
 define_pd_global(bool, NeverActAsServerClassMachine, true );
-define_pd_global(intx, NewSizeThreadIncrease,        16*K );
-define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
+define_pd_global(size_t, NewSizeThreadIncrease,      16*K );
+define_pd_global(uint64_t, MaxRAM,                   1ULL*G);
 define_pd_global(intx, InitialCodeCacheSize,         160*K);
 #endif // !TIERED
 
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
 define_pd_global(intx, FreqInlineSize,               175);
 define_pd_global(intx, INTPRESSURE,                  48);  // large register set
 define_pd_global(intx, InteriorEntryAlignment,       16);  // = CodeEntryAlignment
-define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, RegisterCostAreaRatio,        12000);
 define_pd_global(bool, UseTLAB,                      true);
 define_pd_global(bool, ResizeTLAB,                   true);
@@ -90,7 +90,7 @@
 define_pd_global(intx, NonNMethodCodeHeapSize,       5*M );
 define_pd_global(intx, CodeCacheExpansionSize,       32*K);
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 #endif
 define_pd_global(uintx, CodeCacheMinBlockLength,     4);
 define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
@@ -98,7 +98,7 @@
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on sparc.
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,    ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,7 @@
 define_pd_global(bool, UseMembar,            false);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -957,7 +957,6 @@
   void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -1005,7 +1004,6 @@
     BarrierSet* bs = Universe::heap()->barrier_set();
 
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           // Get some new fresh output registers.
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,6 @@
   assert(index == noreg || offset == 0, "only one offset");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // Load and record the previous value.
--- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,39 +32,39 @@
 // (see c1_globals.hpp)
 
 #ifndef TIERED
-define_pd_global(bool, BackgroundCompilation,        true );
-define_pd_global(bool, UseTLAB,                      true );
-define_pd_global(bool, ResizeTLAB,                   true );
-define_pd_global(bool, InlineIntrinsics,             true );
-define_pd_global(bool, PreferInterpreterNativeStubs, false);
-define_pd_global(bool, ProfileTraps,                 false);
-define_pd_global(bool, UseOnStackReplacement,        true );
-define_pd_global(bool, TieredCompilation,            false);
-define_pd_global(intx, CompileThreshold,             1500 );
+define_pd_global(bool, BackgroundCompilation,          true );
+define_pd_global(bool, UseTLAB,                        true );
+define_pd_global(bool, ResizeTLAB,                     true );
+define_pd_global(bool, InlineIntrinsics,               true );
+define_pd_global(bool, PreferInterpreterNativeStubs,   false);
+define_pd_global(bool, ProfileTraps,                   false);
+define_pd_global(bool, UseOnStackReplacement,          true );
+define_pd_global(bool, TieredCompilation,              false);
+define_pd_global(intx, CompileThreshold,               1500 );
 
-define_pd_global(intx, OnStackReplacePercentage,     933  );
-define_pd_global(intx, FreqInlineSize,               325  );
-define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
-define_pd_global(intx, InitialCodeCacheSize,         160*K);
-define_pd_global(intx, ReservedCodeCacheSize,        32*M );
-define_pd_global(intx, NonProfiledCodeHeapSize,      13*M );
-define_pd_global(intx, ProfiledCodeHeapSize,         14*M );
-define_pd_global(intx, NonNMethodCodeHeapSize,       5*M  );
-define_pd_global(bool, ProfileInterpreter,           false);
-define_pd_global(intx, CodeCacheExpansionSize,       32*K );
-define_pd_global(uintx, CodeCacheMinBlockLength,     1);
-define_pd_global(uintx, CodeCacheMinimumUseSpace,    400*K);
-define_pd_global(uintx, MetaspaceSize,               12*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true );
-define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
-define_pd_global(bool, CICompileOSR,                 true );
+define_pd_global(intx,   OnStackReplacePercentage,     933  );
+define_pd_global(intx,   FreqInlineSize,               325  );
+define_pd_global(size_t, NewSizeThreadIncrease,        4*K  );
+define_pd_global(intx, InitialCodeCacheSize,           160*K);
+define_pd_global(intx, ReservedCodeCacheSize,          32*M );
+define_pd_global(intx, NonProfiledCodeHeapSize,        13*M );
+define_pd_global(intx, ProfiledCodeHeapSize,           14*M );
+define_pd_global(intx, NonNMethodCodeHeapSize,         5*M  );
+define_pd_global(bool,   ProfileInterpreter,           false);
+define_pd_global(intx, CodeCacheExpansionSize,         32*K );
+define_pd_global(uintx, CodeCacheMinBlockLength,       1    );
+define_pd_global(uintx, CodeCacheMinimumUseSpace,      400*K);
+define_pd_global(size_t, MetaspaceSize,                12*M );
+define_pd_global(bool,   NeverActAsServerClassMachine, true );
+define_pd_global(uint64_t, MaxRAM,                    1ULL*G);
+define_pd_global(bool,   CICompileOSR,                 true );
 #endif // !TIERED
-define_pd_global(bool, UseTypeProfile,               false);
-define_pd_global(bool, RoundFPResults,               true );
+define_pd_global(bool, UseTypeProfile,                 false);
+define_pd_global(bool, RoundFPResults,                 true );
 
-define_pd_global(bool, LIRFillDelaySlots,            false);
-define_pd_global(bool, OptimizeSinglePrecision,      true );
-define_pd_global(bool, CSEArrayLength,               false);
-define_pd_global(bool, TwoOperandLIRForm,            true );
+define_pd_global(bool, LIRFillDelaySlots,              false);
+define_pd_global(bool, OptimizeSinglePrecision,        true );
+define_pd_global(bool, CSEArrayLength,                 false);
+define_pd_global(bool, TwoOperandLIRForm,              true );
 
 #endif // CPU_X86_VM_C1_GLOBALS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,25 +54,25 @@
 #ifdef AMD64
 define_pd_global(intx, INTPRESSURE,                  13);
 define_pd_global(intx, InteriorEntryAlignment,       16);
-define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
+define_pd_global(size_t, NewSizeThreadIncrease,      ScaleForWordSize(4*K));
 define_pd_global(intx, LoopUnrollLimit,              60);
 // InitialCodeCacheSize derived from specjbb2000 run.
 define_pd_global(intx, InitialCodeCacheSize,         2496*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, CodeCacheExpansionSize,       64*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    128ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   128ULL*G);
 #else
 define_pd_global(intx, INTPRESSURE,                  6);
 define_pd_global(intx, InteriorEntryAlignment,       4);
-define_pd_global(intx, NewSizeThreadIncrease,        4*K);
+define_pd_global(size_t, NewSizeThreadIncrease,      4*K);
 define_pd_global(intx, LoopUnrollLimit,              50);     // Design center runs on 1.3.1
 // InitialCodeCacheSize derived from specjbb2000 run.
 define_pd_global(intx, InitialCodeCacheSize,         2304*K); // Integral multiple of CodeCacheExpansionSize
 define_pd_global(intx, CodeCacheExpansionSize,       32*K);
 
 // Ergonomics related flags
-define_pd_global(uint64_t,MaxRAM,                    4ULL*G);
+define_pd_global(uint64_t, MaxRAM,                   4ULL*G);
 #endif // AMD64
 define_pd_global(intx, RegisterCostAreaRatio,        16000);
 
@@ -93,7 +93,7 @@
 define_pd_global(bool,  TrapBasedRangeChecks,        false); // Not needed on x86.
 
 // Heap related flags
-define_pd_global(uintx,MetaspaceSize,    ScaleForWordSize(16*M));
+define_pd_global(size_t, MetaspaceSize,              ScaleForWordSize(16*M));
 
 // Ergonomics related flags
 define_pd_global(bool, NeverActAsServerClassMachine, false);
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -78,7 +78,7 @@
 #endif
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 111);
 
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -706,7 +706,6 @@
     assert_different_registers(start, count);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!uninitialized_target) {
@@ -739,7 +738,6 @@
     BarrierSet* bs = Universe::heap()->barrier_set();
     assert_different_registers(start, count);
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           __ pusha();                      // push registers
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1207,7 +1207,6 @@
   void  gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
@@ -1252,7 +1251,6 @@
     assert_different_registers(start, count, scratch);
     BarrierSet* bs = Universe::heap()->barrier_set();
     switch (bs->kind()) {
-      case BarrierSet::G1SATBCT:
       case BarrierSet::G1SATBCTLogging:
         {
           __ pusha();             // push registers (overkill)
--- a/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -156,7 +156,6 @@
   assert(val == noreg || val == rax, "parameter is just for looks");
   switch (barrier) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       {
         // flatten object address if needed
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -57,7 +57,7 @@
 define_pd_global(bool,  UseMembar,            true);
 
 // GC Ergo Flags
-define_pd_global(uintx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+define_pd_global(size_t, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 
 define_pd_global(uintx, TypeProfileLevel, 0);
 
--- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -50,7 +50,7 @@
 define_pd_global(intx,     OnStackReplacePercentage,     933  );
 define_pd_global(intx,     FreqInlineSize,               325  );
 define_pd_global(uintx,    NewRatio,                     12   );
-define_pd_global(intx,     NewSizeThreadIncrease,        4*K  );
+define_pd_global(size_t,   NewSizeThreadIncrease,        4*K  );
 define_pd_global(intx,     InitialCodeCacheSize,         160*K);
 define_pd_global(intx,     ReservedCodeCacheSize,        32*M );
 define_pd_global(intx,     NonProfiledCodeHeapSize,      13*M );
@@ -61,7 +61,7 @@
 define_pd_global(uintx,    CodeCacheMinBlockLength,      1    );
 define_pd_global(uintx,    CodeCacheMinimumUseSpace,     200*K);
 
-define_pd_global(uintx,    MetaspaceSize,                12*M );
+define_pd_global(size_t,   MetaspaceSize,                12*M );
 define_pd_global(bool,     NeverActAsServerClassMachine, true );
 define_pd_global(uint64_t, MaxRAM,                       1ULL*G);
 define_pd_global(bool,     CICompileOSR,                 true );
--- a/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -40,13 +40,13 @@
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 define_pd_global(intx, StackYellowPages,         6);
 define_pd_global(intx, StackRedPages,            1);
 define_pd_global(intx, StackShadowPages,         6 DEBUG_ONLY(+2));
 
 // Only used on 64 bit platforms
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_AIX_OJDKPPC_VM_GLOBALS_AIX_PPC_HPP
--- a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,9 +43,9 @@
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
--- a/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -39,9 +39,9 @@
 define_pd_global(intx,  VMThreadStackSize,       512);
 #endif // _LP64
 define_pd_global(intx,  CompilerThreadStackSize, 0);
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -116,6 +116,14 @@
 #endif
 }
 
+void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) {
+#ifdef BUILTIN_SIM
+  uc->uc_mcontext.gregs[REG_PC] = (intptr_t)pc;
+#else
+  uc->uc_mcontext.pc = (intptr_t)pc;
+#endif
+}
+
 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
 #ifdef BUILTIN_SIM
   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
@@ -311,7 +319,7 @@
     }
 #else
     if (StubRoutines::is_safefetch_fault(pc)) {
-      uc->uc_mcontext.pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
+      os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
       return 1;
     }
 #endif
@@ -432,11 +440,7 @@
     // save all thread context in case we need to restore it
     if (thread != NULL) thread->set_saved_exception_pc(pc);
 
-#ifdef BUILTIN_SIM
-    uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub;
-#else
-    uc->uc_mcontext.pc = (__u64)stub;
-#endif
+    os::Linux::ucontext_set_pc(uc, stub);
     return true;
   }
 
--- a/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -40,13 +40,13 @@
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 define_pd_global(intx, StackYellowPages,         6);
 define_pd_global(intx, StackRedPages,            1);
 define_pd_global(intx, StackShadowPages,         6 DEBUG_ONLY(+2));
 
 // Only used on 64 bit platforms
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_PPC_VM_GLOBALS_LINUX_PPC_HPP
--- a/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,10 @@
 // runtime system.  (see globals.hpp)
 //
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
+define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      CONST64(4)*G);
+define_pd_global(size_t, HeapBaseMinAddress,     CONST64(4)*G);
 
 #endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP
--- a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,9 +42,9 @@
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
-define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
--- a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -39,9 +39,9 @@
 define_pd_global(intx,  VMThreadStackSize,       512);
 #endif // _LP64
 define_pd_global(intx,  CompilerThreadStackSize, 0);
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
--- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,16 +30,16 @@
 // (see globals.hpp)
 //
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    12288);
+define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
 #ifdef _LP64
 // use 6G as default base address because by default the OS maps the application
 // to 4G on Solaris-Sparc. This leaves at least 2G for the native heap.
-define_pd_global(uintx, HeapBaseMinAddress,      CONST64(6)*G);
+define_pd_global(size_t, HeapBaseMinAddress,     CONST64(6)*G);
 #else
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 #endif
 
 
--- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,18 +32,18 @@
 #ifdef AMD64
 define_pd_global(intx, ThreadStackSize,          1024); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        1024);
-define_pd_global(uintx,JVMInvokeMethodSlack,     8*K);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8*K);
 #else
 // ThreadStackSize 320 allows a couple of test cases to run while
 // keeping the number of threads that can be created high.
 define_pd_global(intx, ThreadStackSize,          320);
 define_pd_global(intx, VMThreadStackSize,        512);
-define_pd_global(uintx,JVMInvokeMethodSlack,     10*K);
+define_pd_global(size_t, JVMInvokeMethodSlack,   10*K);
 #endif // AMD64
 
 define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP
--- a/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,9 +43,9 @@
 define_pd_global(intx, CompilerThreadStackSize,  0);
 #endif
 
-define_pd_global(uintx, JVMInvokeMethodSlack,    8192);
+define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
-define_pd_global(uintx, HeapBaseMinAddress,      2*G);
+define_pd_global(size_t, HeapBaseMinAddress,     2*G);
 
 #endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1421,7 +1421,6 @@
   // Do the pre-write barrier, if any.
   switch (_bs->kind()) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
       break;
@@ -1442,7 +1441,6 @@
 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
   switch (_bs->kind()) {
 #if INCLUDE_ALL_GCS
-    case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_post_barrier(addr,  new_val);
       break;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -186,7 +186,7 @@
       cp->space->set_compaction_top(compact_top);
       cp->space = cp->space->next_compaction_space();
       if (cp->space == NULL) {
-        cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
+        cp->gen = GenCollectedHeap::heap()->young_gen();
         assert(cp->gen != NULL, "compaction must succeed");
         cp->space = cp->gen->first_compaction_space();
         assert(cp->space != NULL, "generation must have a first compaction space");
@@ -900,7 +900,6 @@
   }
 }
 
-
 // Callers of this iterator beware: The closure application should
 // be robust in the face of uninitialized objects and should (always)
 // return a correct size so that the next addr + size below gives us a
@@ -2663,8 +2662,8 @@
       // Need to smooth wrt historical average
       if (ResizeOldPLAB) {
         _blocks_to_claim[i].sample(
-          MAX2((size_t)CMSOldPLABMin,
-          MIN2((size_t)CMSOldPLABMax,
+          MAX2(CMSOldPLABMin,
+          MIN2(CMSOldPLABMax,
                _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
       }
       // Reset counters for next round
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,9 @@
 // space, in this case a CompactibleFreeListSpace.
 
 // Forward declarations
+class CMSCollector;
 class CompactibleFreeListSpace;
+class ConcurrentMarkSweepGeneration;
 class BlkClosure;
 class BlkClosureCareful;
 class FreeChunk;
@@ -396,6 +398,10 @@
   // Resizing support
   void set_end(HeapWord* value);  // override
 
+  // Never mangle CompactibleFreeListSpace
+  void mangle_unused_area() {}
+  void mangle_unused_area_complete() {}
+
   // Mutual exclusion support
   Mutex* freelistLock() const { return &_freelistLock; }
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -369,7 +369,7 @@
 double CMSStats::time_until_cms_gen_full() const {
   size_t cms_free = _cms_gen->cmsSpace()->free();
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  size_t expected_promotion = MIN2(gch->get_gen(0)->capacity(),
+  size_t expected_promotion = MIN2(gch->young_gen()->capacity(),
                                    (size_t) _cms_gen->gc_stats()->avg_promoted()->padded_average());
   if (cms_free > expected_promotion) {
     // Start a cms collection if there isn't enough space to promote
@@ -506,7 +506,7 @@
   _collector_policy(cp),
   _should_unload_classes(CMSClassUnloadingEnabled),
   _concurrent_cycles_since_last_unload(0),
-  _roots_scanning_options(SharedHeap::SO_None),
+  _roots_scanning_options(GenCollectedHeap::SO_None),
   _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
   _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
   _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()),
@@ -626,8 +626,8 @@
 
   // Support for parallelizing young gen rescan
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  assert(gch->prev_gen(_cmsGen)->kind() == Generation::ParNew, "CMS can only be used with ParNew");
-  _young_gen = (ParNewGeneration*)gch->prev_gen(_cmsGen);
+  assert(gch->young_gen()->kind() == Generation::ParNew, "CMS can only be used with ParNew");
+  _young_gen = (ParNewGeneration*)gch->young_gen();
   if (gch->supports_inline_contig_alloc()) {
     _top_addr = gch->top_addr();
     _end_addr = gch->end_addr();
@@ -869,7 +869,7 @@
       if (prev_level >= 0) {
         size_t prev_size = 0;
         GenCollectedHeap* gch = GenCollectedHeap::heap();
-        Generation* prev_gen = gch->get_gen(prev_level);
+        Generation* prev_gen = gch->young_gen();
         prev_size = prev_gen->capacity();
           gclog_or_tty->print_cr("  Younger gen size "SIZE_FORMAT,
                                  prev_size/1000);
@@ -1049,11 +1049,8 @@
     // expand and retry
     size_t s = _cmsSpace->expansionSpaceRequired(obj_size);  // HeapWords
     expand_for_gc_cause(s*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_promotion);
-    // Since there's currently no next generation, we don't try to promote
+    // Since this is the old generation, we don't try to promote
     // into a more senior generation.
-    assert(next_gen() == NULL, "assumption, based upon which no attempt "
-                               "is made to pass on a possibly failing "
-                               "promotion to next generation");
     res = _cmsSpace->promote(obj, obj_size);
   }
   if (res != NULL) {
@@ -2499,7 +2496,7 @@
   gch->gen_process_roots(_cmsGen->level(),
                          true,   // younger gens are roots
                          true,   // activate StrongRootsScope
-                         SharedHeap::ScanningOption(roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(roots_scanning_options()),
                          should_unload_classes(),
                          &notOlder,
                          NULL,
@@ -2567,7 +2564,7 @@
   gch->gen_process_roots(_cmsGen->level(),
                          true,   // younger gens are roots
                          true,   // activate StrongRootsScope
-                         SharedHeap::ScanningOption(roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(roots_scanning_options()),
                          should_unload_classes(),
                          &notOlder,
                          NULL,
@@ -2751,7 +2748,7 @@
 void CMSCollector::setup_cms_unloading_and_verification_state() {
   const  bool should_verify =   VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
                              || VerifyBeforeExit;
-  const  int  rso           =   SharedHeap::SO_AllCodeCache;
+  const  int  rso           =   GenCollectedHeap::SO_AllCodeCache;
 
   // We set the proper root for this CMS cycle here.
   if (should_unload_classes()) {   // Should unload classes this cycle
@@ -3000,7 +2997,6 @@
   report_heap_summary(GCWhen::BeforeGC);
 
   ReferenceProcessor* rp = ref_processor();
-  SpecializationStats::clear();
   assert(_restart_addr == NULL, "Control point invariant");
   {
     // acquire locks for subsequent manipulations
@@ -3011,7 +3007,6 @@
     rp->enable_discovery();
     _collectorState = Marking;
   }
-  SpecializationStats::print();
 }
 
 void CMSCollector::checkpointRootsInitialWork() {
@@ -3092,7 +3087,7 @@
       gch->gen_process_roots(_cmsGen->level(),
                              true,   // younger gens are roots
                              true,   // activate StrongRootsScope
-                             SharedHeap::ScanningOption(roots_scanning_options()),
+                             GenCollectedHeap::ScanningOption(roots_scanning_options()),
                              should_unload_classes(),
                              &notOlder,
                              NULL,
@@ -4329,7 +4324,6 @@
   verify_work_stacks_empty();
   verify_overflow_empty();
 
-  SpecializationStats::clear();
   if (PrintGCDetails) {
     gclog_or_tty->print("[YG occupancy: "SIZE_FORMAT" K ("SIZE_FORMAT" K)]",
                         _young_gen->used() / K,
@@ -4360,7 +4354,6 @@
   }
   verify_work_stacks_empty();
   verify_overflow_empty();
-  SpecializationStats::print();
 }
 
 void CMSCollector::checkpointRootsFinalWork() {
@@ -4528,13 +4521,13 @@
   gch->gen_process_roots(_collector->_cmsGen->level(),
                          false,     // yg was scanned above
                          false,     // this is parallel code
-                         SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mri_cl,
                          NULL,
                          &cld_closure);
   assert(_collector->should_unload_classes()
-         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+         || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
   if (PrintCMSStatistics != 0) {
@@ -4664,14 +4657,14 @@
   gch->gen_process_roots(_collector->_cmsGen->level(),
                          false,     // yg was scanned above
                          false,     // this is parallel code
-                         SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                         GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mrias_cl,
                          NULL,
                          NULL);     // The dirty klasses will be handled below
 
   assert(_collector->should_unload_classes()
-         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+         || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   _timer.stop();
   if (PrintCMSStatistics != 0) {
@@ -5255,14 +5248,14 @@
     gch->gen_process_roots(_cmsGen->level(),
                            true,  // younger gens as roots
                            false, // use the local StrongRootsScope
-                           SharedHeap::ScanningOption(roots_scanning_options()),
+                           GenCollectedHeap::ScanningOption(roots_scanning_options()),
                            should_unload_classes(),
                            &mrias_cl,
                            NULL,
                            NULL); // The dirty klasses will be handled below
 
     assert(should_unload_classes()
-           || (roots_scanning_options() & SharedHeap::SO_AllCodeCache),
+           || (roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
            "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
   }
 
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 
+#include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
 #include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gSpaceCounters.hpp"
 #include "gc_implementation/shared/gcStats.hpp"
@@ -55,6 +56,7 @@
 // means of a sliding mark-compact.
 
 class AdaptiveSizePolicy;
+class CMSCollector;
 class CMSConcMarkingTask;
 class CMSGCAdaptivePolicyCounters;
 class CMSTracer;
@@ -64,6 +66,7 @@
 class ConcurrentMarkSweepThread;
 class CompactibleFreeListSpace;
 class FreeChunk;
+class ParNewGeneration;
 class PromotionInfo;
 class ScanMarkedObjectsAgainCarefullyClosure;
 class TenuredGeneration;
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -696,32 +696,32 @@
   }
 
   if (FLAG_IS_DEFAULT(MarkStackSize)) {
-    uintx mark_stack_size =
+    size_t mark_stack_size =
       MIN2(MarkStackSizeMax,
-          MAX2(MarkStackSize, (uintx) (parallel_marking_threads() * TASKQUEUE_SIZE)));
+          MAX2(MarkStackSize, (size_t) (parallel_marking_threads() * TASKQUEUE_SIZE)));
     // Verify that the calculated value for MarkStackSize is in range.
     // It would be nice to use the private utility routine from Arguments.
     if (!(mark_stack_size >= 1 && mark_stack_size <= MarkStackSizeMax)) {
-      warning("Invalid value calculated for MarkStackSize (" UINTX_FORMAT "): "
-              "must be between " UINTX_FORMAT " and " UINTX_FORMAT,
-              mark_stack_size, (uintx) 1, MarkStackSizeMax);
+      warning("Invalid value calculated for MarkStackSize (" SIZE_FORMAT "): "
+              "must be between 1 and " SIZE_FORMAT,
+              mark_stack_size, MarkStackSizeMax);
       return;
     }
-    FLAG_SET_ERGO(uintx, MarkStackSize, mark_stack_size);
+    FLAG_SET_ERGO(size_t, MarkStackSize, mark_stack_size);
   } else {
     // Verify MarkStackSize is in range.
     if (FLAG_IS_CMDLINE(MarkStackSize)) {
       if (FLAG_IS_DEFAULT(MarkStackSizeMax)) {
         if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) {
-          warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT "): "
-                  "must be between " UINTX_FORMAT " and " UINTX_FORMAT,
-                  MarkStackSize, (uintx) 1, MarkStackSizeMax);
+          warning("Invalid value specified for MarkStackSize (" SIZE_FORMAT "): "
+                  "must be between 1 and " SIZE_FORMAT,
+                  MarkStackSize, MarkStackSizeMax);
           return;
         }
       } else if (FLAG_IS_CMDLINE(MarkStackSizeMax)) {
         if (!(MarkStackSize >= 1 && MarkStackSize <= MarkStackSizeMax)) {
-          warning("Invalid value specified for MarkStackSize (" UINTX_FORMAT ")"
-                  " or for MarkStackSizeMax (" UINTX_FORMAT ")",
+          warning("Invalid value specified for MarkStackSize (" SIZE_FORMAT ")"
+                  " or for MarkStackSizeMax (" SIZE_FORMAT ")",
                   MarkStackSize, MarkStackSizeMax);
           return;
         }
@@ -745,7 +745,7 @@
   // so that the assertion in MarkingTaskQueue::task_queue doesn't fail
   _active_tasks = _max_worker_id;
 
-  size_t max_regions = (size_t) _g1h->max_regions();
+  uint max_regions = _g1h->max_regions();
   for (uint i = 0; i < _max_worker_id; ++i) {
     CMTaskQueue* task_queue = new CMTaskQueue();
     task_queue->initialize();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -34,6 +34,7 @@
 class G1CollectedHeap;
 class CMBitMap;
 class CMTask;
+class ConcurrentMark;
 typedef GenericTaskQueue<oop, mtGC>            CMTaskQueue;
 typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet;
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -48,6 +48,7 @@
 #include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/g1/g1YCTypes.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
@@ -89,18 +90,6 @@
 // apply to TLAB allocation, which is not part of this interface: it
 // is done by clients of this interface.)
 
-// Notes on implementation of parallelism in different tasks.
-//
-// G1ParVerifyTask uses heap_region_par_iterate() for parallelism.
-// The number of GC workers is passed to heap_region_par_iterate().
-// It does use run_task() which sets _n_workers in the task.
-// G1ParTask executes g1_process_roots() ->
-// SharedHeap::process_roots() which calls eventually to
-// CardTableModRefBS::par_non_clean_card_iterate_work() which uses
-// SequentialSubTasksDone.  SharedHeap::process_roots() also
-// directly uses SubTasksDone (_process_strong_tasks field in SharedHeap).
-//
-
 // Local to this file.
 
 class RefineCardTableEntryClosure: public CardTableEntryClosure {
@@ -1767,7 +1756,6 @@
   _is_alive_closure_stw(this),
   _ref_processor_cm(NULL),
   _ref_processor_stw(NULL),
-  _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
   _bot_shared(NULL),
   _evac_failure_scan_stack(NULL),
   _mark_in_progress(false),
@@ -1801,9 +1789,6 @@
   _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
 
   _g1h = this;
-  if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  }
 
   _allocator = G1Allocator::create_allocator(_g1h);
   _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
@@ -2026,10 +2011,6 @@
                                              Shared_DirtyCardQ_lock,
                                              &JavaThread::dirty_card_queue_set());
 
-  // In case we're keeping closure specialization stats, initialize those
-  // counts and that mechanism.
-  SpecializationStats::clear();
-
   // Here we allocate the dummy HeapRegion that is required by the
   // G1AllocRegion class.
   HeapRegion* dummy_region = _hrm.get_dummy_region();
@@ -2206,11 +2187,11 @@
   hot_card_cache->drain(worker_i, g1_rem_set(), into_cset_dcq);
 
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  int n_completed_buffers = 0;
+  size_t n_completed_buffers = 0;
   while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) {
     n_completed_buffers++;
   }
-  g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i, n_completed_buffers);
+  g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, n_completed_buffers);
   dcqs.clear_n_completed_buffers();
   assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!");
 }
@@ -3111,11 +3092,12 @@
     G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
     G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
 
-    process_all_roots(true,            // activate StrongRootsScope
-                      SO_AllCodeCache, // roots scanning options
-                      &rootsCl,
-                      &cldCl,
-                      &blobsCl);
+    {
+      G1RootProcessor root_processor(this);
+      root_processor.process_all_roots(&rootsCl,
+                                       &cldCl,
+                                       &blobsCl);
+    }
 
     bool failures = rootsCl.failures() || codeRootsCl.failures();
 
@@ -3321,7 +3303,6 @@
     concurrent_mark()->print_summary_info();
   }
   g1_policy()->print_yg_surv_rate_info();
-  SpecializationStats::print();
 }
 
 #ifndef PRODUCT
@@ -3751,9 +3732,9 @@
 
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
-    int active_workers = workers()->active_workers();
+    uint active_workers = workers()->active_workers();
     double pause_start_sec = os::elapsedTime();
-    g1_policy()->phase_times()->note_gc_start(active_workers);
+    g1_policy()->phase_times()->note_gc_start(active_workers, mark_in_progress());
     log_gc_header();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
@@ -4365,60 +4346,11 @@
   }
 };
 
-class G1CodeBlobClosure : public CodeBlobClosure {
-  class HeapRegionGatheringOopClosure : public OopClosure {
-    G1CollectedHeap* _g1h;
-    OopClosure* _work;
-    nmethod* _nm;
-
-    template <typename T>
-    void do_oop_work(T* p) {
-      _work->do_oop(p);
-      T oop_or_narrowoop = oopDesc::load_heap_oop(p);
-      if (!oopDesc::is_null(oop_or_narrowoop)) {
-        oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
-        HeapRegion* hr = _g1h->heap_region_containing_raw(o);
-        assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
-        hr->add_strong_code_root(_nm);
-      }
-    }
-
-  public:
-    HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {}
-
-    void do_oop(oop* o) {
-      do_oop_work(o);
-    }
-
-    void do_oop(narrowOop* o) {
-      do_oop_work(o);
-    }
-
-    void set_nm(nmethod* nm) {
-      _nm = nm;
-    }
-  };
-
-  HeapRegionGatheringOopClosure _oc;
-public:
-  G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
-
-  void do_code_blob(CodeBlob* cb) {
-    nmethod* nm = cb->as_nmethod_or_null();
-    if (nm != NULL) {
-      if (!nm->test_set_oops_do_mark()) {
-        _oc.set_nm(nm);
-        nm->oops_do(&_oc);
-        nm->fix_oop_relocations();
-      }
-    }
-  }
-};
-
 class G1ParTask : public AbstractGangTask {
 protected:
   G1CollectedHeap*       _g1h;
   RefToScanQueueSet      *_queues;
+  G1RootProcessor*       _root_processor;
   ParallelTaskTerminator _terminator;
   uint _n_workers;
 
@@ -4426,10 +4358,11 @@
   Mutex* stats_lock() { return &_stats_lock; }
 
 public:
-  G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues)
+  G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor)
     : AbstractGangTask("G1 collection"),
       _g1h(g1h),
       _queues(task_queues),
+      _root_processor(root_processor),
       _terminator(0, _queues),
       _stats_lock(Mutex::leaf, "parallel G1 stats lock", true)
   {}
@@ -4443,13 +4376,7 @@
   ParallelTaskTerminator* terminator() { return &_terminator; }
 
   virtual void set_for_termination(int active_workers) {
-    // This task calls set_n_termination() in par_non_clean_card_iterate_work()
-    // in the young space (_par_seq_tasks) in the G1 heap
-    // for SequentialSubTasksDone.
-    // This task also uses SubTasksDone in SharedHeap and G1CollectedHeap
-    // both of which need setting by set_n_termination().
-    _g1h->SharedHeap::set_n_termination(active_workers);
-    _g1h->set_n_termination(active_workers);
+    _root_processor->set_num_workers(active_workers);
     terminator()->reset_for_reuse(active_workers);
     _n_workers = active_workers;
   }
@@ -4486,8 +4413,7 @@
   void work(uint worker_id) {
     if (worker_id >= _n_workers) return;  // no work needed this round
 
-    double start_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->phase_times()->record_gc_worker_start_time(worker_id, start_time_ms);
+    _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerStart, worker_id, os::elapsedTime());
 
     {
       ResourceMark rm;
@@ -4519,24 +4445,21 @@
                                                                                     false, // Process all klasses.
                                                                                     true); // Need to claim CLDs.
 
-      G1CodeBlobClosure scan_only_code_cl(&scan_only_root_cl);
-      G1CodeBlobClosure scan_mark_code_cl(&scan_mark_root_cl);
-      // IM Weak code roots are handled later.
-
       OopClosure* strong_root_cl;
       OopClosure* weak_root_cl;
       CLDClosure* strong_cld_cl;
       CLDClosure* weak_cld_cl;
-      CodeBlobClosure* strong_code_cl;
+
+      bool trace_metadata = false;
 
       if (_g1h->g1_policy()->during_initial_mark_pause()) {
         // We also need to mark copied objects.
         strong_root_cl = &scan_mark_root_cl;
         strong_cld_cl  = &scan_mark_cld_cl;
-        strong_code_cl = &scan_mark_code_cl;
         if (ClassUnloadingWithConcurrentMark) {
           weak_root_cl = &scan_mark_weak_root_cl;
           weak_cld_cl  = &scan_mark_weak_cld_cl;
+          trace_metadata = true;
         } else {
           weak_root_cl = &scan_mark_root_cl;
           weak_cld_cl  = &scan_mark_cld_cl;
@@ -4546,31 +4469,32 @@
         weak_root_cl   = &scan_only_root_cl;
         strong_cld_cl  = &scan_only_cld_cl;
         weak_cld_cl    = &scan_only_cld_cl;
-        strong_code_cl = &scan_only_code_cl;
       }
 
-
-      G1ParPushHeapRSClosure  push_heap_rs_cl(_g1h, &pss);
-
       pss.start_strong_roots();
-      _g1h->g1_process_roots(strong_root_cl,
-                             weak_root_cl,
-                             &push_heap_rs_cl,
-                             strong_cld_cl,
-                             weak_cld_cl,
-                             strong_code_cl,
-                             worker_id);
-
+
+      _root_processor->evacuate_roots(strong_root_cl,
+                                      weak_root_cl,
+                                      strong_cld_cl,
+                                      weak_cld_cl,
+                                      trace_metadata,
+                                      worker_id);
+
+      G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
+      _root_processor->scan_remembered_sets(&push_heap_rs_cl,
+                                            weak_root_cl,
+                                            worker_id);
       pss.end_strong_roots();
 
       {
         double start = os::elapsedTime();
         G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
         evac.do_void();
-        double elapsed_ms = (os::elapsedTime()-start)*1000.0;
-        double term_ms = pss.term_time()*1000.0;
-        _g1h->g1_policy()->phase_times()->add_obj_copy_time(worker_id, elapsed_ms-term_ms);
-        _g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts());
+        double elapsed_sec = os::elapsedTime() - start;
+        double term_sec = pss.term_time();
+        _g1h->g1_policy()->phase_times()->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
+        _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::Termination, worker_id, term_sec);
+        _g1h->g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
       }
       _g1h->g1_policy()->record_thread_age_table(pss.age_table());
       _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
@@ -4586,100 +4510,10 @@
       // destructors are executed here and are included as part of the
       // "GC Worker Time".
     }
-
-    double end_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->phase_times()->record_gc_worker_end_time(worker_id, end_time_ms);
+    _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
   }
 };
 
-// *** Common G1 Evacuation Stuff
-
-// This method is run in a GC worker.
-
-void
-G1CollectedHeap::
-g1_process_roots(OopClosure* scan_non_heap_roots,
-                 OopClosure* scan_non_heap_weak_roots,
-                 G1ParPushHeapRSClosure* scan_rs,
-                 CLDClosure* scan_strong_clds,
-                 CLDClosure* scan_weak_clds,
-                 CodeBlobClosure* scan_strong_code,
-                 uint worker_i) {
-
-  // First scan the shared roots.
-  double ext_roots_start = os::elapsedTime();
-  double closure_app_time_sec = 0.0;
-
-  bool during_im = _g1h->g1_policy()->during_initial_mark_pause();
-  bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark;
-
-  BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
-  BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
-
-  process_roots(false, // no scoping; this is parallel code
-                SharedHeap::SO_None,
-                &buf_scan_non_heap_roots,
-                &buf_scan_non_heap_weak_roots,
-                scan_strong_clds,
-                // Unloading Initial Marks handle the weak CLDs separately.
-                (trace_metadata ? NULL : scan_weak_clds),
-                scan_strong_code);
-
-  // Now the CM ref_processor roots.
-  if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
-    // We need to treat the discovered reference lists of the
-    // concurrent mark ref processor as roots and keep entries
-    // (which are added by the marking threads) on them live
-    // until they can be processed at the end of marking.
-    ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
-  }
-
-  if (trace_metadata) {
-    // Barrier to make sure all workers passed
-    // the strong CLD and strong nmethods phases.
-    active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads());
-
-    // Now take the complement of the strong CLDs.
-    ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
-  }
-
-  // Finish up any enqueued closure apps (attributed as object copy time).
-  buf_scan_non_heap_roots.done();
-  buf_scan_non_heap_weak_roots.done();
-
-  double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
-      + buf_scan_non_heap_weak_roots.closure_app_seconds();
-
-  g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
-
-  double ext_root_time_ms =
-    ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
-
-  g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
-
-  // During conc marking we have to filter the per-thread SATB buffers
-  // to make sure we remove any oops into the CSet (which will show up
-  // as implicitly live).
-  double satb_filtering_ms = 0.0;
-  if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
-    if (mark_in_progress()) {
-      double satb_filter_start = os::elapsedTime();
-
-      JavaThread::satb_mark_queue_set().filter_thread_buffers();
-
-      satb_filtering_ms = (os::elapsedTime() - satb_filter_start) * 1000.0;
-    }
-  }
-  g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
-
-  // Now scan the complement of the collection set.
-  G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
-
-  g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
-
-  _process_strong_tasks->all_tasks_completed();
-}
-
 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
 private:
   BoolObjectClosure* _is_alive;
@@ -5054,14 +4888,13 @@
   G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
 
   virtual void work(uint worker_id) {
-    double start_time = os::elapsedTime();
+    G1GCPhaseTimes* phase_times = G1CollectedHeap::heap()->g1_policy()->phase_times();
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
 
     RedirtyLoggedCardTableEntryClosure cl;
     _queue->par_apply_closure_to_all_completed_buffers(&cl);
 
-    G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
-    timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
-    timer->record_redirty_logged_cards_processed_cards(worker_id, cl.num_processed());
+    phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_processed());
   }
 };
 
@@ -5608,7 +5441,6 @@
   workers()->set_active_workers(n_workers);
   set_par_threads(n_workers);
 
-  G1ParTask g1_par_task(this, _task_queues);
 
   init_for_evac_failure(NULL);
 
@@ -5617,7 +5449,8 @@
   double end_par_time_sec;
 
   {
-    StrongRootsScope srs(this);
+    G1RootProcessor root_processor(this);
+    G1ParTask g1_par_task(this, _task_queues, &root_processor);
     // InitialMark needs claim bits to keep track of the marked-through CLDs.
     if (g1_policy()->during_initial_mark_pause()) {
       ClassLoaderDataGraph::clear_claimed_marks();
@@ -5633,18 +5466,20 @@
     end_par_time_sec = os::elapsedTime();
 
     // Closing the inner scope will execute the destructor
-    // for the StrongRootsScope object. We record the current
+    // for the G1RootProcessor object. We record the current
     // elapsed time before closing the scope so that time
-    // taken for the SRS destructor is NOT included in the
+    // taken for the destructor is NOT included in the
     // reported parallel time.
   }
 
+  G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
+
   double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
-  g1_policy()->phase_times()->record_par_time(par_time_ms);
+  phase_times->record_par_time(par_time_ms);
 
   double code_root_fixup_time_ms =
         (os::elapsedTime() - end_par_time_sec) * 1000.0;
-  g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms);
+  phase_times->record_code_root_fixup_time(code_root_fixup_time_ms);
 
   set_par_threads(0);
 
@@ -5656,9 +5491,14 @@
   process_discovered_references(n_workers);
 
   if (G1StringDedup::is_enabled()) {
+    double fixup_start = os::elapsedTime();
+
     G1STWIsAliveClosure is_alive(this);
     G1KeepAliveClosure keep_alive(this);
-    G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive);
+    G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, phase_times);
+
+    double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
+    phase_times->record_string_dedup_fixup_time(fixup_time_ms);
   }
 
   _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -56,6 +56,7 @@
 class GenerationSpec;
 class OopsInHeapRegionClosure;
 class G1KlassScanClosure;
+class G1ParScanThreadState;
 class ObjectClosure;
 class SpaceClosure;
 class CompactibleSpaceClosure;
@@ -780,22 +781,6 @@
   // statistics or updating free lists.
   void abandon_collection_set(HeapRegion* cs_head);
 
-  // Applies "scan_non_heap_roots" to roots outside the heap,
-  // "scan_rs" to roots inside the heap (having done "set_region" to
-  // indicate the region in which the root resides),
-  // and does "scan_metadata" If "scan_rs" is
-  // NULL, then this step is skipped.  The "worker_i"
-  // param is for use with parallel roots processing, and should be
-  // the "i" of the calling parallel worker thread's work(i) function.
-  // In the sequential case this param will be ignored.
-  void g1_process_roots(OopClosure* scan_non_heap_roots,
-                        OopClosure* scan_non_heap_weak_roots,
-                        G1ParPushHeapRSClosure* scan_rs,
-                        CLDClosure* scan_strong_clds,
-                        CLDClosure* scan_weak_clds,
-                        CodeBlobClosure* scan_strong_code,
-                        uint worker_i);
-
   // The concurrent marker (and the thread it runs in.)
   ConcurrentMark* _cm;
   ConcurrentMarkThread* _cmThread;
@@ -982,21 +967,10 @@
   // of G1CollectedHeap::_gc_time_stamp.
   uint* _worker_cset_start_region_time_stamp;
 
-  enum G1H_process_roots_tasks {
-    G1H_PS_filter_satb_buffers,
-    G1H_PS_refProcessor_oops_do,
-    // Leave this one last.
-    G1H_PS_NumElements
-  };
-
-  SubTasksDone* _process_strong_tasks;
-
   volatile bool _free_regions_coming;
 
 public:
 
-  SubTasksDone* process_strong_tasks() { return _process_strong_tasks; }
-
   void set_refine_cte_cl_concurrency(bool concurrent);
 
   RefToScanQueue *task_queue(int i) const;
@@ -1029,21 +1003,11 @@
   // Initialize weak reference processing.
   virtual void ref_processing_init();
 
-  void set_par_threads(uint t) {
-    SharedHeap::set_par_threads(t);
-    // Done in SharedHeap but oddly there are
-    // two _process_strong_tasks's in a G1CollectedHeap
-    // so do it here too.
-    _process_strong_tasks->set_n_threads(t);
-  }
-
+  // Explicitly import set_par_threads into this scope
+  using SharedHeap::set_par_threads;
   // Set _n_par_threads according to a policy TBD.
   void set_par_threads();
 
-  void set_n_termination(int t) {
-    _process_strong_tasks->set_n_threads(t);
-  }
-
   virtual CollectedHeap::Name kind() const {
     return CollectedHeap::G1CollectedHeap;
   }
@@ -1118,6 +1082,10 @@
   // The number of regions that are completely free.
   uint num_free_regions() const { return _hrm.num_free_regions(); }
 
+  MemoryUsage get_auxiliary_data_memory_usage() const {
+    return _hrm.get_auxiliary_data_memory_usage();
+  }
+
   // The number of regions that are not completely free.
   uint num_used_regions() const { return num_regions() - num_free_regions(); }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -321,7 +321,7 @@
 
 void G1CollectorPolicy::initialize_flags() {
   if (G1HeapRegionSize != HeapRegion::GrainBytes) {
-    FLAG_SET_ERGO(uintx, G1HeapRegionSize, HeapRegion::GrainBytes);
+    FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
   }
 
   if (SurvivorRatio < 1) {
@@ -335,7 +335,7 @@
   uintx max_regions = G1CollectedHeap::heap()->max_regions();
   size_t max_young_size = (size_t)_young_gen_sizer->max_young_length(max_regions) * HeapRegion::GrainBytes;
   if (max_young_size != MaxNewSize) {
-    FLAG_SET_ERGO(uintx, MaxNewSize, max_young_size);
+    FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
   }
 }
 
@@ -1073,7 +1073,7 @@
   if (update_stats) {
     double cost_per_card_ms = 0.0;
     if (_pending_cards > 0) {
-      cost_per_card_ms = phase_times()->average_last_update_rs_time() / (double) _pending_cards;
+      cost_per_card_ms = phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) / (double) _pending_cards;
       _cost_per_card_ms_seq->add(cost_per_card_ms);
     }
 
@@ -1081,7 +1081,7 @@
 
     double cost_per_entry_ms = 0.0;
     if (cards_scanned > 10) {
-      cost_per_entry_ms = phase_times()->average_last_scan_rs_time() / (double) cards_scanned;
+      cost_per_entry_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned;
       if (_last_gc_was_young) {
         _cost_per_entry_ms_seq->add(cost_per_entry_ms);
       } else {
@@ -1123,7 +1123,7 @@
     double cost_per_byte_ms = 0.0;
 
     if (copied_bytes > 0) {
-      cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
+      cost_per_byte_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes;
       if (_in_marking_window) {
         _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
       } else {
@@ -1132,8 +1132,8 @@
     }
 
     double all_other_time_ms = pause_time_ms -
-      (phase_times()->average_last_update_rs_time() + phase_times()->average_last_scan_rs_time()
-      + phase_times()->average_last_obj_copy_time() + phase_times()->average_last_termination_time());
+      (phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) + phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) +
+          phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) + phase_times()->average_time_ms(G1GCPhaseTimes::Termination));
 
     double young_other_time_ms = 0.0;
     if (young_cset_region_length() > 0) {
@@ -1174,8 +1174,8 @@
 
   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
   double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
-  adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
-                               phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
+  adjust_concurrent_refinement(phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS),
+                               phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS), update_rs_time_goal_ms);
 
   _collectionSetChooser->verify();
 }
@@ -2114,19 +2114,19 @@
     _other.add(pause_time_ms - phase_times->accounted_time_ms());
     _root_region_scan_wait.add(phase_times->root_region_scan_wait_time_ms());
     _parallel.add(phase_times->cur_collection_par_time_ms());
-    _ext_root_scan.add(phase_times->average_last_ext_root_scan_time());
-    _satb_filtering.add(phase_times->average_last_satb_filtering_times_ms());
-    _update_rs.add(phase_times->average_last_update_rs_time());
-    _scan_rs.add(phase_times->average_last_scan_rs_time());
-    _obj_copy.add(phase_times->average_last_obj_copy_time());
-    _termination.add(phase_times->average_last_termination_time());
+    _ext_root_scan.add(phase_times->average_time_ms(G1GCPhaseTimes::ExtRootScan));
+    _satb_filtering.add(phase_times->average_time_ms(G1GCPhaseTimes::SATBFiltering));
+    _update_rs.add(phase_times->average_time_ms(G1GCPhaseTimes::UpdateRS));
+    _scan_rs.add(phase_times->average_time_ms(G1GCPhaseTimes::ScanRS));
+    _obj_copy.add(phase_times->average_time_ms(G1GCPhaseTimes::ObjCopy));
+    _termination.add(phase_times->average_time_ms(G1GCPhaseTimes::Termination));
 
-    double parallel_known_time = phase_times->average_last_ext_root_scan_time() +
-      phase_times->average_last_satb_filtering_times_ms() +
-      phase_times->average_last_update_rs_time() +
-      phase_times->average_last_scan_rs_time() +
-      phase_times->average_last_obj_copy_time() +
-      + phase_times->average_last_termination_time();
+    double parallel_known_time = phase_times->average_time_ms(G1GCPhaseTimes::ExtRootScan) +
+      phase_times->average_time_ms(G1GCPhaseTimes::SATBFiltering) +
+      phase_times->average_time_ms(G1GCPhaseTimes::UpdateRS) +
+      phase_times->average_time_ms(G1GCPhaseTimes::ScanRS) +
+      phase_times->average_time_ms(G1GCPhaseTimes::ObjCopy) +
+      phase_times->average_time_ms(G1GCPhaseTimes::Termination);
 
     double parallel_other_time = phase_times->cur_collection_par_time_ms() - parallel_known_time;
     _parallel_other.add(parallel_other_time);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -22,13 +22,13 @@
  *
  */
 
-
 #include "precompiled.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
-#include "runtime/atomic.inline.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/os.hpp"
 
 // Helper class for avoiding interleaved logging
 class LineBuffer: public StackObj {
@@ -71,184 +71,258 @@
     va_end(ap);
   }
 
+  void print_cr() {
+    gclog_or_tty->print_cr("%s", _buffer);
+    _cur = _indent_level * INDENT_CHARS;
+  }
+
   void append_and_print_cr(const char* format, ...)  ATTRIBUTE_PRINTF(2, 3) {
     va_list ap;
     va_start(ap, format);
     vappend(format, ap);
     va_end(ap);
-    gclog_or_tty->print_cr("%s", _buffer);
-    _cur = _indent_level * INDENT_CHARS;
+    print_cr();
   }
 };
 
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED
 template <class T>
-void WorkerDataArray<T>::print(int level, const char* title) {
-  if (_length == 1) {
-    // No need for min, max, average and sum for only one worker
-    LineBuffer buf(level);
-    buf.append("[%s:  ", title);
-    buf.append(_print_format, _data[0]);
-    buf.append_and_print_cr("]");
-    return;
+class WorkerDataArray  : public CHeapObj<mtGC> {
+  friend class G1GCParPhasePrinter;
+  T*          _data;
+  uint        _length;
+  const char* _title;
+  bool        _print_sum;
+  int         _log_level;
+  uint        _indent_level;
+  bool        _enabled;
+
+  WorkerDataArray<size_t>* _thread_work_items;
+
+  NOT_PRODUCT(T uninitialized();)
+
+  // We are caching the sum and average to only have to calculate them once.
+  // This is not done in an MT-safe way. It is intended to allow single
+  // threaded code to call sum() and average() multiple times in any order
+  // without having to worry about the cost.
+  bool   _has_new_data;
+  T      _sum;
+  T      _min;
+  T      _max;
+  double _average;
+
+ public:
+  WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level) :
+    _title(title), _length(0), _print_sum(print_sum), _log_level(log_level), _indent_level(indent_level),
+    _has_new_data(true), _thread_work_items(NULL), _enabled(true) {
+    assert(length > 0, "Must have some workers to store data for");
+    _length = length;
+    _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
+  }
+
+  ~WorkerDataArray() {
+    FREE_C_HEAP_ARRAY(T, _data);
+  }
+
+  void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
+    _thread_work_items = thread_work_items;
+  }
+
+  WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
+
+  void set(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), err_msg("Overwriting data for worker %d in %s", worker_i, _title));
+    _data[worker_i] = value;
+    _has_new_data = true;
+  }
+
+  void set_thread_work_item(uint worker_i, size_t value) {
+    assert(_thread_work_items != NULL, "No sub count");
+    _thread_work_items->set(worker_i, value);
   }
 
-  T min = _data[0];
-  T max = _data[0];
-  T sum = 0;
+  T get(uint worker_i) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data added for worker %d", worker_i));
+    return _data[worker_i];
+  }
+
+  void add(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i));
+    _data[worker_i] += value;
+    _has_new_data = true;
+  }
 
-  LineBuffer buf(level);
-  buf.append("[%s:", title);
-  for (uint i = 0; i < _length; ++i) {
-    T val = _data[i];
-    min = MIN2(val, min);
-    max = MAX2(val, max);
-    sum += val;
-    if (G1Log::finest()) {
-      buf.append("  ");
-      buf.append(_print_format, val);
-    }
+  double average(){
+    calculate_totals();
+    return _average;
+  }
+
+  T sum() {
+    calculate_totals();
+    return _sum;
+  }
+
+  T minimum() {
+    calculate_totals();
+    return _min;
   }
 
-  if (G1Log::finest()) {
-    buf.append_and_print_cr("%s", "");
+  T maximum() {
+    calculate_totals();
+    return _max;
   }
 
-  double avg = (double)sum / (double)_length;
-  buf.append(" Min: ");
-  buf.append(_print_format, min);
-  buf.append(", Avg: ");
-  buf.append("%.1lf", avg); // Always print average as a double
-  buf.append(", Max: ");
-  buf.append(_print_format, max);
-  buf.append(", Diff: ");
-  buf.append(_print_format, max - min);
-  if (_print_sum) {
-    // for things like the start and end times the sum is not
-    // that relevant
-    buf.append(", Sum: ");
-    buf.append(_print_format, sum);
+  void reset() PRODUCT_RETURN;
+  void verify() PRODUCT_RETURN;
+
+  void set_enabled(bool enabled) { _enabled = enabled; }
+
+  int log_level() { return _log_level;  }
+
+ private:
+
+  void calculate_totals(){
+    if (!_has_new_data) {
+      return;
+    }
+
+    _sum = (T)0;
+    _min = _data[0];
+    _max = _min;
+    for (uint i = 0; i < _length; ++i) {
+      T val = _data[i];
+      _sum += val;
+      _min = MIN2(_min, val);
+      _max = MAX2(_max, val);
+    }
+    _average = (double)_sum / (double)_length;
+    _has_new_data = false;
   }
-  buf.append_and_print_cr("]");
-}
-PRAGMA_DIAG_POP
+};
+
 
 #ifndef PRODUCT
 
-template <> const int WorkerDataArray<int>::_uninitialized = -1;
-template <> const double WorkerDataArray<double>::_uninitialized = -1.0;
-template <> const size_t WorkerDataArray<size_t>::_uninitialized = (size_t)-1;
+template <>
+size_t WorkerDataArray<size_t>::uninitialized() {
+  return (size_t)-1;
+}
+
+template <>
+double WorkerDataArray<double>::uninitialized() {
+  return -1.0;
+}
 
 template <class T>
 void WorkerDataArray<T>::reset() {
   for (uint i = 0; i < _length; i++) {
-    _data[i] = (T)_uninitialized;
+    _data[i] = WorkerDataArray<T>::uninitialized();
+  }
+  if (_thread_work_items != NULL) {
+    _thread_work_items->reset();
   }
 }
 
 template <class T>
 void WorkerDataArray<T>::verify() {
+  if (!_enabled) {
+    return;
+  }
+
   for (uint i = 0; i < _length; i++) {
-    assert(_data[i] != _uninitialized,
-        err_msg("Invalid data for worker %u, data: %lf, uninitialized: %lf",
-            i, (double)_data[i], (double)_uninitialized));
+    assert(_data[i] != WorkerDataArray<T>::uninitialized(),
+        err_msg("Invalid data for worker %u in '%s'", i, _title));
+  }
+  if (_thread_work_items != NULL) {
+    _thread_work_items->verify();
   }
 }
 
 #endif
 
 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
-  _max_gc_threads(max_gc_threads),
-  _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
-  _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
-  _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
-  _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
-  _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
-  _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
-  _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
-  _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
-  _last_termination_times_ms(_max_gc_threads, "%.1lf"),
-  _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
-  _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
-  _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
-  _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf"),
-  _last_redirty_logged_cards_time_ms(_max_gc_threads, "%.1lf"),
-  _last_redirty_logged_cards_processed_cards(_max_gc_threads, SIZE_FORMAT),
-  _cur_string_dedup_queue_fixup_worker_times_ms(_max_gc_threads, "%.1lf"),
-  _cur_string_dedup_table_fixup_worker_times_ms(_max_gc_threads, "%.1lf")
+  _max_gc_threads(max_gc_threads)
 {
   assert(max_gc_threads > 0, "Must have some GC threads");
+
+  _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2);
+  _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2);
+
+  // Root scanning phases
+  _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CodeCacheRoots] = new WorkerDataArray<double>(max_gc_threads, "CodeCache Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFinest, 3);
+
+  _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2);
+  _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2);
+
+  _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3);
+  _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers);
+
+  _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts);
+
+  _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2);
+  _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2);
+
+  _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3);
+  _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3);
+  _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
 }
 
-void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
+void G1GCPhaseTimes::note_gc_start(uint active_gc_threads, bool mark_in_progress) {
   assert(active_gc_threads > 0, "The number of threads must be > 0");
-  assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
+  assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads");
   _active_gc_threads = active_gc_threads;
 
-  _last_gc_worker_start_times_ms.reset();
-  _last_ext_root_scan_times_ms.reset();
-  _last_satb_filtering_times_ms.reset();
-  _last_update_rs_times_ms.reset();
-  _last_update_rs_processed_buffers.reset();
-  _last_scan_rs_times_ms.reset();
-  _last_strong_code_root_scan_times_ms.reset();
-  _last_obj_copy_times_ms.reset();
-  _last_termination_times_ms.reset();
-  _last_termination_attempts.reset();
-  _last_gc_worker_end_times_ms.reset();
-  _last_gc_worker_times_ms.reset();
-  _last_gc_worker_other_times_ms.reset();
+  for (int i = 0; i < GCParPhasesSentinel; i++) {
+    _gc_par_phases[i]->reset();
+  }
 
-  _last_redirty_logged_cards_time_ms.reset();
-  _last_redirty_logged_cards_processed_cards.reset();
-
+  _gc_par_phases[StringDedupQueueFixup]->set_enabled(G1StringDedup::is_enabled());
+  _gc_par_phases[StringDedupTableFixup]->set_enabled(G1StringDedup::is_enabled());
 }
 
 void G1GCPhaseTimes::note_gc_end() {
-  _last_gc_worker_start_times_ms.verify();
-  _last_ext_root_scan_times_ms.verify();
-  _last_satb_filtering_times_ms.verify();
-  _last_update_rs_times_ms.verify();
-  _last_update_rs_processed_buffers.verify();
-  _last_scan_rs_times_ms.verify();
-  _last_strong_code_root_scan_times_ms.verify();
-  _last_obj_copy_times_ms.verify();
-  _last_termination_times_ms.verify();
-  _last_termination_attempts.verify();
-  _last_gc_worker_end_times_ms.verify();
+  for (uint i = 0; i < _active_gc_threads; i++) {
+    double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i);
+    record_time_secs(GCWorkerTotal, i , worker_time);
 
-  for (uint i = 0; i < _active_gc_threads; i++) {
-    double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
-    _last_gc_worker_times_ms.set(i, worker_time);
+    double worker_known_time =
+        _gc_par_phases[ExtRootScan]->get(i) +
+        _gc_par_phases[SATBFiltering]->get(i) +
+        _gc_par_phases[UpdateRS]->get(i) +
+        _gc_par_phases[ScanRS]->get(i) +
+        _gc_par_phases[CodeRoots]->get(i) +
+        _gc_par_phases[ObjCopy]->get(i) +
+        _gc_par_phases[Termination]->get(i);
 
-    double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
-                               _last_satb_filtering_times_ms.get(i) +
-                               _last_update_rs_times_ms.get(i) +
-                               _last_scan_rs_times_ms.get(i) +
-                               _last_strong_code_root_scan_times_ms.get(i) +
-                               _last_obj_copy_times_ms.get(i) +
-                               _last_termination_times_ms.get(i);
-
-    double worker_other_time = worker_time - worker_known_time;
-    _last_gc_worker_other_times_ms.set(i, worker_other_time);
+    record_time_secs(Other, i, worker_time - worker_known_time);
   }
 
-  _last_gc_worker_times_ms.verify();
-  _last_gc_worker_other_times_ms.verify();
-
-  _last_redirty_logged_cards_time_ms.verify();
-  _last_redirty_logged_cards_processed_cards.verify();
-}
-
-void G1GCPhaseTimes::note_string_dedup_fixup_start() {
-  _cur_string_dedup_queue_fixup_worker_times_ms.reset();
-  _cur_string_dedup_table_fixup_worker_times_ms.reset();
-}
-
-void G1GCPhaseTimes::note_string_dedup_fixup_end() {
-  _cur_string_dedup_queue_fixup_worker_times_ms.verify();
-  _cur_string_dedup_table_fixup_worker_times_ms.verify();
+  for (int i = 0; i < GCParPhasesSentinel; i++) {
+    _gc_par_phases[i]->verify();
+  }
 }
 
 void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
@@ -288,35 +362,172 @@
     return misc_time_ms;
 }
 
+// record the time a phase took in seconds
+void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) {
+  _gc_par_phases[phase]->set(worker_i, secs);
+}
+
+// add a number of seconds to a phase
+void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) {
+  _gc_par_phases[phase]->add(worker_i, secs);
+}
+
+void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) {
+  _gc_par_phases[phase]->set_thread_work_item(worker_i, count);
+}
+
+// return the average time for a phase in milliseconds
+double G1GCPhaseTimes::average_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->average() * 1000.0;
+}
+
+double G1GCPhaseTimes::get_time_ms(GCParPhases phase, uint worker_i) {
+  return _gc_par_phases[phase]->get(worker_i) * 1000.0;
+}
+
+double G1GCPhaseTimes::sum_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->sum() * 1000.0;
+}
+
+double G1GCPhaseTimes::min_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->minimum() * 1000.0;
+}
+
+double G1GCPhaseTimes::max_time_ms(GCParPhases phase) {
+  return _gc_par_phases[phase]->maximum() * 1000.0;
+}
+
+size_t G1GCPhaseTimes::get_thread_work_item(GCParPhases phase, uint worker_i) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->get(worker_i);
+}
+
+size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->sum();
+}
+
+double G1GCPhaseTimes::average_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->average();
+}
+
+size_t G1GCPhaseTimes::min_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->minimum();
+}
+
+size_t G1GCPhaseTimes::max_thread_work_items(GCParPhases phase) {
+  assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
+  return _gc_par_phases[phase]->thread_work_items()->maximum();
+}
+
+class G1GCParPhasePrinter : public StackObj {
+  G1GCPhaseTimes* _phase_times;
+ public:
+  G1GCParPhasePrinter(G1GCPhaseTimes* phase_times) : _phase_times(phase_times) {}
+
+  void print(G1GCPhaseTimes::GCParPhases phase_id) {
+    WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id];
+
+    if (phase->_log_level > G1Log::level() || !phase->_enabled) {
+      return;
+    }
+
+    if (phase->_length == 1) {
+      print_single_length(phase_id, phase);
+    } else {
+      print_multi_length(phase_id, phase);
+    }
+  }
+
+ private:
+
+  void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    // No need for min, max, average and sum for only one worker
+    LineBuffer buf(phase->_indent_level);
+    buf.append_and_print_cr("[%s:  %.1lf]", phase->_title, _phase_times->get_time_ms(phase_id, 0));
+
+    if (phase->_thread_work_items != NULL) {
+      LineBuffer buf2(phase->_thread_work_items->_indent_level);
+      buf2.append_and_print_cr("[%s:  "SIZE_FORMAT"]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id));
+    }
+  }
+
+  void print_time_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    for (uint i = 0; i < phase->_length; ++i) {
+      buf.append("  %.1lf", _phase_times->get_time_ms(phase_id, i));
+    }
+    buf.print_cr();
+  }
+
+  void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
+    for (uint i = 0; i < thread_work_items->_length; ++i) {
+      buf.append("  " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
+    }
+    buf.print_cr();
+  }
+
+  void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
+    LineBuffer buf(thread_work_items->_indent_level);
+    buf.append("[%s:", thread_work_items->_title);
+
+    if (G1Log::finest()) {
+      print_count_values(buf, phase_id, thread_work_items);
+    }
+
+    assert(thread_work_items->_print_sum, err_msg("%s does not have print sum true even though it is a count", thread_work_items->_title));
+
+    buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
+        _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
+        _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
+  }
+
+  void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
+    LineBuffer buf(phase->_indent_level);
+    buf.append("[%s:", phase->_title);
+
+    if (G1Log::finest()) {
+      print_time_values(buf, phase_id, phase);
+    }
+
+    buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
+        _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
+        _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
+
+    if (phase->_print_sum) {
+      // for things like the start and end times the sum is not
+      // that relevant
+      buf.append(", Sum: %.1lf", _phase_times->sum_time_ms(phase_id));
+    }
+
+    buf.append_and_print_cr("]");
+
+    if (phase->_thread_work_items != NULL) {
+      print_thread_work_items(phase_id, phase->_thread_work_items);
+    }
+  }
+};
+
 void G1GCPhaseTimes::print(double pause_time_sec) {
+  G1GCParPhasePrinter par_phase_printer(this);
+
   if (_root_region_scan_wait_time_ms > 0.0) {
     print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
   }
+
   print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
-  _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
-  _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
-  if (_last_satb_filtering_times_ms.sum() > 0.0) {
-    _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
+  for (int i = 0; i <= GCMainParPhasesLast; i++) {
+    par_phase_printer.print((GCParPhases) i);
   }
-  _last_update_rs_times_ms.print(2, "Update RS (ms)");
-    _last_update_rs_processed_buffers.print(3, "Processed Buffers");
-  _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
-  _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
-  _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
-  _last_termination_times_ms.print(2, "Termination (ms)");
-  if (G1Log::finest()) {
-    _last_termination_attempts.print(3, "Termination Attempts");
-  }
-  _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
-  _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
-  _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
 
   print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
   print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
   if (G1StringDedup::is_enabled()) {
     print_stats(1, "String Dedup Fixup", _cur_string_dedup_fixup_time_ms, _active_gc_threads);
-    _cur_string_dedup_queue_fixup_worker_times_ms.print(2, "Queue Fixup (ms)");
-    _cur_string_dedup_table_fixup_worker_times_ms.print(2, "Table Fixup (ms)");
+    for (int i = StringDedupPhasesFirst; i <= StringDedupPhasesLast; i++) {
+      par_phase_printer.print((GCParPhases) i);
+    }
   }
   print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
   double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
@@ -340,10 +551,7 @@
   print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
   print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
   print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
-  if (G1Log::finest()) {
-    _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty");
-    _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards");
-  }
+  par_phase_printer.print(RedirtyCards);
   if (G1EagerReclaimHumongousObjects) {
     print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
     if (G1Log::finest()) {
@@ -366,3 +574,17 @@
     print_stats(2, "Verify After", _cur_verify_after_time_ms);
   }
 }
+
+G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id) :
+    _phase_times(phase_times), _phase(phase), _worker_id(worker_id) {
+  if (_phase_times != NULL) {
+    _start_time = os::elapsedTime();
+  }
+}
+
+G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() {
+  if (_phase_times != NULL) {
+    _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time);
+  }
+}
+
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -26,106 +26,60 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
 
 #include "memory/allocation.hpp"
-#include "gc_interface/gcCause.hpp"
-
-template <class T>
-class WorkerDataArray  : public CHeapObj<mtGC> {
-  T*          _data;
-  uint        _length;
-  const char* _print_format;
-  bool        _print_sum;
-
-  NOT_PRODUCT(static const T _uninitialized;)
-
-  // We are caching the sum and average to only have to calculate them once.
-  // This is not done in an MT-safe way. It is intended to allow single
-  // threaded code to call sum() and average() multiple times in any order
-  // without having to worry about the cost.
-  bool   _has_new_data;
-  T      _sum;
-  double _average;
-
- public:
-  WorkerDataArray(uint length, const char* print_format, bool print_sum = true) :
-  _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) {
-    assert(length > 0, "Must have some workers to store data for");
-    _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
-  }
-
-  ~WorkerDataArray() {
-    FREE_C_HEAP_ARRAY(T, _data);
-  }
-
-  void set(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i));
-    _data[worker_i] = value;
-    _has_new_data = true;
-  }
 
-  T get(uint worker_i) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
-    return _data[worker_i];
-  }
-
-  void add(uint worker_i, T value) {
-    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
-    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
-    _data[worker_i] += value;
-    _has_new_data = true;
-  }
-
-  double average(){
-    if (_has_new_data) {
-      calculate_totals();
-    }
-    return _average;
-  }
+class LineBuffer;
 
-  T sum() {
-    if (_has_new_data) {
-      calculate_totals();
-    }
-    return _sum;
-  }
-
-  void print(int level, const char* title);
-
-  void reset() PRODUCT_RETURN;
-  void verify() PRODUCT_RETURN;
-
- private:
-
-  void calculate_totals(){
-    _sum = (T)0;
-    for (uint i = 0; i < _length; ++i) {
-      _sum += _data[i];
-    }
-    _average = (double)_sum / (double)_length;
-    _has_new_data = false;
-  }
-};
+template <class T> class WorkerDataArray;
 
 class G1GCPhaseTimes : public CHeapObj<mtGC> {
+  friend class G1GCParPhasePrinter;
 
- private:
   uint _active_gc_threads;
   uint _max_gc_threads;
 
-  WorkerDataArray<double> _last_gc_worker_start_times_ms;
-  WorkerDataArray<double> _last_ext_root_scan_times_ms;
-  WorkerDataArray<double> _last_satb_filtering_times_ms;
-  WorkerDataArray<double> _last_update_rs_times_ms;
-  WorkerDataArray<int>    _last_update_rs_processed_buffers;
-  WorkerDataArray<double> _last_scan_rs_times_ms;
-  WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
-  WorkerDataArray<double> _last_obj_copy_times_ms;
-  WorkerDataArray<double> _last_termination_times_ms;
-  WorkerDataArray<size_t> _last_termination_attempts;
-  WorkerDataArray<double> _last_gc_worker_end_times_ms;
-  WorkerDataArray<double> _last_gc_worker_times_ms;
-  WorkerDataArray<double> _last_gc_worker_other_times_ms;
+ public:
+  enum GCParPhases {
+    GCWorkerStart,
+    ExtRootScan,
+    ThreadRoots,
+    StringTableRoots,
+    UniverseRoots,
+    JNIRoots,
+    ObjectSynchronizerRoots,
+    FlatProfilerRoots,
+    ManagementRoots,
+    SystemDictionaryRoots,
+    CLDGRoots,
+    JVMTIRoots,
+    CodeCacheRoots,
+    CMRefRoots,
+    WaitForStrongCLD,
+    WeakCLDRoots,
+    SATBFiltering,
+    UpdateRS,
+    ScanRS,
+    CodeRoots,
+    ObjCopy,
+    Termination,
+    Other,
+    GCWorkerTotal,
+    GCWorkerEnd,
+    StringDedupQueueFixup,
+    StringDedupTableFixup,
+    RedirtyCards,
+    GCParPhasesSentinel
+  };
+
+ private:
+  // Markers for grouping the phases in the GCPhases enum above
+  static const int GCMainParPhasesLast = GCWorkerEnd;
+  static const int StringDedupPhasesFirst = StringDedupQueueFixup;
+  static const int StringDedupPhasesLast = StringDedupTableFixup;
+
+  WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
+  WorkerDataArray<size_t>* _update_rs_processed_buffers;
+  WorkerDataArray<size_t>* _termination_attempts;
+  WorkerDataArray<size_t>* _redirtied_cards;
 
   double _cur_collection_par_time_ms;
   double _cur_collection_code_root_fixup_time_ms;
@@ -135,9 +89,7 @@
   double _cur_evac_fail_restore_remsets;
   double _cur_evac_fail_remove_self_forwards;
 
-  double                  _cur_string_dedup_fixup_time_ms;
-  WorkerDataArray<double> _cur_string_dedup_queue_fixup_worker_times_ms;
-  WorkerDataArray<double> _cur_string_dedup_table_fixup_worker_times_ms;
+  double _cur_string_dedup_fixup_time_ms;
 
   double _cur_clear_ct_time_ms;
   double _cur_ref_proc_time_ms;
@@ -149,8 +101,6 @@
   double _recorded_young_cset_choice_time_ms;
   double _recorded_non_young_cset_choice_time_ms;
 
-  WorkerDataArray<double> _last_redirty_logged_cards_time_ms;
-  WorkerDataArray<size_t> _last_redirty_logged_cards_processed_cards;
   double _recorded_redirty_logged_cards_time_ms;
 
   double _recorded_young_free_cset_time_ms;
@@ -172,54 +122,34 @@
 
  public:
   G1GCPhaseTimes(uint max_gc_threads);
-  void note_gc_start(uint active_gc_threads);
+  void note_gc_start(uint active_gc_threads, bool mark_in_progress);
   void note_gc_end();
   void print(double pause_time_sec);
 
-  void record_gc_worker_start_time(uint worker_i, double ms) {
-    _last_gc_worker_start_times_ms.set(worker_i, ms);
-  }
-
-  void record_ext_root_scan_time(uint worker_i, double ms) {
-    _last_ext_root_scan_times_ms.set(worker_i, ms);
-  }
+  // record the time a phase took in seconds
+  void record_time_secs(GCParPhases phase, uint worker_i, double secs);
 
-  void record_satb_filtering_time(uint worker_i, double ms) {
-    _last_satb_filtering_times_ms.set(worker_i, ms);
-  }
+  // add a number of seconds to a phase
+  void add_time_secs(GCParPhases phase, uint worker_i, double secs);
 
-  void record_update_rs_time(uint worker_i, double ms) {
-    _last_update_rs_times_ms.set(worker_i, ms);
-  }
+  void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count);
 
-  void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) {
-    _last_update_rs_processed_buffers.set(worker_i, processed_buffers);
-  }
+  // return the average time for a phase in milliseconds
+  double average_time_ms(GCParPhases phase);
 
-  void record_scan_rs_time(uint worker_i, double ms) {
-    _last_scan_rs_times_ms.set(worker_i, ms);
-  }
-
-  void record_strong_code_root_scan_time(uint worker_i, double ms) {
-    _last_strong_code_root_scan_times_ms.set(worker_i, ms);
-  }
-
-  void record_obj_copy_time(uint worker_i, double ms) {
-    _last_obj_copy_times_ms.set(worker_i, ms);
-  }
+  size_t sum_thread_work_items(GCParPhases phase);
 
-  void add_obj_copy_time(uint worker_i, double ms) {
-    _last_obj_copy_times_ms.add(worker_i, ms);
-  }
+ private:
+  double get_time_ms(GCParPhases phase, uint worker_i);
+  double sum_time_ms(GCParPhases phase);
+  double min_time_ms(GCParPhases phase);
+  double max_time_ms(GCParPhases phase);
+  size_t get_thread_work_item(GCParPhases phase, uint worker_i);
+  double average_thread_work_items(GCParPhases phase);
+  size_t min_thread_work_items(GCParPhases phase);
+  size_t max_thread_work_items(GCParPhases phase);
 
-  void record_termination(uint worker_i, double ms, size_t attempts) {
-    _last_termination_times_ms.set(worker_i, ms);
-    _last_termination_attempts.set(worker_i, attempts);
-  }
-
-  void record_gc_worker_end_time(uint worker_i, double ms) {
-    _last_gc_worker_end_times_ms.set(worker_i, ms);
-  }
+ public:
 
   void record_clear_ct_time(double ms) {
     _cur_clear_ct_time_ms = ms;
@@ -249,21 +179,10 @@
     _cur_evac_fail_remove_self_forwards = ms;
   }
 
-  void note_string_dedup_fixup_start();
-  void note_string_dedup_fixup_end();
-
   void record_string_dedup_fixup_time(double ms) {
     _cur_string_dedup_fixup_time_ms = ms;
   }
 
-  void record_string_dedup_queue_fixup_worker_time(uint worker_id, double ms) {
-    _cur_string_dedup_queue_fixup_worker_times_ms.set(worker_id, ms);
-  }
-
-  void record_string_dedup_table_fixup_worker_time(uint worker_id, double ms) {
-    _cur_string_dedup_table_fixup_worker_times_ms.set(worker_id, ms);
-  }
-
   void record_ref_proc_time(double ms) {
     _cur_ref_proc_time_ms = ms;
   }
@@ -303,14 +222,6 @@
     _recorded_non_young_cset_choice_time_ms = time_ms;
   }
 
-  void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) {
-    _last_redirty_logged_cards_time_ms.set(worker_i, time_ms);
-  }
-
-  void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) {
-    _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers);
-  }
-
   void record_redirty_logged_cards_time_ms(double time_ms) {
     _recorded_redirty_logged_cards_time_ms = time_ms;
   }
@@ -364,38 +275,16 @@
   double fast_reclaim_humongous_time_ms() {
     return _cur_fast_reclaim_humongous_time_ms;
   }
-
-  double average_last_update_rs_time() {
-    return _last_update_rs_times_ms.average();
-  }
-
-  int sum_last_update_rs_processed_buffers() {
-    return _last_update_rs_processed_buffers.sum();
-  }
-
-  double average_last_scan_rs_time(){
-    return _last_scan_rs_times_ms.average();
-  }
+};
 
-  double average_last_strong_code_root_scan_time(){
-    return _last_strong_code_root_scan_times_ms.average();
-  }
-
-  double average_last_obj_copy_time() {
-    return _last_obj_copy_times_ms.average();
-  }
-
-  double average_last_termination_time() {
-    return _last_termination_times_ms.average();
-  }
-
-  double average_last_ext_root_scan_time() {
-    return _last_ext_root_scan_times_ms.average();
-  }
-
-  double average_last_satb_filtering_times_ms() {
-    return _last_satb_filtering_times_ms.average();
-  }
+class G1GCParPhaseTimesTracker : public StackObj {
+  double _start_time;
+  G1GCPhaseTimes::GCParPhases _phase;
+  G1GCPhaseTimes* _phase_times;
+  uint _worker_id;
+public:
+  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
+  ~G1GCParPhaseTimesTracker();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -28,6 +28,7 @@
 #include "memory/allocation.hpp"
 
 class G1Log : public AllStatic {
+ public:
   typedef enum {
     LevelNone,
     LevelFine,
@@ -35,6 +36,7 @@
     LevelFinest
   } LogLevel;
 
+ private:
   static LogLevel _level;
 
  public:
@@ -50,6 +52,10 @@
     return _level == LevelFinest;
   }
 
+  static LogLevel level() {
+    return _level;
+  }
+
   static void init();
 };
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -31,6 +31,7 @@
 #include "code/icBuffer.hpp"
 #include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
 #include "gc_implementation/g1/g1StringDedup.hpp"
 #include "gc_implementation/shared/gcHeapSummary.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
@@ -125,21 +126,22 @@
   GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
   GenMarkSweep::trace(" 1");
 
-  SharedHeap* sh = SharedHeap::heap();
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
 
   MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
-  sh->process_strong_roots(true,   // activate StrongRootsScope
-                           SharedHeap::SO_None,
-                           &GenMarkSweep::follow_root_closure,
-                           &GenMarkSweep::follow_cld_closure,
-                           &follow_code_closure);
+  {
+    G1RootProcessor root_processor(g1h);
+    root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
+                                        &GenMarkSweep::follow_cld_closure,
+                                        &follow_code_closure);
+  }
 
   // Process reference objects found during marking
   ReferenceProcessor* rp = GenMarkSweep::ref_processor();
-  assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity");
+  assert(rp == g1h->ref_processor_stw(), "Sanity");
 
   rp->setup_policy(clear_all_softrefs);
   const ReferenceProcessorStats& stats =
@@ -225,6 +227,12 @@
   }
 };
 
+class G1AlwaysTrueClosure: public BoolObjectClosure {
+public:
+  bool do_object_b(oop p) { return true; }
+};
+static G1AlwaysTrueClosure always_true;
+
 void G1MarkSweep::mark_sweep_phase3() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
@@ -232,24 +240,23 @@
   GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
   GenMarkSweep::trace("3");
 
-  SharedHeap* sh = SharedHeap::heap();
-
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
 
   CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
-  sh->process_all_roots(true,  // activate StrongRootsScope
-                        SharedHeap::SO_AllCodeCache,
-                        &GenMarkSweep::adjust_pointer_closure,
-                        &GenMarkSweep::adjust_cld_closure,
-                        &adjust_code_closure);
+  {
+    G1RootProcessor root_processor(g1h);
+    root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure,
+                                     &GenMarkSweep::adjust_cld_closure,
+                                     &adjust_code_closure);
+  }
 
   assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
   g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
 
   // Now adjust pointers in remaining weak roots.  (All of which should
   // have been cleared if they pointed to non-surviving objects.)
-  sh->process_weak_roots(&GenMarkSweep::adjust_pointer_closure);
+  JNIHandles::weak_oops_do(&always_true, &GenMarkSweep::adjust_pointer_closure);
 
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -109,6 +109,18 @@
   template <class T> void do_klass_barrier(T* p, oop new_obj);
 };
 
+enum G1Barrier {
+  G1BarrierNone,
+  G1BarrierEvac,
+  G1BarrierKlass
+};
+
+enum G1Mark {
+  G1MarkNone,
+  G1MarkFromRoot,
+  G1MarkPromotedFromRoot
+};
+
 template <G1Barrier barrier, G1Mark do_mark_object>
 class G1ParCopyClosure : public G1ParCopyHelper {
 private:
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -226,6 +226,8 @@
   }
 
   assert(obj_ptr != NULL, "when we get here, allocation should have succeeded");
+  assert(_g1h->is_in_reserved(obj_ptr), "Allocated memory should be in the heap");
+
 #ifndef PRODUCT
   // Should this evacuation fail?
   if (_g1h->evacuation_should_fail()) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,9 @@
  public:
   MemRegion reserved() { return _storage.reserved(); }
 
+  size_t reserved_size() { return _storage.reserved_size(); }
+  size_t committed_size() { return _storage.committed_size(); }
+
   void set_mapping_changed_listener(G1MappingChangedListener* listener) { _listener = listener; }
 
   virtual ~G1RegionToSpaceMapper() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,6 @@
     _cards_scanned(NULL), _total_cards_scanned(0),
     _prev_period_summary()
 {
-  _seq_task = new SubTasksDone(NumSeqTasks);
   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
@@ -90,7 +89,6 @@
 }
 
 G1RemSet::~G1RemSet() {
-  delete _seq_task;
   for (uint i = 0; i < n_workers(); i++) {
     assert(_cset_rs_update_cl[i] == NULL, "it should be");
   }
@@ -109,7 +107,7 @@
 
   double _strong_code_root_scan_time_sec;
   uint   _worker_i;
-  int    _block_size;
+  size_t _block_size;
   bool   _try_claimed;
 
 public:
@@ -127,7 +125,7 @@
     _g1h = G1CollectedHeap::heap();
     _bot_shared = _g1h->bot_shared();
     _ct_bs = _g1h->g1_barrier_set();
-    _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
+    _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
   }
 
   void set_try_claimed() { _try_claimed = true; }
@@ -248,9 +246,8 @@
   assert(_cards_scanned != NULL, "invariant");
   _cards_scanned[worker_i] = scanRScl.cards_done();
 
-  _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
-  _g1p->phase_times()->record_strong_code_root_scan_time(worker_i,
-                                                         scanRScl.strong_code_root_scan_time_sec() * 1000.0);
+  _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
+  _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, scanRScl.strong_code_root_scan_time_sec());
 }
 
 // Closure used for updating RSets and recording references that
@@ -287,13 +284,11 @@
 };
 
 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) {
-  double start = os::elapsedTime();
+  G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
   // Apply the given closure to all remaining log entries.
   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
 
   _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);
-
-  _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
 }
 
 void G1RemSet::cleanupHRRS() {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -58,7 +58,6 @@
   };
 
   CardTableModRefBS*     _ct_bs;
-  SubTasksDone*          _seq_task;
   G1CollectorPolicy*     _g1p;
 
   ConcurrentG1Refine*    _cg1r;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "classfile/stringTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "code/codeCache.hpp"
+#include "gc_implementation/g1/bufferingOopClosure.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RootProcessor.hpp"
+#include "memory/allocation.inline.hpp"
+#include "runtime/fprofiler.hpp"
+#include "runtime/mutex.hpp"
+#include "services/management.hpp"
+
+class G1CodeBlobClosure : public CodeBlobClosure {
+  class HeapRegionGatheringOopClosure : public OopClosure {
+    G1CollectedHeap* _g1h;
+    OopClosure* _work;
+    nmethod* _nm;
+
+    template <typename T>
+    void do_oop_work(T* p) {
+      _work->do_oop(p);
+      T oop_or_narrowoop = oopDesc::load_heap_oop(p);
+      if (!oopDesc::is_null(oop_or_narrowoop)) {
+        oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop);
+        HeapRegion* hr = _g1h->heap_region_containing_raw(o);
+        assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset");
+        hr->add_strong_code_root(_nm);
+      }
+    }
+
+  public:
+    HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {}
+
+    void do_oop(oop* o) {
+      do_oop_work(o);
+    }
+
+    void do_oop(narrowOop* o) {
+      do_oop_work(o);
+    }
+
+    void set_nm(nmethod* nm) {
+      _nm = nm;
+    }
+  };
+
+  HeapRegionGatheringOopClosure _oc;
+public:
+  G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
+
+  void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = cb->as_nmethod_or_null();
+    if (nm != NULL) {
+      if (!nm->test_set_oops_do_mark()) {
+        _oc.set_nm(nm);
+        nm->oops_do(&_oc);
+        nm->fix_oop_relocations();
+      }
+    }
+  }
+};
+
+
+void G1RootProcessor::worker_has_discovered_all_strong_classes() {
+  uint n_workers = _g1h->n_par_threads();
+  assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
+
+  uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
+  if (new_value == n_workers) {
+    // This thread is last. Notify the others.
+    MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
+    _lock.notify_all();
+  }
+}
+
+void G1RootProcessor::wait_until_all_strong_classes_discovered() {
+  uint n_workers = _g1h->n_par_threads();
+  assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
+
+  if ((uint)_n_workers_discovered_strong_classes != n_workers) {
+    MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
+    while ((uint)_n_workers_discovered_strong_classes != n_workers) {
+      _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
+    }
+  }
+}
+
+G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) :
+    _g1h(g1h),
+    _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
+    _srs(g1h),
+    _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
+    _n_workers_discovered_strong_classes(0) {}
+
+void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
+                                     OopClosure* scan_non_heap_weak_roots,
+                                     CLDClosure* scan_strong_clds,
+                                     CLDClosure* scan_weak_clds,
+                                     bool trace_metadata,
+                                     uint worker_i) {
+  // First scan the shared roots.
+  double ext_roots_start = os::elapsedTime();
+  G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
+
+  BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
+  BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
+
+  OopClosure* const weak_roots = &buf_scan_non_heap_weak_roots;
+  OopClosure* const strong_roots = &buf_scan_non_heap_roots;
+
+  // CodeBlobClosures are not interoperable with BufferingOopClosures
+  G1CodeBlobClosure root_code_blobs(scan_non_heap_roots);
+
+  process_java_roots(strong_roots,
+                     trace_metadata ? scan_strong_clds : NULL,
+                     scan_strong_clds,
+                     trace_metadata ? NULL : scan_weak_clds,
+                     &root_code_blobs,
+                     phase_times,
+                     worker_i);
+
+  // This is the point where this worker thread will not find more strong CLDs/nmethods.
+  // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
+  if (trace_metadata) {
+    worker_has_discovered_all_strong_classes();
+  }
+
+  process_vm_roots(strong_roots, weak_roots, phase_times, worker_i);
+
+  {
+    // Now the CM ref_processor roots.
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
+      // We need to treat the discovered reference lists of the
+      // concurrent mark ref processor as roots and keep entries
+      // (which are added by the marking threads) on them live
+      // until they can be processed at the end of marking.
+      _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
+    }
+  }
+
+  if (trace_metadata) {
+    {
+      G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
+      // Barrier to make sure all workers passed
+      // the strong CLD and strong nmethods phases.
+      wait_until_all_strong_classes_discovered();
+    }
+
+    // Now take the complement of the strong CLDs.
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
+    ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
+  } else {
+    phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
+    phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
+  }
+
+  // Finish up any enqueued closure apps (attributed as object copy time).
+  buf_scan_non_heap_roots.done();
+  buf_scan_non_heap_weak_roots.done();
+
+  double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
+      + buf_scan_non_heap_weak_roots.closure_app_seconds();
+
+  phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec);
+
+  double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec;
+
+  phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
+
+  // During conc marking we have to filter the per-thread SATB buffers
+  // to make sure we remove any oops into the CSet (which will show up
+  // as implicitly live).
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) {
+      JavaThread::satb_mark_queue_set().filter_thread_buffers();
+    }
+  }
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_strong_roots(OopClosure* oops,
+                                           CLDClosure* clds,
+                                           CodeBlobClosure* blobs) {
+
+  process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0);
+  process_vm_roots(oops, NULL, NULL, 0);
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_all_roots(OopClosure* oops,
+                                        CLDClosure* clds,
+                                        CodeBlobClosure* blobs) {
+
+  process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
+  process_vm_roots(oops, oops, NULL, 0);
+
+  if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
+    CodeCache::blobs_do(blobs);
+  }
+
+  _process_strong_tasks->all_tasks_completed();
+}
+
+void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
+                                         CLDClosure* thread_stack_clds,
+                                         CLDClosure* strong_clds,
+                                         CLDClosure* weak_clds,
+                                         CodeBlobClosure* strong_code,
+                                         G1GCPhaseTimes* phase_times,
+                                         uint worker_i) {
+  assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set");
+  // Iterating over the CLDG and the Threads are done early to allow us to
+  // first process the strong CLDs and nmethods and then, after a barrier,
+  // let the thread process the weak CLDs and nmethods.
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
+      ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
+    Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code);
+  }
+}
+
+void G1RootProcessor::process_vm_roots(OopClosure* strong_roots,
+                                       OopClosure* weak_roots,
+                                       G1GCPhaseTimes* phase_times,
+                                       uint worker_i) {
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) {
+      Universe::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) {
+      JNIHandles::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i);
+    if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) {
+      ObjectSynchronizer::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::FlatProfilerRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) {
+      FlatProfiler::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) {
+      Management::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) {
+      JvmtiExport::oops_do(strong_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
+    if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
+      SystemDictionary::roots_oops_do(strong_roots, weak_roots);
+    }
+  }
+
+  {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
+    // All threads execute the following. A specific chunk of buckets
+    // from the StringTable are the individual tasks.
+    if (weak_roots != NULL) {
+      StringTable::possibly_parallel_oops_do(weak_roots);
+    }
+  }
+}
+
+void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
+                                           OopClosure* scan_non_heap_weak_roots,
+                                           uint worker_i) {
+  G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
+  G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CodeCacheRoots, worker_i);
+
+  // Now scan the complement of the collection set.
+  G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
+
+  _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
+}
+
+void G1RootProcessor::set_num_workers(int active_workers) {
+  _process_strong_tasks->set_n_threads(active_workers);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/sharedHeap.hpp"
+#include "runtime/mutex.hpp"
+
+class CLDClosure;
+class CodeBlobClosure;
+class G1CollectedHeap;
+class G1GCPhaseTimes;
+class G1ParPushHeapRSClosure;
+class Monitor;
+class OopClosure;
+class SubTasksDone;
+
+// Scoped object to assist in applying oop, CLD and code blob closures to
+// root locations. Handles claiming of different root scanning tasks
+// and takes care of global state for root scanning via a StrongRootsScope.
+// In the parallel case there is a shared G1RootProcessor object where all
+// worker thread call the process_roots methods.
+class G1RootProcessor : public StackObj {
+  G1CollectedHeap* _g1h;
+  SubTasksDone* _process_strong_tasks;
+  SharedHeap::StrongRootsScope _srs;
+
+  // Used to implement the Thread work barrier.
+  Monitor _lock;
+  volatile jint _n_workers_discovered_strong_classes;
+
+  enum G1H_process_roots_tasks {
+    G1RP_PS_Universe_oops_do,
+    G1RP_PS_JNIHandles_oops_do,
+    G1RP_PS_ObjectSynchronizer_oops_do,
+    G1RP_PS_FlatProfiler_oops_do,
+    G1RP_PS_Management_oops_do,
+    G1RP_PS_SystemDictionary_oops_do,
+    G1RP_PS_ClassLoaderDataGraph_oops_do,
+    G1RP_PS_jvmti_oops_do,
+    G1RP_PS_CodeCache_oops_do,
+    G1RP_PS_filter_satb_buffers,
+    G1RP_PS_refProcessor_oops_do,
+    // Leave this one last.
+    G1RP_PS_NumElements
+  };
+
+  void worker_has_discovered_all_strong_classes();
+  void wait_until_all_strong_classes_discovered();
+
+  void process_java_roots(OopClosure* scan_non_heap_roots,
+                          CLDClosure* thread_stack_clds,
+                          CLDClosure* scan_strong_clds,
+                          CLDClosure* scan_weak_clds,
+                          CodeBlobClosure* scan_strong_code,
+                          G1GCPhaseTimes* phase_times,
+                          uint worker_i);
+
+  void process_vm_roots(OopClosure* scan_non_heap_roots,
+                        OopClosure* scan_non_heap_weak_roots,
+                        G1GCPhaseTimes* phase_times,
+                        uint worker_i);
+
+public:
+  G1RootProcessor(G1CollectedHeap* g1h);
+
+  // Apply closures to the strongly and weakly reachable roots in the system
+  // in a single pass.
+  // Record and report timing measurements for sub phases using the worker_i
+  void evacuate_roots(OopClosure* scan_non_heap_roots,
+                      OopClosure* scan_non_heap_weak_roots,
+                      CLDClosure* scan_strong_clds,
+                      CLDClosure* scan_weak_clds,
+                      bool trace_metadata,
+                      uint worker_i);
+
+  // Apply oops, clds and blobs to all strongly reachable roots in the system
+  void process_strong_roots(OopClosure* oops,
+                            CLDClosure* clds,
+                            CodeBlobClosure* blobs);
+
+  // Apply oops, clds and blobs to strongly and weakly reachable roots in the system
+  void process_all_roots(OopClosure* oops,
+                         CLDClosure* clds,
+                         CodeBlobClosure* blobs);
+
+  // Apply scan_rs to all locations in the union of the remembered sets for all
+  // regions in the collection set
+  // (having done "set_region" to indicate the region in which the root resides),
+  void scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
+                            OopClosure* scan_non_heap_weak_roots,
+                            uint worker_i);
+
+  // Inform the root processor about the number of worker threads
+  void set_num_workers(int active_workers);
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -106,7 +106,7 @@
 
 void G1StringDedup::oops_do(OopClosure* keep_alive) {
   assert(is_enabled(), "String deduplication not enabled");
-  unlink_or_oops_do(NULL, keep_alive);
+  unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */);
 }
 
 void G1StringDedup::unlink(BoolObjectClosure* is_alive) {
@@ -123,45 +123,39 @@
 class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask {
 private:
   G1StringDedupUnlinkOrOopsDoClosure _cl;
+  G1GCPhaseTimes* _phase_times;
 
 public:
   G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive,
                                   OopClosure* keep_alive,
-                                  bool allow_resize_and_rehash) :
+                                  bool allow_resize_and_rehash,
+                                  G1GCPhaseTimes* phase_times) :
     AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"),
-    _cl(is_alive, keep_alive, allow_resize_and_rehash) {
-  }
+    _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { }
 
   virtual void work(uint worker_id) {
-    double queue_fixup_start = os::elapsedTime();
-    G1StringDedupQueue::unlink_or_oops_do(&_cl);
-
-    double table_fixup_start = os::elapsedTime();
-    G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
-
-    double queue_fixup_time_ms = (table_fixup_start - queue_fixup_start) * 1000.0;
-    double table_fixup_time_ms = (os::elapsedTime() - table_fixup_start) * 1000.0;
-    G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
-    g1p->phase_times()->record_string_dedup_queue_fixup_worker_time(worker_id, queue_fixup_time_ms);
-    g1p->phase_times()->record_string_dedup_table_fixup_worker_time(worker_id, table_fixup_time_ms);
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
+      G1StringDedupQueue::unlink_or_oops_do(&_cl);
+    }
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
+      G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
+    }
   }
 };
 
-void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool allow_resize_and_rehash) {
+void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive,
+                                      OopClosure* keep_alive,
+                                      bool allow_resize_and_rehash,
+                                      G1GCPhaseTimes* phase_times) {
   assert(is_enabled(), "String deduplication not enabled");
-  G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
-  g1p->phase_times()->note_string_dedup_fixup_start();
-  double fixup_start = os::elapsedTime();
 
-  G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash);
+  G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times);
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   g1h->set_par_threads();
   g1h->workers()->run_task(&task);
   g1h->set_par_threads(0);
-
-  double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
-  g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
-  g1p->phase_times()->note_string_dedup_fixup_end();
 }
 
 void G1StringDedup::threads_do(ThreadClosure* tc) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -91,6 +91,7 @@
 class ThreadClosure;
 class outputStream;
 class G1StringDedupTable;
+class G1GCPhaseTimes;
 
 //
 // Main interface for interacting with string deduplication.
@@ -131,7 +132,7 @@
   static void oops_do(OopClosure* keep_alive);
   static void unlink(BoolObjectClosure* is_alive);
   static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive,
-                                bool allow_resize_and_rehash = true);
+                                bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL);
 
   static void threads_do(ThreadClosure* tc);
   static void print_worker_threads_on(outputStream* st);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
           "If true, enable reference discovery during concurrent "          \
           "marking and reference processing at the end of remark.")         \
                                                                             \
-  product(intx, G1SATBBufferSize, 1*K,                                      \
+  product(size_t, G1SATBBufferSize, 1*K,                                    \
           "Number of entries in an SATB log buffer.")                       \
                                                                             \
   develop(intx, G1SATBProcessCompletedThreshold, 20,                        \
@@ -112,7 +112,7 @@
             "Prints the liveness information for all regions in the heap "  \
             "at the end of a marking cycle.")                               \
                                                                             \
-  product(intx, G1UpdateBufferSize, 256,                                    \
+  product(size_t, G1UpdateBufferSize, 256,                                  \
           "Size of an update buffer")                                       \
                                                                             \
   product(intx, G1ConcRefinementYellowZone, 0,                              \
@@ -148,7 +148,7 @@
           "Select green, yellow and red zones adaptively to meet the "      \
           "the pause requirements.")                                        \
                                                                             \
-  product(uintx, G1ConcRSLogCacheSize, 10,                                  \
+  product(size_t, G1ConcRSLogCacheSize, 10,                                 \
           "Log base 2 of the length of conc RS hot-card cache.")            \
                                                                             \
   product(uintx, G1ConcRSHotCardLimit, 4,                                   \
@@ -210,7 +210,7 @@
           "When set, G1 will fail when it encounters an FP 'error', "       \
           "so as to allow debugging")                                       \
                                                                             \
-  product(uintx, G1HeapRegionSize, 0,                                       \
+  product(size_t, G1HeapRegionSize, 0,                                      \
           "Size of the G1 regions.")                                        \
                                                                             \
   product(uintx, G1ConcRefinementThreads, 0,                                \
@@ -220,7 +220,7 @@
   develop(bool, G1VerifyCTCleanup, false,                                   \
           "Verify card table cleanup.")                                     \
                                                                             \
-  product(uintx, G1RSetScanBlockSize, 64,                                   \
+  product(size_t, G1RSetScanBlockSize, 64,                                  \
           "Size of a work unit of cards claimed by a worker thread"         \
           "during RSet scanning.")                                          \
                                                                             \
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,23 +30,8 @@
 // non-virtually, using a mechanism defined in this file.  Extend these
 // macros in the obvious way to add specializations for new closures.
 
-enum G1Barrier {
-  G1BarrierNone,
-  G1BarrierEvac,
-  G1BarrierKlass
-};
-
-enum G1Mark {
-  G1MarkNone,
-  G1MarkFromRoot,
-  G1MarkPromotedFromRoot
-};
-
 // Forward declarations.
 
-template<G1Barrier barrier, G1Mark do_mark_object>
-class G1ParCopyClosure;
-
 class G1ParScanClosure;
 class G1ParPushHeapRSClosure;
 
@@ -61,26 +46,16 @@
 class G1InvokeIfNotTriggeredClosure;
 class G1UpdateRSOrPushRefOopClosure;
 
-#ifdef FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES
-#error "FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES already defined."
-#endif
-
-#define FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) \
-      f(G1ParScanClosure,_nv)                           \
-      f(G1ParPushHeapRSClosure,_nv)                     \
-      f(FilterIntoCSClosure,_nv)                        \
-      f(FilterOutOfRegionClosure,_nv)                   \
-      f(G1CMOopClosure,_nv)                             \
-      f(G1RootRegionScanClosure,_nv)                    \
-      f(G1Mux2Closure,_nv)                              \
-      f(G1TriggerClosure,_nv)                           \
-      f(G1InvokeIfNotTriggeredClosure,_nv)              \
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f) \
+      f(G1ParScanClosure,_nv)                      \
+      f(G1ParPushHeapRSClosure,_nv)                \
+      f(FilterIntoCSClosure,_nv)                   \
+      f(FilterOutOfRegionClosure,_nv)              \
+      f(G1CMOopClosure,_nv)                        \
+      f(G1RootRegionScanClosure,_nv)               \
+      f(G1Mux2Closure,_nv)                         \
+      f(G1TriggerClosure,_nv)                      \
+      f(G1InvokeIfNotTriggeredClosure,_nv)         \
       f(G1UpdateRSOrPushRefOopClosure,_nv)
 
-#ifdef FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES
-#error "FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES already defined."
-#endif
-
-#define FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
-
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1_SPECIALIZED_OOP_CLOSURES_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -106,18 +106,18 @@
 }
 
 void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
-  uintx region_size = G1HeapRegionSize;
+  size_t region_size = G1HeapRegionSize;
   if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
     size_t average_heap_size = (initial_heap_size + max_heap_size) / 2;
     region_size = MAX2(average_heap_size / HeapRegionBounds::target_number(),
-                       (uintx) HeapRegionBounds::min_size());
+                       HeapRegionBounds::min_size());
   }
 
   int region_size_log = log2_long((jlong) region_size);
   // Recalculate the region size to make sure it's a power of
   // 2. This means that region_size is the largest power of 2 that's
   // <= what we've calculated so far.
-  region_size = ((uintx)1 << region_size_log);
+  region_size = ((size_t)1 << region_size_log);
 
   // Now make sure that we don't go over or under our limits.
   if (region_size < HeapRegionBounds::min_size()) {
@@ -139,7 +139,7 @@
   guarantee(GrainBytes == 0, "we should only set it once");
   // The cast to int is safe, given that we've bounded region_size by
   // MIN_REGION_SIZE and MAX_REGION_SIZE.
-  GrainBytes = (size_t)region_size;
+  GrainBytes = region_size;
 
   guarantee(GrainWords == 0, "we should only set it once");
   GrainWords = GrainBytes >> LogHeapWordSize;
@@ -933,6 +933,16 @@
   _offsets.resize(new_end - bottom());
 }
 
+#ifndef PRODUCT
+void G1OffsetTableContigSpace::mangle_unused_area() {
+  mangle_unused_area_complete();
+}
+
+void G1OffsetTableContigSpace::mangle_unused_area_complete() {
+  SpaceMangler::mangle_region(MemRegion(top(), end()));
+}
+#endif
+
 void G1OffsetTableContigSpace::print() const {
   print_short();
   gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", "
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -27,7 +27,6 @@
 
 #include "gc_implementation/g1/g1AllocationContext.hpp"
 #include "gc_implementation/g1/g1BlockOffsetTable.hpp"
-#include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
 #include "gc_implementation/g1/heapRegionType.hpp"
 #include "gc_implementation/g1/survRateGroup.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
@@ -155,6 +154,9 @@
   void set_bottom(HeapWord* value);
   void set_end(HeapWord* value);
 
+  void mangle_unused_area() PRODUCT_RETURN;
+  void mangle_unused_area_complete() PRODUCT_RETURN;
+
   HeapWord* scan_top() const;
   void record_timestamp();
   void reset_gc_time_stamp() { _gc_time_stamp = 0; }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -145,6 +145,24 @@
   }
 }
 
+MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
+  size_t used_sz =
+    _prev_bitmap_mapper->committed_size() +
+    _next_bitmap_mapper->committed_size() +
+    _bot_mapper->committed_size() +
+    _cardtable_mapper->committed_size() +
+    _card_counts_mapper->committed_size();
+
+  size_t committed_sz =
+    _prev_bitmap_mapper->reserved_size() +
+    _next_bitmap_mapper->reserved_size() +
+    _bot_mapper->reserved_size() +
+    _cardtable_mapper->reserved_size() +
+    _card_counts_mapper->reserved_size();
+
+  return MemoryUsage(0, used_sz, committed_sz, committed_sz);
+}
+
 uint HeapRegionManager::expand_by(uint num_regions) {
   return expand_at(0, num_regions);
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "gc_implementation/g1/g1BiasedArray.hpp"
 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
 #include "gc_implementation/g1/heapRegionSet.hpp"
+#include "services/memoryUsage.hpp"
 
 class HeapRegion;
 class HeapRegionClosure;
@@ -196,6 +197,8 @@
   // Return the maximum number of regions in the heap.
   uint max_length() const { return (uint)_regions.length(); }
 
+  MemoryUsage get_auxiliary_data_memory_usage() const;
+
   MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
 
   // Expand the sequence to reflect that the heap has grown. Either create new
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
 #include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
@@ -325,7 +326,7 @@
 private:
   ParallelTaskTerminator& _term;
   ParNewGeneration&       _gen;
-  Generation&             _next_gen;
+  Generation&             _old_gen;
  public:
   bool is_valid(int id) const { return id < length(); }
   ParallelTaskTerminator* terminator() { return &_term; }
@@ -338,7 +339,7 @@
   Stack<oop, mtGC>* overflow_stacks,
   size_t desired_plab_sz, ParallelTaskTerminator& term)
   : ResourceArray(sizeof(ParScanThreadState), num_threads),
-    _gen(gen), _next_gen(old_gen), _term(term)
+    _gen(gen), _old_gen(old_gen), _term(term)
 {
   assert(num_threads > 0, "sanity check!");
   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
@@ -471,8 +472,8 @@
     _gen.age_table()->merge(local_table);
 
     // Inform old gen that we're done.
-    _next_gen.par_promote_alloc_done(i);
-    _next_gen.par_oop_since_save_marks_iterate_done(i);
+    _old_gen.par_promote_alloc_done(i);
+    _old_gen.par_oop_since_save_marks_iterate_done(i);
   }
 
   if (UseConcMarkSweepGC) {
@@ -574,10 +575,10 @@
   par_scan_state()->end_term_time();
 }
 
-ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* next_gen,
-                HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
+ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen,
+                             HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
     AbstractGangTask("ParNewGeneration collection"),
-    _gen(gen), _next_gen(next_gen),
+    _gen(gen), _old_gen(old_gen),
     _young_old_boundary(young_old_boundary),
     _state_set(state_set)
   {}
@@ -601,8 +602,6 @@
   // We would need multiple old-gen queues otherwise.
   assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
 
-  Generation* old_gen = gch->next_gen(_gen);
-
   ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id);
   assert(_state_set->is_valid(worker_id), "Should not have been called");
 
@@ -619,7 +618,7 @@
                          true,  // Process younger gens, if any,
                                 // as strong roots.
                          false, // no scope; this is parallel code
-                         SharedHeap::SO_ScavengeCodeCache,
+                         GenCollectedHeap::SO_ScavengeCodeCache,
                          GenCollectedHeap::StrongAndWeakRoots,
                          &par_scan_state.to_space_root_closure(),
                          &par_scan_state.older_gen_closure(),
@@ -763,8 +762,9 @@
 class ParNewRefProcTaskProxy: public AbstractGangTask {
   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
 public:
-  ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
-                         Generation& next_gen,
+  ParNewRefProcTaskProxy(ProcessTask& task,
+                         ParNewGeneration& gen,
+                         Generation& old_gen,
                          HeapWord* young_old_boundary,
                          ParScanThreadStateSet& state_set);
 
@@ -776,20 +776,20 @@
 private:
   ParNewGeneration&      _gen;
   ProcessTask&           _task;
-  Generation&            _next_gen;
+  Generation&            _old_gen;
   HeapWord*              _young_old_boundary;
   ParScanThreadStateSet& _state_set;
 };
 
-ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
-    ProcessTask& task, ParNewGeneration& gen,
-    Generation& next_gen,
-    HeapWord* young_old_boundary,
-    ParScanThreadStateSet& state_set)
+ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task,
+                                               ParNewGeneration& gen,
+                                               Generation& old_gen,
+                                               HeapWord* young_old_boundary,
+                                               ParScanThreadStateSet& state_set)
   : AbstractGangTask("ParNewGeneration parallel reference processing"),
     _gen(gen),
     _task(task),
-    _next_gen(next_gen),
+    _old_gen(old_gen),
     _young_old_boundary(young_old_boundary),
     _state_set(state_set)
 {
@@ -893,7 +893,7 @@
   from()->set_next_compaction_space(to());
   gch->set_incremental_collection_failed();
   // Inform the next generation that a promotion failure occurred.
-  _next_gen->promotion_failure_occurred();
+  _old_gen->promotion_failure_occurred();
 
   // Trace promotion failure in the parallel GC threads
   thread_state_set.trace_promotion_failed(gc_tracer());
@@ -927,7 +927,7 @@
   workers->set_active_workers(active_workers);
   assert(gch->n_gens() == 2,
          "Par collection currently only works with single older gen.");
-  _next_gen = gch->next_gen(this);
+  _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate worst-case promotion
   // from this generation, pass on collection; let the next generation
@@ -952,8 +952,6 @@
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
-  SpecializationStats::clear();
-
   age_table()->clear();
   to()->clear(SpaceDecorator::Mangle);
 
@@ -968,10 +966,10 @@
   // because only those workers go through the termination protocol.
   ParallelTaskTerminator _term(n_workers, task_queues());
   ParScanThreadStateSet thread_state_set(workers->active_workers(),
-                                         *to(), *this, *_next_gen, *task_queues(),
+                                         *to(), *this, *_old_gen, *task_queues(),
                                          _overflow_stacks, desired_plab_sz(), _term);
 
-  ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
+  ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set);
   gch->set_par_threads(n_workers);
   gch->rem_set()->prepare_for_younger_refs_iterate(true);
   // It turns out that even when we're using 1 thread, doing the work in a
@@ -1073,8 +1071,6 @@
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   update_time_of_last_gc(now);
 
-  SpecializationStats::print();
-
   rp->set_enqueuing_is_done(true);
   if (rp->processing_is_mt()) {
     ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
@@ -1127,14 +1123,6 @@
   return forward_ptr;
 }
 
-#ifdef ASSERT
-bool ParNewGeneration::is_legal_forward_ptr(oop p) {
-  return
-    (p == ClaimedForwardPtr)
-    || Universe::heap()->is_in_reserved(p);
-}
-#endif
-
 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
   if (m->must_be_preserved_for_promotion_failure(obj)) {
     // We should really have separate per-worker stacks, rather
@@ -1191,8 +1179,8 @@
     }
 
     if (!_promotion_failed) {
-      new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
-                                        old, m, sz);
+      new_obj = _old_gen->par_promote(par_scan_state->thread_num(),
+                                      old, m, sz);
     }
 
     if (new_obj == NULL) {
@@ -1209,6 +1197,7 @@
   } else {
     // Is in to-space; do copying ourselves.
     Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
+    assert(Universe::heap()->is_in_reserved(new_obj), "illegal forwarding pointer value.");
     forward_ptr = old->forward_to_atomic(new_obj);
     // Restore the mark word copied above.
     new_obj->set_mark(m);
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 
+#include "gc_implementation/parNew/parOopClosures.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
@@ -233,13 +234,13 @@
 class ParNewGenTask: public AbstractGangTask {
  private:
   ParNewGeneration*            _gen;
-  Generation*                  _next_gen;
+  Generation*                  _old_gen;
   HeapWord*                    _young_old_boundary;
   class ParScanThreadStateSet* _state_set;
 
 public:
   ParNewGenTask(ParNewGeneration*      gen,
-                Generation*            next_gen,
+                Generation*            old_gen,
                 HeapWord*              young_old_boundary,
                 ParScanThreadStateSet* state_set);
 
@@ -419,8 +420,6 @@
   }
 
   static oop real_forwardee(oop obj);
-
-  DEBUG_ONLY(static bool is_legal_forward_ptr(oop p);)
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 #include "gc_implementation/parNew/parOopClosures.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/genCollectedHeap.hpp"
+#include "memory/genOopClosures.inline.hpp"
 
 template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
   assert (!oopDesc::is_null(*p), "null weak reference?");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #include "gc_implementation/parallelScavenge/pcTasks.hpp"
 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSMARKSWEEP_HPP
 
 #include "gc_implementation/shared/collectorCounters.hpp"
-#include "gc_implementation/shared/markSweep.inline.hpp"
+#include "gc_implementation/shared/markSweep.hpp"
 #include "utilities/stack.hpp"
 
 class PSAdaptiveSizePolicy;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
-#include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
 #include "memory/sharedHeap.hpp"
 #include "oops/oop.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 #include "memory/padded.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oop.psgc.inline.hpp"
+#include "utilities/stack.inline.hpp"
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -40,6 +40,7 @@
 #include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
+#include "utilities/stack.inline.hpp"
 #include "utilities/taskqueue.hpp"
 
 //
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,3 +63,20 @@
                                      _space->capacity(), CHECK);
   }
 }
+
+void CSpaceCounters::update_capacity() {
+  _capacity->set_value(_space->capacity());
+}
+
+void CSpaceCounters::update_used() {
+  _used->set_value(_space->used());
+}
+
+void CSpaceCounters::update_all() {
+  update_used();
+  update_capacity();
+}
+
+jlong ContiguousSpaceUsedHelper::take_sample(){
+  return _space->used();
+}
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CSPACECOUNTERS_HPP
 
 #include "gc_implementation/shared/generationCounters.hpp"
-#include "memory/space.inline.hpp"
+#include "memory/space.hpp"
 #include "runtime/perfData.hpp"
 
 // A CSpaceCounters is a holder class for performance counters
@@ -56,18 +56,9 @@
       if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
   }
 
-  virtual inline void update_capacity() {
-    _capacity->set_value(_space->capacity());
-  }
-
-  virtual inline void update_used() {
-    _used->set_value(_space->used());
-  }
-
-  virtual inline void update_all() {
-    update_used();
-    update_capacity();
-  }
+  virtual void update_capacity();
+  virtual void update_used();
+  virtual void update_all();
 
   const char* name_space() const        { return _name_space; }
 };
@@ -79,9 +70,7 @@
   public:
     ContiguousSpaceUsedHelper(ContiguousSpace* space) : _space(space) { }
 
-    inline jlong take_sample() {
-      return _space->used();
-    }
+    jlong take_sample();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_CSPACECOUNTERS_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,6 +84,14 @@
 
 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
 
+void PreservedMark::adjust_pointer() {
+  MarkSweep::adjust_pointer(&_obj);
+}
+
+void PreservedMark::restore() {
+  _obj->set_mark(_mark);
+}
+
 // We preserve the mark which should be replaced at the end and the location
 // that it will go.  Note that the object that this markOop belongs to isn't
 // currently at that address but it will be after phase4
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
 
 #include "gc_interface/collectedHeap.hpp"
-#include "memory/universe.hpp"
+#include "memory/genOopClosures.hpp"
+#include "memory/iterator.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.hpp"
 #include "runtime/timer.hpp"
@@ -182,13 +183,8 @@
     _mark = mark;
   }
 
-  void adjust_pointer() {
-    MarkSweep::adjust_pointer(&_obj);
-  }
-
-  void restore() {
-    _obj->set_mark(_mark);
-  }
+  void adjust_pointer();
+  void restore();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -98,7 +98,7 @@
   if (!is_init_completed()) {
     vm_exit_during_initialization(
       err_msg("GC triggered before VM initialization completed. Try increasing "
-              "NewSize, current value " UINTX_FORMAT "%s.",
+              "NewSize, current value " SIZE_FORMAT "%s.",
               byte_size_in_proper_unit(NewSize),
               proper_unit_for_byte_size(NewSize)));
   }
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -27,7 +27,7 @@
 #include "memory/cardTableRS.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/generation.hpp"
-#include "memory/space.hpp"
+#include "memory/space.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/java.hpp"
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -104,15 +104,15 @@
 
   // User inputs from -Xmx and -Xms must be aligned
   _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
-  uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
-  uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
+  size_t aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
+  size_t aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
 
   // Write back to flags if the values changed
   if (aligned_initial_heap_size != InitialHeapSize) {
-    FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size);
   }
   if (aligned_max_heap_size != MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size);
   }
 
   if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
@@ -120,9 +120,9 @@
     vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
   }
   if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, InitialHeapSize);
   } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
-    FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, MaxHeapSize);
     if (InitialHeapSize < _min_heap_byte_size) {
       _min_heap_byte_size = InitialHeapSize;
     }
@@ -131,7 +131,7 @@
   _initial_heap_byte_size = InitialHeapSize;
   _max_heap_byte_size = MaxHeapSize;
 
-  FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
+  FLAG_SET_ERGO(size_t, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
 
   DEBUG_ONLY(CollectorPolicy::assert_flags();)
 }
@@ -282,18 +282,18 @@
   // All generational heaps have a youngest gen; handle those flags here
 
   // Make sure the heap is large enough for two generations
-  uintx smallest_new_size = young_gen_size_lower_bound();
-  uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
+  size_t smallest_new_size = young_gen_size_lower_bound();
+  size_t smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
                                            _heap_alignment);
   if (MaxHeapSize < smallest_heap_size) {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
     _max_heap_byte_size = MaxHeapSize;
   }
   // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
   if (_min_heap_byte_size < smallest_heap_size) {
     _min_heap_byte_size = smallest_heap_size;
     if (InitialHeapSize < _min_heap_byte_size) {
-      FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size);
+      FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
       _initial_heap_byte_size = smallest_heap_size;
     }
   }
@@ -306,8 +306,8 @@
 
   // Now take the actual NewSize into account. We will silently increase NewSize
   // if the user specified a smaller or unaligned value.
-  uintx bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
-  bounded_new_size = MAX2(smallest_new_size, (uintx)align_size_down(bounded_new_size, _gen_alignment));
+  size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
+  bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment));
   if (bounded_new_size != NewSize) {
     // Do not use FLAG_SET_ERGO to update NewSize here, since this will override
     // if NewSize was set on the command line or not. This information is needed
@@ -320,21 +320,21 @@
   if (!FLAG_IS_DEFAULT(MaxNewSize)) {
     if (MaxNewSize >= MaxHeapSize) {
       // Make sure there is room for an old generation
-      uintx smaller_max_new_size = MaxHeapSize - _gen_alignment;
+      size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
       if (FLAG_IS_CMDLINE(MaxNewSize)) {
         warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
                 "heap (" SIZE_FORMAT "k).  A new max generation size of " SIZE_FORMAT "k will be used.",
                 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
       }
-      FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size);
+      FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
       if (NewSize > MaxNewSize) {
-        FLAG_SET_ERGO(uintx, NewSize, MaxNewSize);
+        FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
         _initial_young_size = NewSize;
       }
     } else if (MaxNewSize < _initial_young_size) {
-      FLAG_SET_ERGO(uintx, MaxNewSize, _initial_young_size);
+      FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
     } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
-      FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
+      FLAG_SET_ERGO(size_t, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
     }
     _max_young_size = MaxNewSize;
   }
@@ -347,7 +347,7 @@
               "A new max generation size of " SIZE_FORMAT "k will be used.",
               NewSize/K, MaxNewSize/K, NewSize/K);
     }
-    FLAG_SET_ERGO(uintx, MaxNewSize, NewSize);
+    FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
     _max_young_size = MaxNewSize;
   }
 
@@ -369,9 +369,9 @@
     size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
 
     calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
-    FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
     _max_heap_byte_size = MaxHeapSize;
-    FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
     _initial_heap_byte_size = InitialHeapSize;
   }
 
@@ -380,19 +380,19 @@
     if (_max_heap_size_cmdline) {
       // Somebody has set a maximum heap size with the intention that we should not
       // exceed it. Adjust New/OldSize as necessary.
-      uintx calculated_size = NewSize + OldSize;
+      size_t calculated_size = NewSize + OldSize;
       double shrink_factor = (double) MaxHeapSize / calculated_size;
-      uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
-      FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
+      size_t smaller_new_size = align_size_down((size_t)(NewSize * shrink_factor), _gen_alignment);
+      FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
       _initial_young_size = NewSize;
 
       // OldSize is already aligned because above we aligned MaxHeapSize to
       // _heap_alignment, and we just made sure that NewSize is aligned to
       // _gen_alignment. In initialize_flags() we verified that _heap_alignment
       // is a multiple of _gen_alignment.
-      FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);
+      FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
     } else {
-      FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
+      FLAG_SET_ERGO(size_t, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
       _max_heap_byte_size = MaxHeapSize;
     }
   }
@@ -405,7 +405,7 @@
       // Need to compare against the flag value for max since _max_young_size
       // might not have been set yet.
       if (new_size >= _min_young_size && new_size <= MaxNewSize) {
-        FLAG_SET_ERGO(uintx, NewSize, new_size);
+        FLAG_SET_ERGO(size_t, NewSize, new_size);
         _initial_young_size = NewSize;
       }
     }
@@ -561,15 +561,15 @@
 
   // Write back to flags if necessary.
   if (NewSize != _initial_young_size) {
-    FLAG_SET_ERGO(uintx, NewSize, _initial_young_size);
+    FLAG_SET_ERGO(size_t, NewSize, _initial_young_size);
   }
 
   if (MaxNewSize != _max_young_size) {
-    FLAG_SET_ERGO(uintx, MaxNewSize, _max_young_size);
+    FLAG_SET_ERGO(size_t, MaxNewSize, _max_young_size);
   }
 
   if (OldSize != _initial_old_size) {
-    FLAG_SET_ERGO(uintx, OldSize, _initial_old_size);
+    FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
   }
 
   if (PrintGCDetails && Verbose) {
@@ -601,7 +601,7 @@
     HandleMark hm; // Discard any handles allocated in each iteration.
 
     // First allocation attempt is lock-free.
-    Generation *young = gch->get_gen(0);
+    Generation *young = gch->young_gen();
     assert(young->supports_inline_contig_alloc(),
       "Otherwise, must do alloc within heap lock");
     if (young->should_allocate(size, is_tlab)) {
@@ -615,8 +615,8 @@
     {
       MutexLocker ml(Heap_lock);
       if (PrintGC && Verbose) {
-        gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
-                      " attempting locked slow path allocation");
+        gclog_or_tty->print_cr("GenCollectorPolicy::mem_allocate_work:"
+                               " attempting locked slow path allocation");
       }
       // Note that only large objects get a shot at being
       // allocated in later generations.
@@ -705,7 +705,7 @@
     // Give a warning if we seem to be looping forever.
     if ((QueuedAllocationWarningCount > 0) &&
         (try_count % QueuedAllocationWarningCount == 0)) {
-          warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"
+          warning("GenCollectorPolicy::mem_allocate_work retries %d times \n\t"
                   " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
     }
   }
@@ -715,10 +715,14 @@
                                                        bool   is_tlab) {
   GenCollectedHeap *gch = GenCollectedHeap::heap();
   HeapWord* result = NULL;
-  for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) {
-    Generation *gen = gch->get_gen(i);
-    if (gen->should_allocate(size, is_tlab)) {
-      result = gen->expand_and_allocate(size, is_tlab);
+  Generation *old = gch->old_gen();
+  if (old->should_allocate(size, is_tlab)) {
+    result = old->expand_and_allocate(size, is_tlab);
+  }
+  if (result == NULL) {
+    Generation *young = gch->young_gen();
+    if (young->should_allocate(size, is_tlab)) {
+      result = young->expand_and_allocate(size, is_tlab);
     }
   }
   assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
@@ -891,7 +895,7 @@
 bool GenCollectorPolicy::should_try_older_generation_allocation(
         size_t word_size) const {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  size_t young_capacity = gch->get_gen(0)->capacity_before_gc();
+  size_t young_capacity = gch->young_gen()->capacity_before_gc();
   return    (word_size > heap_word_size(young_capacity))
          || GC_locker::is_active_and_needs_gc()
          || gch->incremental_collection_failed();
@@ -903,7 +907,7 @@
 //
 
 void MarkSweepPolicy::initialize_alignments() {
-  _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
+  _space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
   _heap_alignment = compute_heap_alignment();
 }
 
@@ -935,18 +939,18 @@
     // for both min and initial young size if less than min heap.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_initial(flag_value);
 
     // If NewSize is set on command line, but is larger than the min
     // heap size, it should only be used for initial young size.
     flag_value = 80 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
     verify_young_initial(flag_value);
 
     // If NewSize has been ergonomically set, the collector policy
@@ -954,11 +958,11 @@
     // using NewRatio.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_ERGO(uintx, NewSize, flag_value);
+    FLAG_SET_ERGO(size_t, NewSize, flag_value);
     verify_young_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_ERGO(uintx, NewSize, flag_value);
+    FLAG_SET_ERGO(size_t, NewSize, flag_value);
     verify_scaled_young_initial(InitialHeapSize);
 
     restore_flags();
@@ -974,11 +978,11 @@
     // for both min and initial old size if less than min heap.
     flag_value = 20 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     verify_old_min(flag_value);
 
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     // Calculate what we expect the flag to be.
     size_t expected_old_initial = align_size_up(InitialHeapSize, heap_alignment) - MaxNewSize;
     verify_old_initial(expected_old_initial);
@@ -989,10 +993,10 @@
     // We intentionally set MaxNewSize + OldSize > MaxHeapSize (see over_size).
     flag_value = 30 * M;
     set_basic_flag_values();
-    FLAG_SET_CMDLINE(uintx, OldSize, flag_value);
+    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
     size_t over_size = 20*M;
     size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment) - flag_value + over_size;
-    FLAG_SET_CMDLINE(uintx, MaxNewSize, new_size_value);
+    FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
     // Calculate what we expect the flag to be.
     expected_old_initial = align_size_up(MaxHeapSize, heap_alignment) - MaxNewSize;
     verify_old_initial(expected_old_initial);
@@ -1053,11 +1057,11 @@
   static size_t original_OldSize;
 
   static void set_basic_flag_values() {
-    FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);
-    FLAG_SET_ERGO(uintx, InitialHeapSize, 100 * M);
-    FLAG_SET_ERGO(uintx, OldSize, 4 * M);
-    FLAG_SET_ERGO(uintx, NewSize, 1 * M);
-    FLAG_SET_ERGO(uintx, MaxNewSize, 80 * M);
+    FLAG_SET_ERGO(size_t, MaxHeapSize, 180 * M);
+    FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
+    FLAG_SET_ERGO(size_t, OldSize, 4 * M);
+    FLAG_SET_ERGO(size_t, NewSize, 1 * M);
+    FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
     Arguments::set_min_heap_size(40 * M);
   }
 
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -226,7 +226,7 @@
 
   compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
   update_counters();
-  _next_gen = NULL;
+  _old_gen = NULL;
   _tenuring_threshold = MaxTenuringThreshold;
   _pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
 
@@ -383,8 +383,8 @@
   assert(next_level < gch->_n_gens,
          "DefNewGeneration cannot be an oldest gen");
 
-  Generation* next_gen = gch->get_gen(next_level);
-  size_t old_size = next_gen->capacity();
+  Generation* old_gen = gch->old_gen();
+  size_t old_size = old_gen->capacity();
   size_t new_size_before = _virtual_space.committed_size();
   size_t min_new_size = spec()->init_size();
   size_t max_new_size = reserved().byte_size();
@@ -568,7 +568,7 @@
   DefNewTracer gc_tracer;
   gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 
-  _next_gen = gch->next_gen(this);
+  _old_gen = gch->old_gen();
 
   // If the next generation is too full to accommodate promotion
   // from this generation, pass on collection; let the next generation
@@ -590,8 +590,6 @@
 
   gch->trace_heap_before_gc(&gc_tracer);
 
-  SpecializationStats::clear();
-
   // These can be shared for all code paths
   IsAliveClosure is_alive(this);
   ScanWeakRefClosure scan_weak_ref(this);
@@ -628,7 +626,7 @@
                          true,  // Process younger gens, if any,
                                 // as strong roots.
                          true,  // activate StrongRootsScope
-                         SharedHeap::SO_ScavengeCodeCache,
+                         GenCollectedHeap::SO_ScavengeCodeCache,
                          GenCollectedHeap::StrongAndWeakRoots,
                          &fsc_with_no_gc_barrier,
                          &fsc_with_gc_barrier,
@@ -688,7 +686,7 @@
     gch->set_incremental_collection_failed();
 
     // Inform the next generation that a promotion failure occurred.
-    _next_gen->promotion_failure_occurred();
+    _old_gen->promotion_failure_occurred();
     gc_tracer.report_promotion_failed(_promotion_failed_info);
 
     // Reset the PromotionFailureALot counters.
@@ -700,7 +698,6 @@
   // set new iteration safe limit for the survivor spaces
   from()->set_concurrent_iteration_safe_limit(from()->top());
   to()->set_concurrent_iteration_safe_limit(to()->top());
-  SpecializationStats::print();
 
   // We need to use a monotonically non-decreasing time in ms
   // or we will see time-warp warnings and os::javaTimeMillis()
@@ -793,7 +790,7 @@
 
   // Otherwise try allocating obj tenured
   if (obj == NULL) {
-    obj = _next_gen->promote(old, s);
+    obj = _old_gen->promote(old, s);
     if (obj == NULL) {
       handle_promotion_failure(old);
       return old;
@@ -898,11 +895,11 @@
     }
     return false;
   }
-  if (_next_gen == NULL) {
+  if (_old_gen == NULL) {
     GenCollectedHeap* gch = GenCollectedHeap::heap();
-    _next_gen = gch->next_gen(this);
+    _old_gen = gch->old_gen();
   }
-  return _next_gen->promotion_attempt_is_safe(used());
+  return _old_gen->promotion_attempt_is_safe(used());
 }
 
 void DefNewGeneration::gc_epilogue(bool full) {
@@ -1022,8 +1019,7 @@
   return eden();
 }
 
-HeapWord* DefNewGeneration::allocate(size_t word_size,
-                                     bool is_tlab) {
+HeapWord* DefNewGeneration::allocate(size_t word_size, bool is_tlab) {
   // This is the slow-path allocation for the DefNewGeneration.
   // Most allocations are fast-path in compiled code.
   // We try to allocate from the eden.  If that works, we are happy.
@@ -1031,8 +1027,8 @@
   // have to use it here, as well.
   HeapWord* result = eden()->par_allocate(word_size);
   if (result != NULL) {
-    if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
-      _next_gen->sample_eden_chunk();
+    if (CMSEdenChunksRecordAlways && _old_gen != NULL) {
+      _old_gen->sample_eden_chunk();
     }
   } else {
     // If the eden is full and the last collection bailed out, we are running
@@ -1047,8 +1043,8 @@
 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
                                          bool is_tlab) {
   HeapWord* res = eden()->par_allocate(word_size);
-  if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
-    _next_gen->sample_eden_chunk();
+  if (CMSEdenChunksRecordAlways && _old_gen != NULL) {
+    _old_gen->sample_eden_chunk();
   }
   return res;
 }
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,11 +29,14 @@
 #include "gc_implementation/shared/cSpaceCounters.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/generation.hpp"
 #include "utilities/stack.hpp"
 
 class ContiguousSpace;
 class ScanClosure;
 class STWGCTimer;
+class CSpaceCounters;
+class ScanWeakRefClosure;
 
 // DefNewGeneration is a young generation containing eden, from- and
 // to-space.
@@ -42,7 +45,7 @@
   friend class VMStructs;
 
 protected:
-  Generation* _next_gen;
+  Generation* _old_gen;
   uint        _tenuring_threshold;   // Tenuring threshold for next collection.
   ageTable    _age_table;
   // Size of object to pretenure in words; command line provides bytes
--- a/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
 #ifndef SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 #define SHARE_VM_MEMORY_DEFNEWGENERATION_INLINE_HPP
 
+#include "gc_interface/collectedHeap.hpp"
 #include "memory/cardTableRS.hpp"
 #include "memory/defNewGeneration.hpp"
+#include "memory/genOopClosures.inline.hpp"
 #include "memory/space.hpp"
 
 // Methods of protected closure types
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -26,6 +26,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
@@ -47,6 +48,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/management.hpp"
 #include "services/memoryService.hpp"
 #include "utilities/vmError.hpp"
 #include "utilities/workgroup.hpp"
@@ -61,7 +63,15 @@
 
 // The set of potentially parallel tasks in root scanning.
 enum GCH_strong_roots_tasks {
-  // We probably want to parallelize both of these internally, but for now...
+  GCH_PS_Universe_oops_do,
+  GCH_PS_JNIHandles_oops_do,
+  GCH_PS_ObjectSynchronizer_oops_do,
+  GCH_PS_FlatProfiler_oops_do,
+  GCH_PS_Management_oops_do,
+  GCH_PS_SystemDictionary_oops_do,
+  GCH_PS_ClassLoaderDataGraph_oops_do,
+  GCH_PS_jvmti_oops_do,
+  GCH_PS_CodeCache_oops_do,
   GCH_PS_younger_gens,
   // Leave this one last.
   GCH_PS_NumElements
@@ -71,13 +81,9 @@
   SharedHeap(policy),
   _rem_set(NULL),
   _gen_policy(policy),
-  _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)),
+  _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
   _full_collections_completed(0)
 {
-  if (_gen_process_roots_tasks == NULL ||
-      !_gen_process_roots_tasks->valid()) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  }
   assert(policy != NULL, "Sanity check");
 }
 
@@ -177,18 +183,17 @@
   SharedHeap::post_initialize();
   GenCollectorPolicy *policy = (GenCollectorPolicy *)collector_policy();
   guarantee(policy->is_generation_policy(), "Illegal policy type");
-  assert((get_gen(0)->kind() == Generation::DefNew) ||
-         (get_gen(0)->kind() == Generation::ParNew),
+  assert((_young_gen->kind() == Generation::DefNew) ||
+         (_young_gen->kind() == Generation::ParNew),
     "Wrong youngest generation type");
-  DefNewGeneration* def_new_gen = (DefNewGeneration*)get_gen(0);
+  DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
 
-  Generation* old_gen = get_gen(1);
-  assert(old_gen->kind() == Generation::ConcurrentMarkSweep ||
-         old_gen->kind() == Generation::MarkSweepCompact,
+  assert(_old_gen->kind() == Generation::ConcurrentMarkSweep ||
+         _old_gen->kind() == Generation::MarkSweepCompact,
     "Wrong generation kind");
 
   policy->initialize_size_policy(def_new_gen->eden()->capacity(),
-                                 old_gen->capacity(),
+                                 _old_gen->capacity(),
                                  def_new_gen->from()->capacity());
   policy->initialize_gc_policy_counters();
 }
@@ -570,29 +575,137 @@
 
 void GenCollectedHeap::set_par_threads(uint t) {
   SharedHeap::set_par_threads(t);
-  _gen_process_roots_tasks->set_n_threads(t);
+  set_n_termination(t);
+}
+
+void GenCollectedHeap::set_n_termination(uint t) {
+  _process_strong_tasks->set_n_threads(t);
 }
 
-void GenCollectedHeap::
-gen_process_roots(int level,
-                  bool younger_gens_as_roots,
-                  bool activate_scope,
-                  SharedHeap::ScanningOption so,
-                  OopsInGenClosure* not_older_gens,
-                  OopsInGenClosure* weak_roots,
-                  OopsInGenClosure* older_gens,
-                  CLDClosure* cld_closure,
-                  CLDClosure* weak_cld_closure,
-                  CodeBlobClosure* code_closure) {
+#ifdef ASSERT
+class AssertNonScavengableClosure: public OopClosure {
+public:
+  virtual void do_oop(oop* p) {
+    assert(!Universe::heap()->is_in_partial_collection(*p),
+      "Referent should not be scavengable.");  }
+  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+};
+static AssertNonScavengableClosure assert_is_non_scavengable_closure;
+#endif
+
+void GenCollectedHeap::process_roots(bool activate_scope,
+                                     ScanningOption so,
+                                     OopClosure* strong_roots,
+                                     OopClosure* weak_roots,
+                                     CLDClosure* strong_cld_closure,
+                                     CLDClosure* weak_cld_closure,
+                                     CodeBlobClosure* code_roots) {
+  StrongRootsScope srs(this, activate_scope);
 
   // General roots.
-  SharedHeap::process_roots(activate_scope, so,
-                            not_older_gens, weak_roots,
-                            cld_closure, weak_cld_closure,
-                            code_closure);
+  assert(_strong_roots_parity != 0, "must have called prologue code");
+  assert(code_roots != NULL, "code root closure should always be set");
+  // _n_termination for _process_strong_tasks should be set up stream
+  // in a method not running in a GC worker.  Otherwise the GC worker
+  // could be trying to change the termination condition while the task
+  // is executing in another GC worker.
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_ClassLoaderDataGraph_oops_do)) {
+    ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
+  }
+
+  // Some CLDs contained in the thread frames should be considered strong.
+  // Don't process them if they will be processed during the ClassLoaderDataGraph phase.
+  CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
+  // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
+  CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
+
+  Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) {
+    Universe::oops_do(strong_roots);
+  }
+  // Global (strong) JNI handles
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) {
+    JNIHandles::oops_do(strong_roots);
+  }
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) {
+    ObjectSynchronizer::oops_do(strong_roots);
+  }
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) {
+    FlatProfiler::oops_do(strong_roots);
+  }
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) {
+    Management::oops_do(strong_roots);
+  }
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) {
+    JvmtiExport::oops_do(strong_roots);
+  }
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) {
+    SystemDictionary::roots_oops_do(strong_roots, weak_roots);
+  }
+
+  // All threads execute the following. A specific chunk of buckets
+  // from the StringTable are the individual tasks.
+  if (weak_roots != NULL) {
+    if (CollectedHeap::use_parallel_gc_threads()) {
+      StringTable::possibly_parallel_oops_do(weak_roots);
+    } else {
+      StringTable::oops_do(weak_roots);
+    }
+  }
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) {
+    if (so & SO_ScavengeCodeCache) {
+      assert(code_roots != NULL, "must supply closure for code cache");
+
+      // We only visit parts of the CodeCache when scavenging.
+      CodeCache::scavenge_root_nmethods_do(code_roots);
+    }
+    if (so & SO_AllCodeCache) {
+      assert(code_roots != NULL, "must supply closure for code cache");
+
+      // CMSCollector uses this to do intermediate-strength collections.
+      // We scan the entire code cache, since CodeCache::do_unloading is not called.
+      CodeCache::blobs_do(code_roots);
+    }
+    // Verify that the code cache contents are not subject to
+    // movement by a scavenging collection.
+    DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations));
+    DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
+  }
+
+}
+
+void GenCollectedHeap::gen_process_roots(int level,
+                                         bool younger_gens_as_roots,
+                                         bool activate_scope,
+                                         ScanningOption so,
+                                         bool only_strong_roots,
+                                         OopsInGenClosure* not_older_gens,
+                                         OopsInGenClosure* older_gens,
+                                         CLDClosure* cld_closure) {
+  const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots;
+
+  bool is_moving_collection = false;
+  if (level == 0 || is_adjust_phase) {
+    // young collections are always moving
+    is_moving_collection = true;
+  }
+
+  MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection);
+  OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens;
+  CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
+
+  process_roots(activate_scope, so,
+                not_older_gens, weak_roots,
+                cld_closure, weak_cld_closure,
+                &mark_code_closure);
 
   if (younger_gens_as_roots) {
-    if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) {
+    if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
       if (level == 1) {
         not_older_gens->set_generation(_young_gen);
         _young_gen->oop_iterate(not_older_gens);
@@ -608,43 +721,18 @@
     older_gens->reset_generation();
   }
 
-  _gen_process_roots_tasks->all_tasks_completed();
+  _process_strong_tasks->all_tasks_completed();
 }
 
-void GenCollectedHeap::
-gen_process_roots(int level,
-                  bool younger_gens_as_roots,
-                  bool activate_scope,
-                  SharedHeap::ScanningOption so,
-                  bool only_strong_roots,
-                  OopsInGenClosure* not_older_gens,
-                  OopsInGenClosure* older_gens,
-                  CLDClosure* cld_closure) {
 
-  const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots;
-
-  bool is_moving_collection = false;
-  if (level == 0 || is_adjust_phase) {
-    // young collections are always moving
-    is_moving_collection = true;
-  }
-
-  MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection);
-  CodeBlobClosure* code_closure = &mark_code_closure;
-
-  gen_process_roots(level,
-                    younger_gens_as_roots,
-                    activate_scope, so,
-                    not_older_gens, only_strong_roots ? NULL : not_older_gens,
-                    older_gens,
-                    cld_closure, only_strong_roots ? NULL : cld_closure,
-                    code_closure);
-
-}
+class AlwaysTrueClosure: public BoolObjectClosure {
+public:
+  bool do_object_b(oop p) { return true; }
+};
+static AlwaysTrueClosure always_true;
 
 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
-  SharedHeap::process_weak_roots(root_closure);
-  // "Local" "weak" refs
+  JNIHandles::weak_oops_do(&always_true, root_closure);
   _young_gen->ref_processor()->weak_oops_do(root_closure);
   _old_gen->ref_processor()->weak_oops_do(root_closure);
 }
@@ -1113,10 +1201,10 @@
 
 void GenCollectedHeap::print_tracing_info() const {
   if (TraceYoungGenTime) {
-    get_gen(0)->print_summary_info();
+    _young_gen->print_summary_info();
   }
   if (TraceOldGenTime) {
-    get_gen(1)->print_summary_info();
+    _old_gen->print_summary_info();
   }
 }
 
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -85,8 +85,7 @@
 
   // Data structure for claiming the (potentially) parallel tasks in
   // (gen-specific) roots processing.
-  SubTasksDone* _gen_process_roots_tasks;
-  SubTasksDone* gen_process_roots_tasks() { return _gen_process_roots_tasks; }
+  SubTasksDone* _process_strong_tasks;
 
   // Collects the given generation.
   void collect_generation(Generation* gen, bool full, size_t size, bool is_tlab,
@@ -373,27 +372,6 @@
   // collection.
   virtual bool is_maximal_no_gc() const;
 
-  // Return the generation before "gen".
-  Generation* prev_gen(Generation* gen) const {
-    guarantee(gen->level() == 1, "Out of bounds");
-    return _young_gen;
-  }
-
-  // Return the generation after "gen".
-  Generation* next_gen(Generation* gen) const {
-    guarantee(gen->level() == 0, "Out of bounds");
-    return _old_gen;
-  }
-
-  Generation* get_gen(int i) const {
-    guarantee(i == 0 || i == 1, "Out of bounds");
-    if (i == 0) {
-      return _young_gen;
-    } else {
-      return _old_gen;
-    }
-  }
-
   int n_gens() const {
     assert(_n_gens == gen_policy()->number_of_generations(), "Sanity");
     return _n_gens;
@@ -408,6 +386,7 @@
   static GenCollectedHeap* heap();
 
   void set_par_threads(uint t);
+  void set_n_termination(uint t);
 
   // Invoke the "do_oop" method of one of the closures "not_older_gens"
   // or "older_gens" on root locations for the generation at
@@ -421,11 +400,25 @@
   // The "so" argument determines which of the roots
   // the closure is applied to:
   // "SO_None" does none;
+  enum ScanningOption {
+    SO_None                =  0x0,
+    SO_AllCodeCache        =  0x8,
+    SO_ScavengeCodeCache   = 0x10
+  };
+
  private:
+  void process_roots(bool activate_scope,
+                     ScanningOption so,
+                     OopClosure* strong_roots,
+                     OopClosure* weak_roots,
+                     CLDClosure* strong_cld_closure,
+                     CLDClosure* weak_cld_closure,
+                     CodeBlobClosure* code_roots);
+
   void gen_process_roots(int level,
                          bool younger_gens_as_roots,
                          bool activate_scope,
-                         SharedHeap::ScanningOption so,
+                         ScanningOption so,
                          OopsInGenClosure* not_older_gens,
                          OopsInGenClosure* weak_roots,
                          OopsInGenClosure* older_gens,
@@ -440,7 +433,7 @@
   void gen_process_roots(int level,
                          bool younger_gens_as_roots,
                          bool activate_scope,
-                         SharedHeap::ScanningOption so,
+                         ScanningOption so,
                          bool only_strong_roots,
                          OopsInGenClosure* not_older_gens,
                          OopsInGenClosure* older_gens,
@@ -486,7 +479,7 @@
     assert(heap()->collector_policy()->is_generation_policy(),
            "the following definition may not be suitable for an n(>2)-generation system");
     return incremental_collection_failed() ||
-           (consult_young && !get_gen(0)->collection_attempt_is_safe());
+           (consult_young && !_young_gen->collection_attempt_is_safe());
   }
 
   // If a generation bails out of an incremental collection,
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -50,6 +50,7 @@
 #include "runtime/vmThread.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/events.hpp"
+#include "utilities/stack.inline.hpp"
 
 void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) {
   guarantee(level == 1, "We always collect both old and young.");
@@ -109,20 +110,16 @@
 
   deallocate_stacks();
 
-  // If compaction completely evacuated all generations younger than this
-  // one, then we can clear the card table.  Otherwise, we must invalidate
+  // If compaction completely evacuated the young generation then we
+  // can clear the card table.  Otherwise, we must invalidate
   // it (consider all cards dirty).  In the future, we might consider doing
   // compaction within generations only, and doing card-table sliding.
-  bool all_empty = true;
-  for (int i = 0; all_empty && i < level; i++) {
-    Generation* g = gch->get_gen(i);
-    all_empty = all_empty && gch->get_gen(i)->used() == 0;
-  }
   GenRemSet* rs = gch->rem_set();
-  Generation* old_gen = gch->get_gen(level);
+  Generation* old_gen = gch->old_gen();
+
   // Clear/invalidate below make use of the "prev_used_regions" saved earlier.
-  if (all_empty) {
-    // We've evacuated all generations below us.
+  if (gch->young_gen()->used() == 0) {
+    // We've evacuated the young generation.
     rs->clear_into_younger(old_gen);
   } else {
     // Invalidate the cards corresponding to the currently used
@@ -157,9 +154,8 @@
 
 void GenMarkSweep::allocate_stacks() {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  // Scratch request on behalf of oldest generation; will do no
-  // allocation.
-  ScratchBlock* scratch = gch->gather_scratch(gch->get_gen(gch->_n_gens-1), 0);
+  // Scratch request on behalf of old generation; will do no allocation.
+  ScratchBlock* scratch = gch->gather_scratch(gch->old_gen(), 0);
 
   // $$$ To cut a corner, we'll only use the first scratch block, and then
   // revert to malloc.
@@ -188,7 +184,7 @@
 }
 
 void GenMarkSweep::mark_sweep_phase1(int level,
-                                  bool clear_all_softrefs) {
+                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
   GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
   trace(" 1");
@@ -199,7 +195,8 @@
   // use OopsInGenClosure constructor which takes a generation,
   // as the Universe has not been created when the static constructors
   // are run.
-  follow_root_closure.set_orig_generation(gch->get_gen(level));
+  assert(level == 1, "We don't use mark-sweep on young generations");
+  follow_root_closure.set_orig_generation(gch->old_gen());
 
   // Need new claim bits before marking starts.
   ClassLoaderDataGraph::clear_claimed_marks();
@@ -207,7 +204,7 @@
   gch->gen_process_roots(level,
                          false, // Younger gens are not roots.
                          true,  // activate StrongRootsScope
-                         SharedHeap::SO_None,
+                         GenCollectedHeap::SO_None,
                          GenCollectedHeap::StrongRootsOnly,
                          &follow_root_closure,
                          &follow_root_closure,
@@ -287,12 +284,13 @@
   // use OopsInGenClosure constructor which takes a generation,
   // as the Universe has not been created when the static constructors
   // are run.
-  adjust_pointer_closure.set_orig_generation(gch->get_gen(level));
+  assert(level == 1, "We don't use mark-sweep on young generations.");
+  adjust_pointer_closure.set_orig_generation(gch->old_gen());
 
   gch->gen_process_roots(level,
                          false, // Younger gens are not roots.
                          true,  // activate StrongRootsScope
-                         SharedHeap::SO_AllCodeCache,
+                         GenCollectedHeap::SO_AllCodeCache,
                          GenCollectedHeap::StrongAndWeakRoots,
                          &adjust_pointer_closure,
                          &adjust_pointer_closure,
--- a/hotspot/src/share/vm/memory/generation.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/generation.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -153,9 +153,8 @@
 
 Generation* Generation::next_gen() const {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
-  int next = level() + 1;
-  if (next < gch->_n_gens) {
-    return gch->get_gen(next);
+  if (level() == 0) {
+    return gch->old_gen();
   } else {
     return NULL;
   }
--- a/hotspot/src/share/vm/memory/heapInspection.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -33,6 +33,7 @@
 #include "runtime/os.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
+#include "utilities/stack.inline.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
 #endif // INCLUDE_ALL_GCS
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -3131,7 +3131,7 @@
 void Metaspace::initialize_class_space(ReservedSpace rs) {
   // The reserved space size may be bigger because of alignment, esp with UseLargePages
   assert(rs.size() >= CompressedClassSpaceSize,
-         err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
+         err_msg(SIZE_FORMAT " != " SIZE_FORMAT, rs.size(), CompressedClassSpaceSize));
   assert(using_class_space(), "Must be using class space");
   _class_space_list = new VirtualSpaceList(rs);
   _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk);
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -410,7 +410,7 @@
 
     // Split up and initialize the misc code and data spaces
     ReservedSpace* shared_rs = MetaspaceShared::shared_rs();
-    int metadata_size = SharedReadOnlySize+SharedReadWriteSize;
+    size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
     ReservedSpace shared_ro_rw = shared_rs->first_part(metadata_size);
     ReservedSpace misc_section = shared_rs->last_part(metadata_size);
 
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -32,7 +32,6 @@
 #include "runtime/atomic.inline.hpp"
 #include "runtime/fprofiler.hpp"
 #include "runtime/java.hpp"
-#include "services/management.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/workgroup.hpp"
 
@@ -40,32 +39,12 @@
 
 SharedHeap* SharedHeap::_sh;
 
-// The set of potentially parallel tasks in root scanning.
-enum SH_process_roots_tasks {
-  SH_PS_Universe_oops_do,
-  SH_PS_JNIHandles_oops_do,
-  SH_PS_ObjectSynchronizer_oops_do,
-  SH_PS_FlatProfiler_oops_do,
-  SH_PS_Management_oops_do,
-  SH_PS_SystemDictionary_oops_do,
-  SH_PS_ClassLoaderDataGraph_oops_do,
-  SH_PS_jvmti_oops_do,
-  SH_PS_CodeCache_oops_do,
-  // Leave this one last.
-  SH_PS_NumElements
-};
-
 SharedHeap::SharedHeap(CollectorPolicy* policy_) :
   CollectedHeap(),
   _collector_policy(policy_),
-  _strong_roots_scope(NULL),
   _strong_roots_parity(0),
-  _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)),
   _workers(NULL)
 {
-  if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  }
   _sh = this;  // ch is static, should be set only once.
   if (UseConcMarkSweepGC || UseG1GC) {
     _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
@@ -79,14 +58,6 @@
   }
 }
 
-int SharedHeap::n_termination() {
-  return _process_strong_tasks->n_threads();
-}
-
-void SharedHeap::set_n_termination(int t) {
-  _process_strong_tasks->set_n_threads(t);
-}
-
 bool SharedHeap::heap_lock_held_for_gc() {
   Thread* t = Thread::current();
   return    Heap_lock->owned_by_self()
@@ -97,31 +68,6 @@
 void SharedHeap::set_par_threads(uint t) {
   assert(t == 0 || !UseSerialGC, "Cannot have parallel threads");
   _n_par_threads = t;
-  _process_strong_tasks->set_n_threads(t);
-}
-
-#ifdef ASSERT
-class AssertNonScavengableClosure: public OopClosure {
-public:
-  virtual void do_oop(oop* p) {
-    assert(!Universe::heap()->is_in_partial_collection(*p),
-      "Referent should not be scavengable.");  }
-  virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-};
-static AssertNonScavengableClosure assert_is_non_scavengable_closure;
-#endif
-
-SharedHeap::StrongRootsScope* SharedHeap::active_strong_roots_scope() const {
-  return _strong_roots_scope;
-}
-void SharedHeap::register_strong_roots_scope(SharedHeap::StrongRootsScope* scope) {
-  assert(_strong_roots_scope == NULL, "Should only have one StrongRootsScope active");
-  assert(scope != NULL, "Illegal argument");
-  _strong_roots_scope = scope;
-}
-void SharedHeap::unregister_strong_roots_scope(SharedHeap::StrongRootsScope* scope) {
-  assert(_strong_roots_scope == scope, "Wrong scope unregistered");
-  _strong_roots_scope = NULL;
 }
 
 void SharedHeap::change_strong_roots_parity() {
@@ -135,174 +81,15 @@
 }
 
 SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate)
-  : MarkScope(activate), _sh(heap), _n_workers_done_with_threads(0)
+  : MarkScope(activate), _sh(heap)
 {
   if (_active) {
-    _sh->register_strong_roots_scope(this);
     _sh->change_strong_roots_parity();
     // Zero the claimed high water mark in the StringTable
     StringTable::clear_parallel_claimed_index();
   }
 }
 
-SharedHeap::StrongRootsScope::~StrongRootsScope() {
-  if (_active) {
-    _sh->unregister_strong_roots_scope(this);
-  }
-}
-
-Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false, Monitor::_safepoint_check_never);
-
-void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) {
-  // The Thread work barrier is only needed by G1 Class Unloading.
-  // No need to use the barrier if this is single-threaded code.
-  if (UseG1GC && ClassUnloadingWithConcurrentMark && n_workers > 0) {
-    uint new_value = (uint)Atomic::add(1, &_n_workers_done_with_threads);
-    if (new_value == n_workers) {
-      // This thread is last. Notify the others.
-      MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
-      _lock->notify_all();
-    }
-  }
-}
-
-void SharedHeap::StrongRootsScope::wait_until_all_workers_done_with_threads(uint n_workers) {
-  assert(UseG1GC,                          "Currently only used by G1");
-  assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
-
-  // No need to use the barrier if this is single-threaded code.
-  if (n_workers > 0 && (uint)_n_workers_done_with_threads != n_workers) {
-    MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag);
-    while ((uint)_n_workers_done_with_threads != n_workers) {
-      _lock->wait(Mutex::_no_safepoint_check_flag, 0, false);
-    }
-  }
-}
-
-void SharedHeap::process_roots(bool activate_scope,
-                               ScanningOption so,
-                               OopClosure* strong_roots,
-                               OopClosure* weak_roots,
-                               CLDClosure* strong_cld_closure,
-                               CLDClosure* weak_cld_closure,
-                               CodeBlobClosure* code_roots) {
-  StrongRootsScope srs(this, activate_scope);
-
-  // General roots.
-  assert(_strong_roots_parity != 0, "must have called prologue code");
-  assert(code_roots != NULL, "code root closure should always be set");
-  // _n_termination for _process_strong_tasks should be set up stream
-  // in a method not running in a GC worker.  Otherwise the GC worker
-  // could be trying to change the termination condition while the task
-  // is executing in another GC worker.
-
-  // Iterating over the CLDG and the Threads are done early to allow G1 to
-  // first process the strong CLDs and nmethods and then, after a barrier,
-  // let the thread process the weak CLDs and nmethods.
-
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
-    ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
-  }
-
-  // Some CLDs contained in the thread frames should be considered strong.
-  // Don't process them if they will be processed during the ClassLoaderDataGraph phase.
-  CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL;
-  // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
-  CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
-
-  Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p);
-
-  // This is the point where this worker thread will not find more strong CLDs/nmethods.
-  // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
-  active_strong_roots_scope()->mark_worker_done_with_threads(n_par_threads());
-
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
-    Universe::oops_do(strong_roots);
-  }
-  // Global (strong) JNI handles
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
-    JNIHandles::oops_do(strong_roots);
-
-  if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
-    ObjectSynchronizer::oops_do(strong_roots);
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
-    FlatProfiler::oops_do(strong_roots);
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
-    Management::oops_do(strong_roots);
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
-    JvmtiExport::oops_do(strong_roots);
-
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
-    SystemDictionary::roots_oops_do(strong_roots, weak_roots);
-  }
-
-  // All threads execute the following. A specific chunk of buckets
-  // from the StringTable are the individual tasks.
-  if (weak_roots != NULL) {
-    if (CollectedHeap::use_parallel_gc_threads()) {
-      StringTable::possibly_parallel_oops_do(weak_roots);
-    } else {
-      StringTable::oops_do(weak_roots);
-    }
-  }
-
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
-    if (so & SO_ScavengeCodeCache) {
-      assert(code_roots != NULL, "must supply closure for code cache");
-
-      // We only visit parts of the CodeCache when scavenging.
-      CodeCache::scavenge_root_nmethods_do(code_roots);
-    }
-    if (so & SO_AllCodeCache) {
-      assert(code_roots != NULL, "must supply closure for code cache");
-
-      // CMSCollector uses this to do intermediate-strength collections.
-      // We scan the entire code cache, since CodeCache::do_unloading is not called.
-      CodeCache::blobs_do(code_roots);
-    }
-    // Verify that the code cache contents are not subject to
-    // movement by a scavenging collection.
-    DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations));
-    DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
-  }
-
-  _process_strong_tasks->all_tasks_completed();
-}
-
-void SharedHeap::process_all_roots(bool activate_scope,
-                                   ScanningOption so,
-                                   OopClosure* roots,
-                                   CLDClosure* cld_closure,
-                                   CodeBlobClosure* code_closure) {
-  process_roots(activate_scope, so,
-                roots, roots,
-                cld_closure, cld_closure,
-                code_closure);
-}
-
-void SharedHeap::process_strong_roots(bool activate_scope,
-                                      ScanningOption so,
-                                      OopClosure* roots,
-                                      CLDClosure* cld_closure,
-                                      CodeBlobClosure* code_closure) {
-  process_roots(activate_scope, so,
-                roots, NULL,
-                cld_closure, NULL,
-                code_closure);
-}
-
-
-class AlwaysTrueClosure: public BoolObjectClosure {
-public:
-  bool do_object_b(oop p) { return true; }
-};
-static AlwaysTrueClosure always_true;
-
-void SharedHeap::process_weak_roots(OopClosure* root_closure) {
-  // Global (weak) JNI handles
-  JNIHandles::weak_oops_do(&always_true, root_closure);
-}
-
 void SharedHeap::set_barrier_set(BarrierSet* bs) {
   _barrier_set = bs;
   // Cached barrier set for fast access in oops
--- a/hotspot/src/share/vm/memory/sharedHeap.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/sharedHeap.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -61,18 +61,18 @@
 //    counts the number of tasks that have been done and then reset
 //    the SubTasksDone so that it can be used again.  When the number of
 //    tasks is set to the number of GC workers, then _n_threads must
-//    be set to the number of active GC workers. G1CollectedHeap,
-//    HRInto_G1RemSet, GenCollectedHeap and SharedHeap have SubTasksDone.
-//    This seems too many.
+//    be set to the number of active GC workers. G1RootProcessor and
+//    GenCollectedHeap have SubTasksDone.
 //    3) SequentialSubTasksDone has an _n_threads that is used in
 //    a way similar to SubTasksDone and has the same dependency on the
 //    number of active GC workers.  CompactibleFreeListSpace and Space
 //    have SequentialSubTasksDone's.
-// Example of using SubTasksDone and SequentialSubTasksDone
-// G1CollectedHeap::g1_process_roots()
-//  to SharedHeap::process_roots() and uses
-//  SubTasksDone* _process_strong_tasks to claim tasks.
-//  process_roots() calls
+//
+// Examples of using SubTasksDone and SequentialSubTasksDone:
+//  G1RootProcessor and GenCollectedHeap::process_roots() use
+//  SubTasksDone* _process_strong_tasks to claim tasks for workers
+//
+//  GenCollectedHeap::gen_process_roots() calls
 //      rem_set()->younger_refs_iterate()
 //  to scan the card table and which eventually calls down into
 //  CardTableModRefBS::par_non_clean_card_iterate_work().  This method
@@ -104,10 +104,6 @@
   friend class VM_GC_Operation;
   friend class VM_CGC_Operation;
 
-private:
-  // For claiming strong_roots tasks.
-  SubTasksDone* _process_strong_tasks;
-
 protected:
   // There should be only a single instance of "SharedHeap" in a program.
   // This is enforced with the protected constructor below, which will also
@@ -140,7 +136,6 @@
   static SharedHeap* heap() { return _sh; }
 
   void set_barrier_set(BarrierSet* bs);
-  SubTasksDone* process_strong_tasks() { return _process_strong_tasks; }
 
   // Does operations required after initialization has been done.
   virtual void post_initialize();
@@ -193,69 +188,19 @@
   // strong_roots_prologue calls change_strong_roots_parity, if
   // parallel tasks are enabled.
   class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
-    // Used to implement the Thread work barrier.
-    static Monitor* _lock;
-
     SharedHeap*   _sh;
-    volatile jint _n_workers_done_with_threads;
 
    public:
     StrongRootsScope(SharedHeap* heap, bool activate = true);
-    ~StrongRootsScope();
-
-    // Mark that this thread is done with the Threads work.
-    void mark_worker_done_with_threads(uint n_workers);
-    // Wait until all n_workers are done with the Threads work.
-    void wait_until_all_workers_done_with_threads(uint n_workers);
   };
   friend class StrongRootsScope;
 
-  // The current active StrongRootScope
-  StrongRootsScope* _strong_roots_scope;
-
-  StrongRootsScope* active_strong_roots_scope() const;
-
  private:
-  void register_strong_roots_scope(StrongRootsScope* scope);
-  void unregister_strong_roots_scope(StrongRootsScope* scope);
   void change_strong_roots_parity();
 
  public:
-  enum ScanningOption {
-    SO_None                =  0x0,
-    SO_AllCodeCache        =  0x8,
-    SO_ScavengeCodeCache   = 0x10
-  };
-
   FlexibleWorkGang* workers() const { return _workers; }
 
-  // Invoke the "do_oop" method the closure "roots" on all root locations.
-  // The "so" argument determines which roots the closure is applied to:
-  // "SO_None" does none;
-  // "SO_AllCodeCache" applies the closure to all elements of the CodeCache.
-  // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache.
-  void process_roots(bool activate_scope,
-                     ScanningOption so,
-                     OopClosure* strong_roots,
-                     OopClosure* weak_roots,
-                     CLDClosure* strong_cld_closure,
-                     CLDClosure* weak_cld_closure,
-                     CodeBlobClosure* code_roots);
-  void process_all_roots(bool activate_scope,
-                         ScanningOption so,
-                         OopClosure* roots,
-                         CLDClosure* cld_closure,
-                         CodeBlobClosure* code_roots);
-  void process_strong_roots(bool activate_scope,
-                            ScanningOption so,
-                            OopClosure* roots,
-                            CLDClosure* cld_closure,
-                            CodeBlobClosure* code_roots);
-
-
-  // Apply "root_closure" to the JNI weak roots..
-  void process_weak_roots(OopClosure* root_closure);
-
   // The functions below are helper functions that a subclass of
   // "SharedHeap" can use in the implementation of its virtual
   // functions.
@@ -270,9 +215,6 @@
   // (such as process roots) subsequently.
   virtual void set_par_threads(uint t);
 
-  int n_termination();
-  void set_n_termination(int t);
-
   //
   // New methods from CollectedHeap
   //
@@ -284,8 +226,4 @@
                              size_t capacity);
 };
 
-inline SharedHeap::ScanningOption operator|(SharedHeap::ScanningOption so0, SharedHeap::ScanningOption so1) {
-  return static_cast<SharedHeap::ScanningOption>(static_cast<int>(so0) | static_cast<int>(so1));
-}
-
 #endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP
--- a/hotspot/src/share/vm/memory/space.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/space.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -26,7 +26,6 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc_implementation/shared/liveRange.hpp"
-#include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/blockOffsetTable.inline.hpp"
@@ -353,15 +352,6 @@
 void ContiguousSpace::mangle_unused_area_complete() {
   mangler()->mangle_unused_area_complete();
 }
-void ContiguousSpace::mangle_region(MemRegion mr) {
-  // Although this method uses SpaceMangler::mangle_region() which
-  // is not specific to a space, the when the ContiguousSpace version
-  // is called, it is always with regard to a space and this
-  // bounds checking is appropriate.
-  MemRegion space_mr(bottom(), end());
-  assert(space_mr.contains(mr), "Mangling outside space");
-  SpaceMangler::mangle_region(mr);
-}
 #endif  // NOT_PRODUCT
 
 void CompactibleSpace::initialize(MemRegion mr,
@@ -388,7 +378,7 @@
     cp->space->set_compaction_top(compact_top);
     cp->space = cp->space->next_compaction_space();
     if (cp->space == NULL) {
-      cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
+      cp->gen = GenCollectedHeap::heap()->young_gen();
       assert(cp->gen != NULL, "compaction must succeed");
       cp->space = cp->gen->first_compaction_space();
       assert(cp->space != NULL, "generation must have a first compaction space");
--- a/hotspot/src/share/vm/memory/space.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/space.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,11 +128,10 @@
 
   // For detecting GC bugs.  Should only be called at GC boundaries, since
   // some unused space may be used as scratch space during GC's.
-  // Default implementation does nothing. We also call this when expanding
-  // a space to satisfy an allocation request. See bug #4668531
-  virtual void mangle_unused_area() {}
-  virtual void mangle_unused_area_complete() {}
-  virtual void mangle_region(MemRegion mr) {}
+  // We also call this when expanding a space to satisfy an allocation
+  // request. See bug #4668531
+  virtual void mangle_unused_area() = 0;
+  virtual void mangle_unused_area_complete() = 0;
 
   // Testers
   bool is_empty() const              { return used() == 0; }
@@ -196,7 +195,7 @@
   // structure supporting these calls, possibly speeding up future calls.
   // The default implementation, however, is simply to call the const
   // version.
-  inline virtual HeapWord* block_start(const void* p);
+  virtual HeapWord* block_start(const void* p);
 
   // Requires "addr" to be the start of a chunk, and returns its size.
   // "addr + size" is required to be the start of a new chunk, or the end
@@ -559,8 +558,6 @@
   void mangle_unused_area() PRODUCT_RETURN;
   // Mangle [top, end)
   void mangle_unused_area_complete() PRODUCT_RETURN;
-  // Mangle the given MemRegion.
-  void mangle_region(MemRegion mr) PRODUCT_RETURN;
 
   // Do some sparse checking on the area that should have been mangled.
   void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
--- a/hotspot/src/share/vm/memory/specialized_oop_closures.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2001, 2010, 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 "memory/specialized_oop_closures.hpp"
-#include "utilities/ostream.hpp"
-
-// For keeping stats on effectiveness.
-#ifndef PRODUCT
-#if ENABLE_SPECIALIZATION_STATS
-
-int SpecializationStats::_numCallsAll;
-
-int SpecializationStats::_numCallsTotal[NUM_Kinds];
-int SpecializationStats::_numCalls_nv[NUM_Kinds];
-
-int SpecializationStats::_numDoOopCallsTotal[NUM_Kinds];
-int SpecializationStats::_numDoOopCalls_nv[NUM_Kinds];
-
-void SpecializationStats::clear() {
-  _numCallsAll = 0;
-  for (int k = ik; k < NUM_Kinds; k++) {
-    _numCallsTotal[k] = 0;
-    _numCalls_nv[k] = 0;
-
-    _numDoOopCallsTotal[k] = 0;
-    _numDoOopCalls_nv[k] = 0;
-  }
-}
-
-void SpecializationStats::print() {
-  const char* header_format = "    %20s %10s %11s %10s";
-  const char* line_format   = "    %20s %10d %11d %9.2f%%";
-  int all_numCallsTotal =
-    _numCallsTotal[ik] + _numCallsTotal[irk] + _numCallsTotal[oa];
-  int all_numCalls_nv =
-    _numCalls_nv[ik] + _numCalls_nv[irk] + _numCalls_nv[oa];
-  gclog_or_tty->print_cr("\nOf %d oop_oop_iterate calls %d (%6.3f%%) are in (ik, irk, oa).",
-                _numCallsAll, all_numCallsTotal,
-                100.0 * (float)all_numCallsTotal / (float)_numCallsAll);
-  // irk calls are double-counted.
-  int real_ik_numCallsTotal = _numCallsTotal[ik] - _numCallsTotal[irk];
-  int real_ik_numCalls_nv   = _numCalls_nv[ik]   - _numCalls_nv[irk];
-  gclog_or_tty->print_cr("");
-  gclog_or_tty->print_cr(header_format, "oop_oop_iterate:", "calls", "non-virtual", "pct");
-  gclog_or_tty->print_cr(header_format,
-                "----------",
-                "----------",
-                "-----------",
-                "----------");
-  gclog_or_tty->print_cr(line_format, "all",
-                all_numCallsTotal,
-                all_numCalls_nv,
-                100.0 * (float)all_numCalls_nv / (float)all_numCallsTotal);
-  gclog_or_tty->print_cr(line_format, "ik",
-                real_ik_numCallsTotal, real_ik_numCalls_nv,
-                100.0 * (float)real_ik_numCalls_nv /
-                (float)real_ik_numCallsTotal);
-  gclog_or_tty->print_cr(line_format, "irk",
-                _numCallsTotal[irk], _numCalls_nv[irk],
-                100.0 * (float)_numCalls_nv[irk] / (float)_numCallsTotal[irk]);
-  gclog_or_tty->print_cr(line_format, "oa",
-                _numCallsTotal[oa], _numCalls_nv[oa],
-                100.0 * (float)_numCalls_nv[oa] / (float)_numCallsTotal[oa]);
-
-
-  gclog_or_tty->print_cr("");
-  gclog_or_tty->print_cr(header_format, "do_oop:", "calls", "non-virtual", "pct");
-  gclog_or_tty->print_cr(header_format,
-                "----------",
-                "----------",
-                "-----------",
-                "----------");
-  int all_numDoOopCallsTotal =
-    _numDoOopCallsTotal[ik] + _numDoOopCallsTotal[irk] + _numDoOopCallsTotal[oa];
-  int all_numDoOopCalls_nv =
-    _numDoOopCalls_nv[ik] + _numDoOopCalls_nv[irk] + _numDoOopCalls_nv[oa];
-  gclog_or_tty->print_cr(line_format, "all",
-                all_numDoOopCallsTotal, all_numDoOopCalls_nv,
-                100.0 * (float)all_numDoOopCalls_nv /
-                (float)all_numDoOopCallsTotal);
-  const char* kind_names[] = { "ik", "irk", "oa" };
-  for (int k = ik; k < NUM_Kinds; k++) {
-    gclog_or_tty->print_cr(line_format, kind_names[k],
-                  _numDoOopCallsTotal[k], _numDoOopCalls_nv[k],
-                  (_numDoOopCallsTotal[k] > 0 ?
-                   100.0 * (float)_numDoOopCalls_nv[k] /
-                   (float)_numDoOopCallsTotal[k]
-                   : 0.0));
-  }
-}
-
-#endif  // ENABLE_SPECIALIZATION_STATS
-#endif  // !PRODUCT
--- a/hotspot/src/share/vm/memory/specialized_oop_closures.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/specialized_oop_closures.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -60,21 +60,15 @@
 // This macro applies an argument macro to all OopClosures for which we
 // want specialized bodies of "oop_oop_iterate".  The arguments to "f" are:
 //   "f(closureType, non_virtual)"
-// where "closureType" is the name of the particular subclass of OopClosure,
+// where "closureType" is the name of the particular subclass of ExtendedOopClosure,
 // and "non_virtual" will be the string "_nv" if the closure type should
 // have its "do_oop" method invoked non-virtually, or else the
-// string "_v".  ("OopClosure" itself will be the only class in the latter
+// string "_v".  ("ExtendedOopClosure" itself will be the only class in the latter
 // category.)
 
 // This is split into several because of a Visual C++ 6.0 compiler bug
 // where very long macros cause the compiler to crash
 
-// Some other heap might define further specialized closures.
-#ifndef FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES
-#define FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) \
-        /* None */
-#endif
-
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f)       \
   f(ScanClosure,_nv)                                    \
   f(FastScanClosure,_nv)                                \
@@ -94,7 +88,7 @@
   SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f)
 
 #if INCLUDE_ALL_GCS
-#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)       \
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f)     \
   f(MarkRefsIntoAndScanClosure,_nv)                     \
   f(Par_MarkRefsIntoAndScanClosure,_nv)                 \
   f(PushAndMarkClosure,_nv)                             \
@@ -102,8 +96,13 @@
   f(PushOrMarkClosure,_nv)                              \
   f(Par_PushOrMarkClosure,_nv)                          \
   f(CMSKeepAliveClosure,_nv)                            \
-  f(CMSInnerParMarkAndPushClosure,_nv)                  \
-  FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f)
+  f(CMSInnerParMarkAndPushClosure,_nv)
+#endif
+
+#if INCLUDE_ALL_GCS
+#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)       \
+  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_CMS(f)           \
+  SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_G1(f)
 #else  // INCLUDE_ALL_GCS
 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f)
 #endif // INCLUDE_ALL_GCS
@@ -144,13 +143,6 @@
 // The "root_class" is the most general class to define; this may be
 // "OopClosure" in some applications and "OopsInGenClosure" in others.
 
-
-// Some other heap might define further specialized closures.
-#ifndef FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES
-#define FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) \
-        /* None */
-#endif
-
 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \
   f(ScanClosure,_nv)                                     \
   f(FastScanClosure,_nv)
@@ -158,8 +150,7 @@
 #if INCLUDE_ALL_GCS
 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \
   f(ParScanWithBarrierClosure,_nv)                       \
-  f(ParScanWithoutBarrierClosure,_nv)                    \
-  FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
+  f(ParScanWithoutBarrierClosure,_nv)
 #else  // INCLUDE_ALL_GCS
 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f)
 #endif // INCLUDE_ALL_GCS
@@ -174,93 +165,9 @@
 // We separate these out, because sometime the general one has
 // a different definition from the specialized ones, and sometimes it
 // doesn't.
-// NOTE:   One of the valid criticisms of this
-// specialize-oop_oop_iterate-for-specific-closures idiom is that it is
-// easy to have a silent performance bug: if you fail to de-virtualize,
-// things still work, just slower.  The "SpecializationStats" mode is
-// intended to at least make such a failure easy to detect.
-// *Not* using the ALL_SINCE_SAVE_MARKS_CLOSURES(f) macro defined
-// below means that *only* closures for which oop_oop_iterate specializations
-// exist above may be applied to "oops_since_save_marks".  That is,
-// this form of the performance bug is caught statically.  When you add
-// a definition for the general type, this property goes away.
-// Make sure you test with SpecializationStats to find such bugs
-// when introducing a new closure where you don't want virtual dispatch.
 
 #define ALL_SINCE_SAVE_MARKS_CLOSURES(f)                \
   f(OopsInGenClosure,_v)                                \
   SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
 
-// For keeping stats on effectiveness.
-#define ENABLE_SPECIALIZATION_STATS 0
-
-
-class SpecializationStats {
-public:
-  enum Kind {
-    ik,             // InstanceKlass
-    irk,            // InstanceRefKlass
-    oa,             // ObjArrayKlass
-    NUM_Kinds
-  };
-
-#if ENABLE_SPECIALIZATION_STATS
-private:
-  static bool _init;
-  static bool _wrapped;
-  static jint _numCallsAll;
-
-  static jint _numCallsTotal[NUM_Kinds];
-  static jint _numCalls_nv[NUM_Kinds];
-
-  static jint _numDoOopCallsTotal[NUM_Kinds];
-  static jint _numDoOopCalls_nv[NUM_Kinds];
-public:
-#endif
-  static void clear()  PRODUCT_RETURN;
-
-  static inline void record_call()  PRODUCT_RETURN;
-  static inline void record_iterate_call_v(Kind k)  PRODUCT_RETURN;
-  static inline void record_iterate_call_nv(Kind k)  PRODUCT_RETURN;
-  static inline void record_do_oop_call_v(Kind k)  PRODUCT_RETURN;
-  static inline void record_do_oop_call_nv(Kind k)  PRODUCT_RETURN;
-
-  static void print() PRODUCT_RETURN;
-};
-
-#ifndef PRODUCT
-#if ENABLE_SPECIALIZATION_STATS
-
-inline void SpecializationStats::record_call() {
-  Atomic::inc(&_numCallsAll);
-}
-inline void SpecializationStats::record_iterate_call_v(Kind k) {
-  Atomic::inc(&_numCallsTotal[k]);
-}
-inline void SpecializationStats::record_iterate_call_nv(Kind k) {
-  Atomic::inc(&_numCallsTotal[k]);
-  Atomic::inc(&_numCalls_nv[k]);
-}
-
-inline void SpecializationStats::record_do_oop_call_v(Kind k) {
-  Atomic::inc(&_numDoOopCallsTotal[k]);
-}
-inline void SpecializationStats::record_do_oop_call_nv(Kind k) {
-  Atomic::inc(&_numDoOopCallsTotal[k]);
-  Atomic::inc(&_numDoOopCalls_nv[k]);
-}
-
-#else   // !ENABLE_SPECIALIZATION_STATS
-
-inline void SpecializationStats::record_call() {}
-inline void SpecializationStats::record_iterate_call_v(Kind k) {}
-inline void SpecializationStats::record_iterate_call_nv(Kind k) {}
-inline void SpecializationStats::record_do_oop_call_v(Kind k) {}
-inline void SpecializationStats::record_do_oop_call_nv(Kind k) {}
-inline void SpecializationStats::clear() {}
-inline void SpecializationStats::print() {}
-
-#endif  // ENABLE_SPECIALIZATION_STATS
-#endif  // !PRODUCT
-
 #endif // SHARE_VM_MEMORY_SPECIALIZED_OOP_CLOSURES_HPP
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -178,7 +178,6 @@
                                 bool   is_tlab) {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 
-  SpecializationStats::clear();
   // Temporarily expand the span of our ref processor, so
   // refs discovery is over the entire heap, not just this generation
   ReferenceProcessorSpanMutator
@@ -195,8 +194,6 @@
   gc_timer->register_gc_end();
 
   gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
-
-  SpecializationStats::print();
 }
 
 HeapWord*
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -35,9 +35,6 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-# include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
-#endif // INCLUDE_ALL_GCS
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -30,6 +30,7 @@
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
@@ -54,7 +55,6 @@
 int InstanceClassLoaderKlass::                                                  \
 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
   /* Get size before changing pointers */                                       \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
   int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
                                                                                 \
   if_do_metadata_checked(closure, nv_suffix) {                                  \
@@ -74,7 +74,6 @@
 int InstanceClassLoaderKlass::                                                  \
 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
   /* Get size before changing pointers */                                       \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
   int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
   return size;                                                                  \
 }
@@ -87,8 +86,6 @@
 oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
                                OopClosureType* closure,                         \
                                MemRegion mr) {                                  \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
-                                                                                \
   int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
                                                                                 \
   if_do_metadata_checked(closure, nv_suffix) {                                  \
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
 #define SHARE_VM_OOPS_INSTANCECLASSLOADERKLASS_HPP
 
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceKlass.hpp"
 #include "utilities/macros.hpp"
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -38,6 +38,7 @@
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/fieldStreams.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceKlass.hpp"
@@ -2209,15 +2210,12 @@
 #define InstanceKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)        \
                                                                              \
 int InstanceKlass::oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
   /* header */                                                          \
   if_do_metadata_checked(closure, nv_suffix) {                          \
     closure->do_klass##nv_suffix(obj->klass());                         \
   }                                                                     \
   InstanceKlass_OOP_MAP_ITERATE(                                        \
     obj,                                                                \
-    SpecializationStats::                                               \
-      record_do_oop_call##nv_suffix(SpecializationStats::ik);           \
     (closure)->do_oop##nv_suffix(p),                                    \
     assert_is_in_closed_subset)                                         \
   return size_helper();                                                 \
@@ -2228,14 +2226,11 @@
                                                                                 \
 int InstanceKlass::oop_oop_iterate_backwards##nv_suffix(oop obj,                \
                                               OopClosureType* closure) {        \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik); \
-                                                                                \
   assert_should_ignore_metadata(closure, nv_suffix);                            \
                                                                                 \
   /* instance variables */                                                      \
   InstanceKlass_OOP_MAP_REVERSE_ITERATE(                                        \
     obj,                                                                        \
-    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::ik);\
     (closure)->do_oop##nv_suffix(p),                                            \
     assert_is_in_closed_subset)                                                 \
    return size_helper();                                                        \
@@ -2247,7 +2242,6 @@
 int InstanceKlass::oop_oop_iterate##nv_suffix##_m(oop obj,              \
                                                   OopClosureType* closure, \
                                                   MemRegion mr) {          \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::ik);\
   if_do_metadata_checked(closure, nv_suffix) {                           \
     if (mr.contains(obj)) {                                              \
       closure->do_klass##nv_suffix(obj->klass());                        \
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -27,6 +27,7 @@
 
 #include "classfile/classLoaderData.hpp"
 #include "memory/referenceType.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constMethod.hpp"
 #include "oops/fieldInfo.hpp"
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -30,6 +30,7 @@
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceOop.hpp"
@@ -250,8 +251,6 @@
 int InstanceMirrorKlass::                                                             \
 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                        \
   /* Get size before changing pointers */                                             \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
-                                                                                      \
   InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
                                                                                       \
   if_do_metadata_checked(closure, nv_suffix) {                                        \
@@ -275,8 +274,6 @@
 int InstanceMirrorKlass::                                                             \
 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {              \
   /* Get size before changing pointers */                                             \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
-                                                                                      \
   InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
                                                                                       \
   if (UseCompressedOops) {                                                            \
@@ -294,8 +291,6 @@
 oop_oop_iterate##nv_suffix##_m(oop obj,                                               \
                                OopClosureType* closure,                               \
                                MemRegion mr) {                                        \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
-                                                                                      \
   InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
                                                                                       \
   if_do_metadata_checked(closure, nv_suffix) {                                        \
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
 
 #include "classfile/systemDictionary.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceKlass.hpp"
 #include "runtime/handles.hpp"
 #include "utilities/macros.hpp"
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Jul 05 20:27:20 2017 +0200
@@ -30,6 +30,7 @@
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/genOopClosures.inline.hpp"
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/preserveException.hpp"
@@ -260,7 +261,6 @@
       return size;                                                              \
     } else if (contains(referent_addr)) {                                       \
       /* treat referent as normal oop */                                        \
-      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
       closure->do_oop##nv_suffix(referent_addr);                                \
     }                                                                           \
   }                                                                             \
@@ -276,7 +276,6 @@
                                  INTPTR_FORMAT, disc_addr);                     \
         }                                                                       \
       )                                                                         \
-      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
       closure->do_oop##nv_suffix(disc_addr);                                    \
     }                                                                           \
   } else {                                                                      \
@@ -293,7 +292,6 @@
   }                                                                             \
   /* treat next as normal oop */                                                \
   if (contains(next_addr)) {                                                    \
-    SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
     closure->do_oop##nv_suffix(next_addr);                                      \
   }                                                                             \
   return size;                                                                  \
@@ -309,8 +307,6 @@
 int InstanceRefKlass::                                                          \
 oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                  \
   /* Get size before changing pointers */                                       \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
-                                                                                \
   int size = InstanceKlass::oop_oop_iterate##nv_suffix(obj, closure);           \
                                                                                 \
   if (UseCompressedOops) {                                                      \
@@ -326,8 +322,6 @@
 int InstanceRefKlass::                                                          \
 oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {        \
   /* Get size before changing pointers */                                       \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
-                                                                                \
   int size = InstanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \
                                                                                 \
   if (UseCompressedOops) {                                                      \
@@ -345,8 +339,6 @@
 oop_oop_iterate##nv_suffix##_m(oop obj,                                         \
                                OopClosureType* closure,                         \
                                MemRegion mr) {                                  \
-  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);\
-                                                                                \
   int size = InstanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);   \
   if (UseCompressedOops) {                                                      \
     InstanceRefKlass_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr.contains); \
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Wed Apr 08 13:12:48 2015 -0700
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Wed Jul 05 20:27:20 2017 +0200
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
 #define SHARE_VM_OOPS_INSTANCEREFKLASS_HPP
 
+#include "memory/specialized_oop_closures.hpp"
 #include "oops/instanceKlass.hpp"
 #include "utilities/macros.hpp"
 
--- a/hotspot/src/share/vm/oops/klass.cpp	We