changeset 48128:2d91c9a4f409

Merge
author aph
date Mon, 27 Nov 2017 17:04:45 +0000
parents efc459cf351e 4e5124dacf91
children c134a8bee21a
files src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp src/hotspot/share/gc/g1/hSpaceCounters.cpp src/hotspot/share/gc/g1/hSpaceCounters.hpp src/java.desktop/share/classes/sun/java2d/pisces/Curve.java src/java.desktop/share/classes/sun/java2d/pisces/Dasher.java src/java.desktop/share/classes/sun/java2d/pisces/Helpers.java src/java.desktop/share/classes/sun/java2d/pisces/PiscesCache.java src/java.desktop/share/classes/sun/java2d/pisces/PiscesRenderingEngine.java src/java.desktop/share/classes/sun/java2d/pisces/PiscesTileGenerator.java src/java.desktop/share/classes/sun/java2d/pisces/Renderer.java src/java.desktop/share/classes/sun/java2d/pisces/Stroker.java src/java.desktop/share/classes/sun/java2d/pisces/TransformingPathConsumer2D.java src/java.desktop/unix/classes/sun/java2d/jules/IdleTileCache.java src/java.desktop/unix/classes/sun/java2d/jules/JulesAATileGenerator.java src/java.desktop/unix/classes/sun/java2d/jules/JulesPathBuf.java src/java.desktop/unix/classes/sun/java2d/jules/JulesRenderingEngine.java src/java.desktop/unix/classes/sun/java2d/jules/JulesShapePipe.java src/java.desktop/unix/classes/sun/java2d/jules/JulesTile.java src/java.desktop/unix/classes/sun/java2d/jules/TileTrapContainer.java src/java.desktop/unix/classes/sun/java2d/jules/TileWorker.java src/java.desktop/unix/classes/sun/java2d/jules/TrapezoidList.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TableHeader.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/GroupTypes.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/MethodTypes.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ModulePackageTypes.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TableTabTypes.java src/jdk.jshell/share/classes/jdk/jshell/tool/resources/JAVASE.jsh test/hotspot/jtreg/gc/metaspace/PerfCounter.java test/hotspot/jtreg/gc/metaspace/PerfCounters.java test/jdk/sun/java2d/pisces/OpenJDKFillBug.java test/jdk/sun/java2d/pisces/Renderer/Test7019861.java test/jdk/sun/java2d/pisces/Renderer/TestNPE.java test/jdk/sun/java2d/pisces/Test7036754.java test/jdk/sun/pisces/DashStrokeTest.java test/jdk/sun/pisces/JoinMiterTest.java test/jdk/sun/pisces/ScaleTest.java test/jdk/sun/pisces/StrokeShapeTest.java test/jdk/sun/pisces/TEST.properties test/jdk/sun/pisces/ThinLineTest.java test/langtools/tools/javadoc/sourceOnly/p/NonSource.class
diffstat 482 files changed, 15041 insertions(+), 13477 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Nov 24 17:19:47 2017 +0000
+++ b/.hgtags	Mon Nov 27 17:04:45 2017 +0000
@@ -456,3 +456,5 @@
 a6e591e12f122768f675428e1e5a838fd0e9c7ec jdk-10+29
 8fee80b92e65149f7414250fd5e34b6f35d417b4 jdk-10+30
 e6278add9ff28fab70fe1cc4c1d65f7363dc9445 jdk-10+31
+a2008587c13fa05fa2dbfcb09fe987576fbedfd1 jdk-10+32
+bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33
--- a/doc/building.html	Fri Nov 24 17:19:47 2017 +0000
+++ b/doc/building.html	Mon Nov 27 17:04:45 2017 +0000
@@ -871,9 +871,9 @@
 <p>When building for distribution, <code>zipped</code> is a good solution. Binaries built with <code>internal</code> is suitable for use by developers, since they facilitate debugging, but should be stripped before distributed to end users.</p>
 <h3 id="autoconf-details">Autoconf Details</h3>
 <p>The <code>configure</code> script is based on the autoconf framework, but in some details deviate from a normal autoconf <code>configure</code> script.</p>
-<p>The <code>configure</code> script in the top level directory of OpenJDK is just a thin wrapper that calls <code>common/autoconf/configure</code>. This in turn provides functionality that is not easily expressed in the normal Autoconf framework, and then calls into the core of the <code>configure</code> script, which is the <code>common/autoconf/generated-configure.sh</code> file.</p>
+<p>The <code>configure</code> script in the top level directory of OpenJDK is just a thin wrapper that calls <code>make/autoconf/configure</code>. This in turn provides functionality that is not easily expressed in the normal Autoconf framework, and then calls into the core of the <code>configure</code> script, which is the <code>make/autoconf/generated-configure.sh</code> file.</p>
 <p>As the name implies, this file is generated by Autoconf. It is checked in after regeneration, to alleviate the common user to have to install Autoconf.</p>
-<p>The build system will detect if the Autoconf source files have changed, and will trigger a regeneration of <code>common/autoconf/generated-configure.sh</code> if needed. You can also manually request such an update by <code>bash common/autoconf/autogen.sh</code>.</p>
+<p>The build system will detect if the Autoconf source files have changed, and will trigger a regeneration of <code>make/autoconf/generated-configure.sh</code> if needed. You can also manually request such an update by <code>bash make/autoconf/autogen.sh</code>.</p>
 <p>If you make changes to the build system that requires a re-generation, note the following:</p>
 <ul>
 <li><p>You must use <em>exactly</em> version 2.69 of autoconf for your patch to be accepted. This is to avoid spurious changes in the generated file. Note that Ubuntu 16.04 ships a patched version of autoconf which claims to be 2.69, but is not.</p></li>
--- a/doc/building.md	Fri Nov 24 17:19:47 2017 +0000
+++ b/doc/building.md	Mon Nov 27 17:04:45 2017 +0000
@@ -1660,18 +1660,18 @@
 deviate from a normal autoconf `configure` script.
 
 The `configure` script in the top level directory of OpenJDK is just a thin
-wrapper that calls `common/autoconf/configure`. This in turn provides
+wrapper that calls `make/autoconf/configure`. This in turn provides
 functionality that is not easily expressed in the normal Autoconf framework,
 and then calls into the core of the `configure` script, which is the
-`common/autoconf/generated-configure.sh` file.
+`make/autoconf/generated-configure.sh` file.
 
 As the name implies, this file is generated by Autoconf. It is checked in after
 regeneration, to alleviate the common user to have to install Autoconf.
 
 The build system will detect if the Autoconf source files have changed, and
-will trigger a regeneration of `common/autoconf/generated-configure.sh` if
+will trigger a regeneration of `make/autoconf/generated-configure.sh` if
 needed. You can also manually request such an update by `bash
-common/autoconf/autogen.sh`.
+make/autoconf/autogen.sh`.
 
 If you make changes to the build system that requires a re-generation, note the
 following:
--- a/make/Init.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/Init.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -329,7 +329,7 @@
 	$(call PrintFailureReports)
 	$(call PrintBuildLogFailures)
 	$(call ReportProfileTimes)
-	$(PRINTF) "Hint: See common/doc/building.html#troubleshooting for assistance.\n\n"
+	$(PRINTF) "Hint: See doc/building.html#troubleshooting for assistance.\n\n"
         ifneq ($(COMPARE_BUILD), )
 	  $(call CleanupCompareBuild)
         endif
--- a/make/RunTests.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/RunTests.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -32,9 +32,6 @@
 # We will always run multiple tests serially
 .NOTPARALLEL:
 
-# Directories to find jtreg tests relative to
-JTREG_TEST_TOPDIRS := $(TOPDIR) $(JTREG_TESTROOTS)
-
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, RunTests.gmk))
 
@@ -119,12 +116,40 @@
   )
 endef
 
+# Take a partial Jtreg root path and return a full, absolute path to that Jtreg
+# root. Also support having "hotspot" as an alias for "hotspot/jtreg".
+ExpandJtregRoot = \
+  $(strip $(wildcard $(patsubst %/, %, \
+    $(if $(filter /%, $1), \
+      $1 \
+    , \
+      $(filter $(addprefix %, $1), $(JTREG_TESTROOTS) $(addsuffix /, $(JTREG_TESTROOTS))) \
+      $(filter $(addprefix %, $(strip $1)/jtreg), $(JTREG_TESTROOTS) $(addsuffix /, $(JTREG_TESTROOTS))) \
+    ) \
+  )))
+
+# Take a partial Jtreg test path and return a full, absolute path to that Jtreg
+# test. Also support having "hotspot" as an alias for "hotspot/jtreg".
+ExpandJtregPath = \
+  $(if $(call ExpandJtregRoot, $1), \
+    $(call ExpandJtregRoot, $1) \
+  , \
+    $(strip $(wildcard $(patsubst %/, %, \
+      $(if $(filter /%, $1), \
+        $1 \
+      , \
+        $(addsuffix /$(strip $1), $(JTREG_TESTROOTS) $(TEST_BASEDIRS)) \
+        $(addsuffix $(strip $(patsubst hotspot/%, /hotspot/jtreg/%, $1)), $(JTREG_TESTROOTS) $(TEST_BASEDIRS)) \
+      ) \
+    ))) \
+  )
+
 # Helper function to determine if a test specification is a Jtreg test
 #
 # It is a Jtreg test if it optionally begins with jtreg:, and then is either
 # an unspecified group name (possibly prefixed by :), or a group in a
-# specified test/<component> directory, or a path to a test or test directory,
-# either absolute or relative to any of the JTREG_TEST_TOPDIRS.
+# specified test root, or a path to a test or test directory,
+# either absolute or relative to any of the TEST_BASEDIRS or test roots.
 define ParseJtregTestSelection
   $(eval TEST_NAME := $(strip $(patsubst jtreg:%, %, $1))) \
   $(if $(or $(findstring :, $(TEST_NAME)), $(findstring /, $(TEST_NAME))), , \
@@ -132,20 +157,16 @@
   ) \
   $(if $(findstring :, $(TEST_NAME)), \
     $(if $(filter :%, $(TEST_NAME)), \
-      $(foreach root, $(JTREG_TESTROOTS), \
-        $(if $(filter $(patsubst :%, %, $(TEST_NAME)), \
-            $($(root)_JTREG_TEST_GROUPS)), \
-          jtreg:$(root):$(patsubst :%,%,$(TEST_NAME)) \
-        ) \
-      ) \
+      $(eval TEST_GROUP := $(patsubst :%, %, $(TEST_NAME))) \
+      $(eval TEST_ROOTS := $(JTREG_TESTROOTS)) \
     , \
-      $(eval ROOT_PART := $(word 1, $(subst :, $(SPACE), $(TEST_NAME)))) \
-      $(eval ROOT := $(filter $(addprefix %, $(ROOT_PART)), $(JTREG_TESTROOTS))) \
-      $(eval GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \
-      $(foreach root, $(ROOT), \
-        $(if $(filter $(GROUP), $($(root)_JTREG_TEST_GROUPS)), \
-          jtreg:$(root):$(GROUP) \
-        ) \
+      $(eval TEST_PATH := $(word 1, $(subst :, $(SPACE), $(TEST_NAME)))) \
+      $(eval TEST_GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \
+      $(eval TEST_ROOTS := $(call ExpandJtregRoot, $(TEST_PATH))) \
+    ) \
+    $(foreach test_root, $(TEST_ROOTS), \
+      $(if $(filter $(TEST_GROUP), $($(test_root)_JTREG_TEST_GROUPS)), \
+        jtreg:$(test_root):$(TEST_GROUP) \
       ) \
     ) \
   , \
@@ -154,7 +175,10 @@
         jtreg:$(TEST_NAME) \
       ) \
     , \
-      $(addprefix jtreg:, $(wildcard $(addsuffix /$(TEST_NAME), $(JTREG_TEST_TOPDIRS)))) \
+      $(eval TEST_PATHS := $(call ExpandJtregPath, $(TEST_NAME))) \
+      $(foreach test_path, $(TEST_PATHS), \
+        jtreg:$(test_path) \
+      ) \
     ) \
   )
 endef
@@ -162,7 +186,7 @@
 ifeq ($(TEST), )
   $(info No test selection given in TEST!)
   $(info Please use e.g. 'run-test TEST=tier1' or 'run-test-tier1')
-  $(info See common/doc/testing.[md|html] for help)
+  $(info See doc/testing.[md|html] for help)
   $(error Cannot continue)
 endif
 
@@ -185,7 +209,7 @@
 
 ifneq ($(UNKNOWN_TEST), )
   $(info Unknown test selection: '$(UNKNOWN_TEST)')
-  $(info See common/doc/testing.[md|html] for help)
+  $(info See doc/testing.[md|html] for help)
   $(error Cannot continue)
 endif
 
@@ -299,8 +323,17 @@
   $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
 
   $1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST)))
-  $1_COMPONENT := $$(firstword $$(subst /, $$(SPACE), \
-      $$(patsubst test/%, %, $$($1_TEST_NAME))))
+
+  $1_COMPONENT := \
+      $$(strip $$(foreach root, $$(JTREG_TESTROOTS), \
+        $$(if $$(filter $$(root)%, $$($1_TEST_NAME)), \
+          $$(lastword $$(subst /, $$(SPACE), $$(root))) \
+        ) \
+      ))
+  # This will work only as long as just hotspot has the additional "jtreg" directory
+  ifeq ($$($1_COMPONENT), jtreg)
+    $1_COMPONENT := hotspot
+  endif
 
   ifeq ($$(JT_HOME), )
     $$(info Error: jtreg framework is not found.)
--- a/make/autoconf/configure	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/autoconf/configure	Mon Nov 27 17:04:45 2017 +0000
@@ -90,13 +90,13 @@
 
 check_hg_updates() {
   if test "x`which hg 2> /dev/null | grep -v '^no hg in'`" != x; then
-    conf_updated_autoconf_files=`cd $conf_script_dir && hg status -mard 2> /dev/null | grep autoconf`
+    conf_updated_autoconf_files=`cd $conf_script_dir && hg status -mard . 2> /dev/null`
     if test "x$conf_updated_autoconf_files" != x; then
       echo "Configure source code has been updated, checking time stamps"
       check_autoconf_timestamps
     elif test "x$CUSTOM_CONFIG_DIR" != x; then
       # If custom source configure is available, make sure it is up-to-date as well.
-      conf_custom_updated_autoconf_files=`cd $CUSTOM_CONFIG_DIR && hg status -mard 2> /dev/null | grep autoconf`
+      conf_custom_updated_autoconf_files=`cd $CUSTOM_CONFIG_DIR && hg status -mard . 2> /dev/null`
       if test "x$conf_custom_updated_autoconf_files" != x; then
         echo "Configure custom source code has been updated, checking time stamps"
         check_autoconf_timestamps
--- a/make/autoconf/generated-configure.sh	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/autoconf/generated-configure.sh	Mon Nov 27 17:04:45 2017 +0000
@@ -656,7 +656,6 @@
 ENABLE_INTREE_EC
 VALID_JVM_FEATURES
 JVM_FEATURES_custom
-JVM_FEATURES_zeroshark
 JVM_FEATURES_zero
 JVM_FEATURES_minimal
 JVM_FEATURES_core
@@ -676,10 +675,6 @@
 PNG_CFLAGS
 USE_EXTERNAL_LIBGIF
 USE_EXTERNAL_LIBJPEG
-LLVM_LIBS
-LLVM_LDFLAGS
-LLVM_CFLAGS
-LLVM_CONFIG
 LIBFFI_LIB_FILE
 ENABLE_LIBFFI_BUNDLING
 LIBFFI_LIBS
@@ -1993,6 +1988,7 @@
   --enable-cds[=yes/no]   enable class data sharing feature in non-minimal VM.
                           Default is yes.
   --disable-hotspot-gtest Disables building of the Hotspot unit tests
+                          [enabled]
   --disable-freetype-bundling
                           disable bundling of the freetype library with the
                           build result [enabled on Windows or when using
@@ -2033,8 +2029,7 @@
   --with-debug-level      set the debug level (release, fastdebug, slowdebug,
                           optimized) [release]
   --with-jvm-variants     JVM variants (separated by commas) to build
-                          (server,client,minimal,core,zero,zeroshark,custom)
-                          [server]
+                          (server,client,minimal,core,zero,custom) [server]
   --with-cpu-port         specify sources to use for Hotspot 64-bit ARM port
                           (arm64,aarch64) [aarch64]
   --with-devkit           use this devkit for compilers, tools and resources
@@ -4272,12 +4267,12 @@
 #
 
 # All valid JVM features, regardless of platform
-VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+VALID_JVM_FEATURES="compiler1 compiler2 zero minimal dtrace jvmti jvmci \
     graal vm-structs jni-check services management all-gcs nmt cds \
     static-build link-time-opt aot"
 
 # All valid JVM variants
-VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
+VALID_JVM_VARIANTS="server client minimal core zero custom"
 
 ###############################################################################
 # Check if the specified JVM variant should be built. To be used in shell if
@@ -4308,7 +4303,6 @@
 #   minimal: reduced form of client with optional features stripped out
 #   core: normal interpreter only, no compiler
 #   zero: C++ based interpreter only, no compiler
-#   zeroshark: C++ based interpreter, and a llvm-based compiler
 #   custom: baseline JVM with no default features
 #
 
@@ -4809,11 +4803,6 @@
 
 
 ################################################################################
-# Setup llvm (Low-Level VM)
-################################################################################
-
-
-################################################################################
 # Setup various libraries, typically small system libraries
 ################################################################################
 
@@ -5166,7 +5155,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1509128484
+DATE_WHEN_GENERATED=1511254554
 
 ###############################################################################
 #
@@ -17069,7 +17058,7 @@
 
 
 
-  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
     # zero behaves as a platform and rewrites these values. This is really weird. :(
     # We are guaranteed that we do not build any other variants when building zero.
     HOTSPOT_TARGET_CPU=zero
@@ -25114,7 +25103,7 @@
 
   # Should we build the serviceability agent (SA)?
   INCLUDE_SA=true
-  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
     INCLUDE_SA=false
   fi
   if test "x$OPENJDK_TARGET_OS" = xaix ; then
@@ -51971,7 +51960,7 @@
 
 
     fi
-    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
       # Non-zero builds have stricter warnings
       JVM_CFLAGS="$JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
     else
@@ -52852,7 +52841,7 @@
 
 
     fi
-    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
       # Non-zero builds have stricter warnings
       OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
     else
@@ -54613,7 +54602,7 @@
   fi
 
   # Check if ffi is needed
-  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
     NEEDS_LIB_FFI=true
   else
     NEEDS_LIB_FFI=false
@@ -54686,8 +54675,7 @@
     # If dynamic wasn't requested, go with static unless it isn't available.
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
 $as_echo_n "checking how to link with libstdc++... " >&6; }
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
-        ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno ; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
 $as_echo "dynamic" >&6; }
     else
@@ -65169,94 +65157,6 @@
 
 
 
-  if   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
-    # Extract the first word of "llvm-config", so it can be a program name with args.
-set dummy llvm-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_LLVM_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$LLVM_CONFIG"; then
-  ac_cv_prog_LLVM_CONFIG="$LLVM_CONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_LLVM_CONFIG="llvm-config"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-LLVM_CONFIG=$ac_cv_prog_LLVM_CONFIG
-if test -n "$LLVM_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_CONFIG" >&5
-$as_echo "$LLVM_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-    if test "x$LLVM_CONFIG" != xllvm-config; then
-      as_fn_error $? "llvm-config not found in $PATH." "$LINENO" 5
-    fi
-
-    llvm_components="jit mcjit engine nativecodegen native"
-    unset LLVM_CFLAGS
-    for flag in $("$LLVM_CONFIG" --cxxflags); do
-      if echo "${flag}" | grep -q '^-[ID]'; then
-        if test "${flag}" != "-D_DEBUG" ; then
-          if test "${LLVM_CFLAGS}" != "" ; then
-            LLVM_CFLAGS="${LLVM_CFLAGS} "
-          fi
-          LLVM_CFLAGS="${LLVM_CFLAGS}${flag}"
-        fi
-      fi
-    done
-    llvm_version=$("${LLVM_CONFIG}" --version | $SED 's/\.//; s/svn.*//')
-    LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}"
-
-    unset LLVM_LDFLAGS
-    for flag in $("${LLVM_CONFIG}" --ldflags); do
-      if echo "${flag}" | grep -q '^-L'; then
-        if test "${LLVM_LDFLAGS}" != ""; then
-          LLVM_LDFLAGS="${LLVM_LDFLAGS} "
-        fi
-        LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}"
-      fi
-    done
-
-    unset LLVM_LIBS
-    for flag in $("${LLVM_CONFIG}" --libs ${llvm_components}); do
-      if echo "${flag}" | grep -q '^-l'; then
-        if test "${LLVM_LIBS}" != ""; then
-          LLVM_LIBS="${LLVM_LIBS} "
-        fi
-        LLVM_LIBS="${LLVM_LIBS}${flag}"
-      fi
-    done
-
-    # Due to https://llvm.org/bugs/show_bug.cgi?id=16902, llvm does not
-    # always properly detect -ltinfo
-    LLVM_LIBS="${LLVM_LIBS} -ltinfo"
-
-
-
-
-  fi
-
-
 
 # Check whether --with-libjpeg was given.
 if test "${with_libjpeg+set}" = set; then :
@@ -66053,7 +65953,6 @@
 
 
 
-
 # Hotspot setup depends on lib checks.
 
 
@@ -66124,15 +66023,9 @@
     fi
   fi
 
-  if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+  if !   [[ " $JVM_VARIANTS " =~ " zero " ]]  ; then
     if   [[ " $JVM_FEATURES " =~ " zero " ]]  ; then
-      as_fn_error $? "To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark" "$LINENO" 5
-    fi
-  fi
-
-  if !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
-    if   [[ " $JVM_FEATURES " =~ " shark " ]]  ; then
-      as_fn_error $? "To enable shark, you must use --with-jvm-variants=zeroshark" "$LINENO" 5
+      as_fn_error $? "To enable zero, you must use --with-jvm-variants=zero" "$LINENO" 5
     fi
   fi
 
@@ -66216,7 +66109,6 @@
   JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
   JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES $JVM_FEATURES_link_time_opt"
   JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
-  JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
   JVM_FEATURES_custom="$JVM_FEATURES"
 
 
@@ -66226,7 +66118,6 @@
 
 
 
-
   # Used for verification of Makefiles by check-jvm-feature
 
 
@@ -68104,7 +67995,6 @@
   JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
   JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
   JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
-  JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
   JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
 
   # Validate features
--- a/make/autoconf/hotspot.m4	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/autoconf/hotspot.m4	Mon Nov 27 17:04:45 2017 +0000
@@ -393,7 +393,7 @@
   NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti vm-structs jni-check services management all-gcs nmt"
   if test "x$ENABLE_CDS" = "xtrue"; then
     NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cds"
-  fi                                            
+  fi
 
   # Enable features depending on variant.
   JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci $JVM_FEATURES_aot $JVM_FEATURES_graal"
@@ -476,7 +476,7 @@
 AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_GTEST],
 [
   AC_ARG_ENABLE([hotspot-gtest], [AS_HELP_STRING([--disable-hotspot-gtest],
-      [Disables building of the Hotspot unit tests])])
+      [Disables building of the Hotspot unit tests @<:@enabled@:>@])])
 
   if test -e "${TOPDIR}/test/hotspot/gtest"; then
     GTEST_DIR_EXISTS="true"
--- a/make/common/FindTests.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/common/FindTests.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -29,6 +29,9 @@
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, common/FindTests.gmk))
 
+# TEST_BASEDIRS might have been set by a custom extension
+TEST_BASEDIRS += $(TOPDIR)/test $(TOPDIR)
+
 # JTREG_TESTROOTS might have been set by a custom extension
 JTREG_TESTROOTS += $(addprefix $(TOPDIR)/test/, hotspot/jtreg jdk langtools nashorn jaxp)
 
--- a/make/common/Modules.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/common/Modules.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -328,8 +328,9 @@
 	      $(NAWK) -v MODULE=$(call GetModuleNameFromModuleInfo, $m) '\
 	          BEGIN      { if (MODULE != "java.base") printf(" java.base"); } \
 	          /^ *requires/ { sub(/;/, ""); \
-	                          sub(/requires/, ""); \
-	                          sub(/transitive/, ""); \
+	                          sub(/requires /, " "); \
+	                          sub(/ static /, " "); \
+	                          sub(/ transitive /, " "); \
 	                          sub(/\/\/.*/, ""); \
 	                          sub(/\/\*.*\*\//, ""); \
 	                          gsub(/^ +\*.*/, ""); \
--- a/make/conf/jib-profiles.js	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/conf/jib-profiles.js	Mon Nov 27 17:04:45 2017 +0000
@@ -203,7 +203,7 @@
     data.src_bundle_excludes = "./build webrev* */webrev* */*/webrev* */*/*/webrev* .hg */.hg */*/.hg */*/*/.hg";
     // Include list to use when creating a minimal jib source bundle which
     // contains just the jib configuration files.
-    data.conf_bundle_includes = "*/conf/jib-profiles.* common/autoconf/version-numbers"
+    data.conf_bundle_includes = "*/conf/jib-profiles.* make/autoconf/version-numbers"
 
     // Define some common values
     var common = getJibProfilesCommon(input, data);
@@ -1043,7 +1043,7 @@
 
 /**
  * Constructs the numeric version string from reading the
- * common/autoconf/version-numbers file and removing all trailing ".0".
+ * make/autoconf/version-numbers file and removing all trailing ".0".
  *
  * @param major Override major version
  * @param minor Override minor version
@@ -1080,17 +1080,17 @@
     return args;
 }
 
-// Properties representation of the common/autoconf/version-numbers file. Lazily
+// Properties representation of the make/autoconf/version-numbers file. Lazily
 // initiated by the function below.
 var version_numbers;
 
 /**
- * Read the common/autoconf/version-numbers file into a Properties object.
+ * Read the make/autoconf/version-numbers file into a Properties object.
  *
  * @returns {java.utilProperties}
  */
 var getVersionNumbers = function () {
-    // Read version information from common/autoconf/version-numbers
+    // Read version information from make/autoconf/version-numbers
     if (version_numbers == null) {
         version_numbers = new java.util.Properties();
         var stream = new java.io.FileInputStream(__DIR__ + "/../autoconf/version-numbers");
--- a/make/data/lsrdata/language-subtag-registry.txt	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/data/lsrdata/language-subtag-registry.txt	Mon Nov 27 17:04:45 2017 +0000
@@ -1,4 +1,4 @@
-File-Date: 2016-02-10
+File-Date: 2017-08-15
 %%
 Type: language
 Subtag: aa
@@ -106,6 +106,7 @@
 Type: language
 Subtag: bn
 Description: Bengali
+Description: Bangla
 Added: 2005-10-16
 Suppress-Script: Beng
 %%
@@ -792,6 +793,7 @@
 Type: language
 Subtag: or
 Description: Oriya (macrolanguage)
+Description: Odia (macrolanguage)
 Added: 2005-10-16
 Suppress-Script: Orya
 Scope: macrolanguage
@@ -4107,7 +4109,7 @@
 %%
 Type: language
 Subtag: bcg
-Description: Baga Binari
+Description: Baga Pokur
 Added: 2009-07-29
 %%
 Type: language
@@ -4641,6 +4643,8 @@
 Subtag: bgm
 Description: Baga Mboteni
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: bcg
 %%
 Type: language
 Subtag: bgn
@@ -5330,6 +5334,7 @@
 %%
 Type: language
 Subtag: blv
+Description: Kibala
 Description: Bolo
 Added: 2009-07-29
 %%
@@ -5380,7 +5385,7 @@
 %%
 Type: language
 Subtag: bmf
-Description: Bom
+Description: Bom-Kim
 Added: 2009-07-29
 %%
 Type: language
@@ -6281,6 +6286,7 @@
 Subtag: btl
 Description: Bhatola
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: btm
@@ -7268,6 +7274,7 @@
 Subtag: cbe
 Description: Chipiajes
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: cbg
@@ -7278,6 +7285,7 @@
 Subtag: cbh
 Description: Cagua
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: cbi
@@ -8071,6 +8079,7 @@
 %%
 Type: language
 Subtag: cnh
+Description: Hakha Chin
 Description: Haka Chin
 Added: 2009-07-29
 %%
@@ -8230,6 +8239,8 @@
 Subtag: coy
 Description: Coyaima
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: pij
 %%
 Type: language
 Subtag: coz
@@ -8320,6 +8331,8 @@
 Subtag: cqu
 Description: Chilean Quechua
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: quh
 Macrolanguage: qu
 %%
 Type: language
@@ -8666,6 +8679,7 @@
 %%
 Type: language
 Subtag: cug
+Description: Chungmboko
 Description: Cung
 Added: 2009-07-29
 %%
@@ -8700,6 +8714,7 @@
 Subtag: cum
 Description: Cumeral
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: cuo
@@ -9320,6 +9335,7 @@
 %%
 Type: language
 Subtag: dhg
+Description: Dhangu-Djangu
 Description: Dhangu
 Description: Djangu
 Added: 2009-07-29
@@ -9958,7 +9974,7 @@
 %%
 Type: language
 Subtag: dri
-Description: C'lela
+Description: C'Lela
 Added: 2009-07-29
 %%
 Type: language
@@ -10090,12 +10106,18 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: dtn
+Description: Daatsʼíin
+Added: 2016-05-30
+%%
+Type: language
 Subtag: dto
 Description: Tommo So Dogon
 Added: 2012-08-12
 %%
 Type: language
 Subtag: dtp
+Description: Kadazan Dusun
 Description: Central Dusun
 Added: 2009-07-29
 %%
@@ -10176,6 +10198,8 @@
 Subtag: duj
 Description: Dhuwal
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Comments: see dwu, dwy
 %%
 Type: language
 Subtag: duk
@@ -10250,7 +10274,7 @@
 %%
 Type: language
 Subtag: duz
-Description: Duli
+Description: Duli-Gey
 Added: 2009-07-29
 %%
 Type: language
@@ -10281,11 +10305,21 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: dwu
+Description: Dhuwal
+Added: 2016-05-30
+%%
+Type: language
 Subtag: dww
 Description: Dawawa
 Added: 2009-07-29
 %%
 Type: language
+Subtag: dwy
+Description: Dhuwaya
+Added: 2016-05-30
+%%
+Type: language
 Subtag: dya
 Description: Dyan
 Added: 2009-07-29
@@ -10818,6 +10852,12 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: esg
+Description: Aheri Gondi
+Added: 2016-05-30
+Macrolanguage: gon
+%%
+Type: language
 Subtag: esh
 Description: Eshtehardi
 Added: 2009-07-29
@@ -11214,6 +11254,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: fnb
+Description: Fanbak
+Added: 2016-05-30
+%%
+Type: language
 Subtag: fng
 Description: Fanagalo
 Added: 2009-07-29
@@ -11898,7 +11943,7 @@
 %%
 Type: language
 Subtag: gek
-Description: Yiwom
+Description: Ywom
 Added: 2009-07-29
 %%
 Type: language
@@ -12003,12 +12048,15 @@
 Subtag: ggn
 Description: Eastern Gurung
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: gvr
 %%
 Type: language
 Subtag: ggo
 Description: Southern Gondi
 Added: 2009-07-29
-Macrolanguage: gon
+Deprecated: 2016-05-30
+Comments: see esg, wsg
 %%
 Type: language
 Subtag: ggr
@@ -12110,6 +12158,12 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: gie
+Description: Gaɓogbo
+Description: Guébie
+Added: 2017-02-23
+%%
+Type: language
 Subtag: gig
 Description: Goaria
 Added: 2009-07-29
@@ -12212,6 +12266,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: gjr
+Description: Gurindji Kriol
+Added: 2016-05-30
+%%
+Type: language
 Subtag: gju
 Description: Gujari
 Added: 2009-07-29
@@ -12791,6 +12850,7 @@
 %%
 Type: language
 Subtag: gsn
+Description: Nema
 Description: Gusan
 Added: 2009-07-29
 %%
@@ -12942,6 +13002,8 @@
 Subtag: guv
 Description: Gey
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: duz
 %%
 Type: language
 Subtag: guw
@@ -13011,7 +13073,7 @@
 %%
 Type: language
 Subtag: gvr
-Description: Western Gurung
+Description: Gurung
 Added: 2009-07-29
 %%
 Type: language
@@ -14195,6 +14257,7 @@
 Subtag: iap
 Description: Iapama
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: iar
@@ -14227,6 +14290,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: ibh
+Description: Bih
+Added: 2017-02-23
+%%
+Type: language
 Subtag: ibi
 Description: Ibilo
 Added: 2009-07-29
@@ -14581,6 +14649,13 @@
 Subtag: ill
 Description: Iranun
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Comments: see ilm, ilp
+%%
+Type: language
+Subtag: ilm
+Description: Iranun (Malaysia)
+Added: 2016-05-30
 %%
 Type: language
 Subtag: ilo
@@ -14588,6 +14663,11 @@
 Added: 2005-10-16
 %%
 Type: language
+Subtag: ilp
+Description: Iranun (Philippines)
+Added: 2016-05-30
+%%
+Type: language
 Subtag: ils
 Description: International Sign
 Added: 2009-07-29
@@ -14901,6 +14981,11 @@
 Scope: collection
 %%
 Type: language
+Subtag: itd
+Description: Southern Tidung
+Added: 2016-05-30
+%%
+Type: language
 Subtag: ite
 Description: Itene
 Added: 2009-07-29
@@ -15252,6 +15337,8 @@
 Subtag: jeg
 Description: Jeng
 Added: 2009-07-29
+Deprecated: 2017-02-23
+Preferred-Value: oyb
 %%
 Type: language
 Subtag: jeh
@@ -15416,6 +15503,11 @@
 Added: 2012-08-12
 %%
 Type: language
+Subtag: jka
+Description: Kaera
+Added: 2016-05-30
+%%
+Type: language
 Subtag: jkm
 Description: Mobwa Karen
 Added: 2012-08-12
@@ -15796,6 +15888,7 @@
 %%
 Type: language
 Subtag: kak
+Description: Kalanguya
 Description: Kayapa Kallahan
 Added: 2009-07-29
 %%
@@ -16450,7 +16543,8 @@
 %%
 Type: language
 Subtag: kfr
-Description: Kachchi
+Description: Kachhi
+Description: Kutchi
 Added: 2009-07-29
 %%
 Type: language
@@ -16507,11 +16601,15 @@
 Subtag: kgc
 Description: Kasseng
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: tdf
 %%
 Type: language
 Subtag: kgd
 Description: Kataang
 Added: 2009-07-29
+Deprecated: 2017-02-23
+Comments: see ncq, sct
 %%
 Type: language
 Subtag: kge
@@ -17238,6 +17336,7 @@
 %%
 Type: language
 Subtag: klw
+Description: Tado
 Description: Lindu
 Added: 2009-07-29
 %%
@@ -17621,6 +17720,7 @@
 Subtag: kox
 Description: Coxima
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: koy
@@ -17955,6 +18055,8 @@
 Subtag: krm
 Description: Krim
 Added: 2009-07-29
+Deprecated: 2017-02-23
+Preferred-Value: bmf
 %%
 Type: language
 Subtag: krn
@@ -17974,7 +18076,7 @@
 %%
 Type: language
 Subtag: krr
-Description: Kru'ng 2
+Description: Krung
 Added: 2009-07-29
 %%
 Type: language
@@ -18238,6 +18340,8 @@
 Subtag: ktr
 Description: Kota Marudu Tinagas
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: dtp
 %%
 Type: language
 Subtag: kts
@@ -18278,6 +18382,7 @@
 Subtag: ktz
 Description: Ju/'hoan
 Description: Juǀʼhoan
+Description: Juǀʼhoansi
 Added: 2009-07-29
 %%
 Type: language
@@ -18496,6 +18601,8 @@
 Subtag: kvs
 Description: Kunggara
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: gdj
 %%
 Type: language
 Subtag: kvt
@@ -18979,6 +19086,8 @@
 Subtag: kzj
 Description: Coastal Kadazan
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: dtp
 %%
 Type: language
 Subtag: kzk
@@ -19029,6 +19138,8 @@
 Subtag: kzt
 Description: Tambunan Dusun
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: dtp
 %%
 Type: language
 Subtag: kzu
@@ -19306,6 +19417,7 @@
 Type: language
 Subtag: lce
 Description: Loncong
+Description: Sekak
 Added: 2009-07-29
 Macrolanguage: ms
 %%
@@ -19602,6 +19714,7 @@
 %%
 Type: language
 Subtag: lgn
+Description: T'apo
 Description: Opuuo
 Added: 2009-07-29
 %%
@@ -20320,7 +20433,7 @@
 %%
 Type: language
 Subtag: lou
-Description: Louisiana Creole French
+Description: Louisiana Creole
 Added: 2009-07-29
 %%
 Type: language
@@ -20532,6 +20645,11 @@
 Macrolanguage: lv
 %%
 Type: language
+Subtag: lth
+Description: Thur
+Added: 2017-02-23
+%%
+Type: language
 Subtag: lti
 Description: Leti (Indonesia)
 Added: 2009-07-29
@@ -21926,6 +22044,11 @@
 Deprecated: 2011-08-16
 %%
 Type: language
+Subtag: mjb
+Description: Makalero
+Added: 2016-05-30
+%%
+Type: language
 Subtag: mjc
 Description: San Juan Colorado Mixtec
 Added: 2009-07-29
@@ -24093,6 +24216,8 @@
 Subtag: nad
 Description: Nijadali
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: xny
 %%
 Type: language
 Subtag: nae
@@ -24404,6 +24529,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: ncq
+Description: Northern Katang
+Added: 2017-02-23
+%%
+Type: language
 Subtag: ncr
 Description: Ncane
 Added: 2009-07-29
@@ -24802,6 +24932,7 @@
 %%
 Type: language
 Subtag: ngt
+Description: Kriang
 Description: Ngeq
 Added: 2009-07-29
 %%
@@ -25810,6 +25941,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: npx
+Description: Noipx
+Added: 2017-02-23
+%%
+Type: language
 Subtag: npy
 Description: Napu
 Added: 2009-07-29
@@ -25825,6 +25961,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: nql
+Description: Ngendelengo
+Added: 2017-02-23
+%%
+Type: language
 Subtag: nqm
 Description: Ndom
 Added: 2009-07-29
@@ -26062,6 +26203,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: ntd
+Description: Northern Tidung
+Added: 2016-05-30
+%%
+Type: language
 Subtag: nte
 Description: Nathembo
 Added: 2009-07-29
@@ -26110,6 +26256,8 @@
 Subtag: nts
 Description: Natagaimas
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: pij
 %%
 Type: language
 Subtag: ntu
@@ -26918,6 +27066,11 @@
 Added: 2014-02-28
 %%
 Type: language
+Subtag: olu
+Description: Kuvale
+Added: 2016-05-30
+%%
+Type: language
 Subtag: oma
 Description: Omaha-Ponca
 Added: 2009-07-29
@@ -26936,6 +27089,7 @@
 Subtag: ome
 Description: Omejes
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: omg
@@ -27219,6 +27373,7 @@
 %%
 Type: language
 Subtag: ory
+Description: Odia (individual language)
 Description: Oriya (individual language)
 Added: 2012-08-12
 Macrolanguage: or
@@ -27398,6 +27553,12 @@
 Preferred-Value: vaj
 %%
 Type: language
+Subtag: ovd
+Description: Elfdalian
+Description: Övdalian
+Added: 2016-06-16
+%%
+Type: language
 Subtag: owi
 Description: Owiniga
 Added: 2009-07-29
@@ -27941,6 +28102,11 @@
 Deprecated: 2012-08-12
 %%
 Type: language
+Subtag: pgz
+Description: Papua New Guinean Sign Language
+Added: 2016-05-30
+%%
+Type: language
 Subtag: pha
 Description: Pa-Hng
 Added: 2009-07-29
@@ -28343,6 +28509,8 @@
 Subtag: pmc
 Description: Palumata
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: huw
 %%
 Type: language
 Subtag: pmd
@@ -28580,6 +28748,7 @@
 Subtag: pod
 Description: Ponares
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: poe
@@ -28676,6 +28845,8 @@
 Subtag: ppa
 Description: Pao
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: bfy
 %%
 Type: language
 Subtag: ppe
@@ -28777,6 +28948,7 @@
 Subtag: prb
 Description: Lua'
 Added: 2009-07-29
+Deprecated: 2017-02-23
 %%
 Type: language
 Subtag: prc
@@ -28885,6 +29057,8 @@
 Subtag: pry
 Description: Pray 3
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: prt
 %%
 Type: language
 Subtag: prz
@@ -29104,6 +29278,7 @@
 Subtag: puk
 Description: Pu Ko
 Added: 2009-07-29
+Deprecated: 2017-02-23
 %%
 Type: language
 Subtag: pum
@@ -29874,6 +30049,7 @@
 Subtag: rie
 Description: Rien
 Added: 2009-07-29
+Deprecated: 2017-02-23
 %%
 Type: language
 Subtag: rif
@@ -30099,6 +30275,7 @@
 Subtag: rna
 Description: Runa
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: rnd
@@ -30241,6 +30418,7 @@
 Subtag: rsi
 Description: Rennellese Sign Language
 Added: 2009-07-29
+Deprecated: 2017-02-23
 %%
 Type: language
 Subtag: rsl
@@ -30248,6 +30426,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: rsm
+Description: Miriwoong Sign Language
+Added: 2016-05-30
+%%
+Type: language
 Subtag: rtc
 Description: Rungtu Chin
 Added: 2012-08-12
@@ -30401,6 +30584,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: rzh
+Description: Rāziḥī
+Added: 2016-05-30
+%%
+Type: language
 Subtag: saa
 Description: Saba
 Added: 2009-07-29
@@ -30729,6 +30917,11 @@
 Macrolanguage: den
 %%
 Type: language
+Subtag: sct
+Description: Southern Katang
+Added: 2017-02-23
+%%
+Type: language
 Subtag: scu
 Description: Shumcho
 Added: 2009-07-29
@@ -31515,6 +31708,8 @@
 Subtag: skk
 Description: Sok
 Added: 2009-07-29
+Deprecated: 2017-02-23
+Preferred-Value: oyb
 %%
 Type: language
 Subtag: skm
@@ -31849,6 +32044,7 @@
 Subtag: snh
 Description: Shinabo
 Added: 2009-07-29
+Deprecated: 2017-02-23
 %%
 Type: language
 Subtag: sni
@@ -32710,6 +32906,7 @@
 Subtag: svr
 Description: Savara
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: svs
@@ -33023,6 +33220,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: szs
+Description: Solomon Islands Sign Language
+Added: 2017-02-23
+%%
+Type: language
 Subtag: szv
 Description: Isu (Fako Division)
 Added: 2009-07-29
@@ -33458,6 +33660,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: tdm
+Description: Taruma
+Added: 2016-05-30
+%%
+Type: language
 Subtag: tdn
 Description: Tondano
 Added: 2009-07-29
@@ -33491,6 +33698,8 @@
 Subtag: tdu
 Description: Tempasuk Dusun
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: dtp
 %%
 Type: language
 Subtag: tdv
@@ -33771,6 +33980,8 @@
 Subtag: thc
 Description: Tai Hang Tong
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: tpo
 %%
 Type: language
 Subtag: thd
@@ -33891,6 +34102,8 @@
 Subtag: tid
 Description: Tidong
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Comments: see itd, ntd
 %%
 Type: language
 Subtag: tie
@@ -34246,6 +34459,7 @@
 %%
 Type: language
 Subtag: tlt
+Description: Sou Nama
 Description: Teluti
 Added: 2009-07-29
 %%
@@ -34358,6 +34572,8 @@
 Subtag: tmp
 Description: Tai Mène
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: tyj
 %%
 Type: language
 Subtag: tmq
@@ -34429,6 +34645,8 @@
 Subtag: tne
 Description: Tinoc Kallahan
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: kak
 %%
 Type: language
 Subtag: tnf
@@ -34529,7 +34747,7 @@
 %%
 Type: language
 Subtag: tnz
-Description: Tonga (Thailand)
+Description: Ten'edn
 Added: 2009-07-29
 %%
 Type: language
@@ -34551,6 +34769,7 @@
 Subtag: toe
 Description: Tomedes
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: tof
@@ -35596,6 +35815,7 @@
 Type: language
 Subtag: tyj
 Description: Tai Do
+Description: Tai Yo
 Added: 2009-07-29
 %%
 Type: language
@@ -35855,6 +36075,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: ukk
+Description: Muak Sa-aak
+Added: 2017-02-23
+%%
+Type: language
 Subtag: ukl
 Description: Ukrainian Sign Language
 Added: 2009-07-29
@@ -36989,6 +37214,11 @@
 Macrolanguage: raj
 %%
 Type: language
+Subtag: wbs
+Description: West Bengal Sign Language
+Added: 2017-02-23
+%%
+Type: language
 Subtag: wbt
 Description: Wanman
 Added: 2009-07-29
@@ -37169,6 +37399,7 @@
 %%
 Type: language
 Subtag: wha
+Description: Sou Upaa
 Description: Manusela
 Added: 2009-07-29
 %%
@@ -37739,6 +37970,12 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: wsg
+Description: Adilabad Gondi
+Added: 2016-05-30
+Macrolanguage: gon
+%%
+Type: language
 Subtag: wsi
 Description: Wusi
 Added: 2009-07-29
@@ -37971,6 +38208,11 @@
 Added: 2014-02-28
 %%
 Type: language
+Subtag: xak
+Description: Máku
+Added: 2016-05-30
+%%
+Type: language
 Subtag: xal
 Description: Kalmyk
 Description: Oirat
@@ -38041,6 +38283,8 @@
 Subtag: xba
 Description: Kamba (Brazil)
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: cax
 %%
 Type: language
 Subtag: xbb
@@ -38111,6 +38355,7 @@
 Subtag: xbx
 Description: Kabixí
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: xby
@@ -38214,6 +38459,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: xdo
+Description: Kwandu
+Added: 2017-02-23
+%%
+Type: language
 Subtag: xdy
 Description: Malayic Dayak
 Added: 2009-07-29
@@ -38408,6 +38658,7 @@
 Subtag: xip
 Description: Xipináwa
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: xir
@@ -38478,6 +38729,8 @@
 Subtag: xkh
 Description: Karahawyana
 Added: 2009-07-29
+Deprecated: 2016-05-30
+Preferred-Value: waw
 %%
 Type: language
 Subtag: xki
@@ -39328,6 +39581,7 @@
 Type: language
 Subtag: xuu
 Description: Kxoe
+Description: Khwedam
 Added: 2009-07-29
 %%
 Type: language
@@ -40394,6 +40648,7 @@
 Subtag: yri
 Description: Yarí
 Added: 2009-07-29
+Deprecated: 2016-05-30
 %%
 Type: language
 Subtag: yrk
@@ -40416,6 +40671,11 @@
 Added: 2009-07-29
 %%
 Type: language
+Subtag: yro
+Description: Yaroamë
+Added: 2016-05-30
+%%
+Type: language
 Subtag: yrs
 Description: Yarsun
 Added: 2009-07-29
@@ -40740,6 +41000,7 @@
 %%
 Type: language
 Subtag: zab
+Description: Western Tlacolula Valley Zapotec
 Description: San Juan Guelavía Zapotec
 Added: 2009-07-29
 Macrolanguage: zap
@@ -42633,6 +42894,7 @@
 Type: extlang
 Subtag: lce
 Description: Loncong
+Description: Sekak
 Added: 2009-07-29
 Preferred-Value: lce
 Prefix: ms
@@ -42953,6 +43215,13 @@
 Macrolanguage: ar
 %%
 Type: extlang
+Subtag: pgz
+Description: Papua New Guinean Sign Language
+Added: 2016-05-30
+Preferred-Value: pgz
+Prefix: sgn
+%%
+Type: extlang
 Subtag: pks
 Description: Pakistan Sign Language
 Added: 2009-07-29
@@ -43049,7 +43318,7 @@
 Subtag: rsi
 Description: Rennellese Sign Language
 Added: 2009-07-29
-Preferred-Value: rsi
+Deprecated: 2017-02-23
 Prefix: sgn
 %%
 Type: extlang
@@ -43060,6 +43329,13 @@
 Prefix: sgn
 %%
 Type: extlang
+Subtag: rsm
+Description: Miriwoong Sign Language
+Added: 2016-05-30
+Preferred-Value: rsm
+Prefix: sgn
+%%
+Type: extlang
 Subtag: sdl
 Description: Saudi Arabian Sign Language
 Added: 2009-07-29
@@ -43192,6 +43468,13 @@
 Prefix: sgn
 %%
 Type: extlang
+Subtag: szs
+Description: Solomon Islands Sign Language
+Added: 2017-02-23
+Preferred-Value: szs
+Prefix: sgn
+%%
+Type: extlang
 Subtag: tmw
 Description: Temuan
 Added: 2009-07-29
@@ -43342,6 +43625,13 @@
 Prefix: sgn
 %%
 Type: extlang
+Subtag: wbs
+Description: West Bengal Sign Language
+Added: 2017-02-23
+Preferred-Value: wbs
+Prefix: sgn
+%%
+Type: extlang
 Subtag: wuu
 Description: Wu Chinese
 Added: 2009-07-29
@@ -43522,6 +43812,7 @@
 Type: script
 Subtag: Beng
 Description: Bengali
+Description: Bangla
 Added: 2005-10-16
 %%
 Type: script
@@ -43595,8 +43886,13 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Cpmn
+Description: Cypro-Minoan
+Added: 2017-08-13
+%%
+Type: script
 Subtag: Cprt
-Description: Cypriot
+Description: Cypriot syllabary
 Added: 2005-10-16
 %%
 Type: script
@@ -43616,6 +43912,11 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Dogr
+Description: Dogra
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Dsrt
 Description: Deseret
 Description: Mormon
@@ -43661,7 +43962,7 @@
 %%
 Type: script
 Subtag: Geor
-Description: Georgian (Mkhedruli)
+Description: Georgian (Mkhedruli and Mtavruli)
 Added: 2005-10-16
 %%
 Type: script
@@ -43670,6 +43971,16 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Gong
+Description: Gunjala Gondi
+Added: 2017-01-13
+%%
+Type: script
+Subtag: Gonm
+Description: Masaram Gondi
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Goth
 Description: Gothic
 Added: 2005-10-16
@@ -43758,6 +44069,11 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Hmnp
+Description: Nyiakeng Puachue Hmong
+Added: 2017-08-13
+%%
+Type: script
 Subtag: Hrkt
 Description: Japanese syllabaries (alias for Hiragana + Katakana)
 Added: 2005-10-16
@@ -43933,6 +44249,11 @@
 Added: 2012-11-01
 %%
 Type: script
+Subtag: Maka
+Description: Makasar
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Mand
 Description: Mandaic
 Description: Mandaean
@@ -43954,6 +44275,13 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Medf
+Description: Medefaidrin
+Description: Oberi Okaime
+Description: Oberi Ɔkaimɛ
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Mend
 Description: Mende Kikakui
 Added: 2010-04-10
@@ -44036,10 +44364,18 @@
 Added: 2016-01-04
 %%
 Type: script
+Subtag: Nkdb
+Description: Naxi Dongba
+Description: na²¹ɕi³³ to³³ba²¹
+Description: Nakhi Tomba
+Added: 2017-08-13
+%%
+Type: script
 Subtag: Nkgb
+Description: Naxi Geba
+Description: na²¹ɕi³³ gʌ²¹ba²¹
+Description: 'Na-'Khi ²Ggŏ-¹baw
 Description: Nakhi Geba
-Description: 'Na-'Khi ²Ggŏ-¹baw
-Description: Naxi Geba
 Added: 2009-03-13
 %%
 Type: script
@@ -44075,6 +44411,7 @@
 Type: script
 Subtag: Orya
 Description: Oriya
+Description: Odia
 Added: 2005-10-16
 %%
 Type: script
@@ -44203,6 +44540,11 @@
 Added: 2011-01-07
 %%
 Type: script
+Subtag: Shui
+Description: Shuishu
+Added: 2017-08-13
+%%
+Type: script
 Subtag: Sidd
 Description: Siddham
 Description: Siddhaṃ
@@ -44226,6 +44568,11 @@
 Added: 2011-01-07
 %%
 Type: script
+Subtag: Soyo
+Description: Soyombo
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Sund
 Description: Sundanese
 Added: 2006-07-21
@@ -44357,6 +44704,11 @@
 Added: 2009-12-09
 %%
 Type: script
+Subtag: Wcho
+Description: Wancho
+Added: 2017-08-13
+%%
+Type: script
 Subtag: Wole
 Description: Woleai
 Added: 2011-01-07
@@ -44377,6 +44729,14 @@
 Added: 2005-10-16
 %%
 Type: script
+Subtag: Zanb
+Description: Zanabazar Square
+Description: Zanabazarin Dörböljin Useg
+Description: Xewtee Dörböljin Bicig
+Description: Horizontal Square Script
+Added: 2017-01-13
+%%
+Type: script
 Subtag: Zinh
 Description: Code for inherited script
 Added: 2009-04-03
@@ -44726,6 +45086,7 @@
 %%
 Type: region
 Subtag: CZ
+Description: Czechia
 Description: Czech Republic
 Added: 2005-10-16
 %%
@@ -44817,6 +45178,11 @@
 Added: 2009-07-29
 %%
 Type: region
+Subtag: EZ
+Description: Eurozone
+Added: 2016-07-14
+%%
+Type: region
 Subtag: FI
 Description: Finland
 Added: 2005-10-16
@@ -45675,6 +46041,11 @@
 Added: 2005-10-16
 %%
 Type: region
+Subtag: UN
+Description: United Nations
+Added: 2016-07-14
+%%
+Type: region
 Subtag: US
 Description: United States
 Added: 2005-10-16
@@ -45940,6 +46311,11 @@
 Added: 2005-10-16
 %%
 Type: region
+Subtag: 202
+Description: Sub-Saharan Africa
+Added: 2017-04-18
+%%
+Type: region
 Subtag: 419
 Description: Latin America and the Caribbean
 Added: 2005-10-16
@@ -46020,6 +46396,12 @@
   continuum in Eastern Suriname and Western French Guiana
 %%
 Type: variant
+Subtag: akuapem
+Description: Akuapem Twi
+Added: 2017-06-05
+Prefix: tw
+%%
+Type: variant
 Subtag: ao1990
 Description: Portuguese Language Orthographic Agreement of 1990 (Acordo
   Ortográfico da Língua Portuguesa de 1990)
@@ -46042,6 +46424,13 @@
 Prefix: hy
 %%
 Type: variant
+Subtag: asante
+Description: Asante Twi
+Description: Ashanti Twi
+Added: 2017-06-05
+Prefix: tw
+%%
+Type: variant
 Subtag: baku1926
 Description: Unified Turkic Latin Alphabet (Historical)
 Added: 2007-04-18
@@ -46167,6 +46556,12 @@
 Added: 2006-12-11
 %%
 Type: variant
+Subtag: fonnapa
+Description: North American Phonetic Alphabet
+Description: Americanist Phonetic Notation
+Added: 2016-06-24
+%%
+Type: variant
 Subtag: fonupa
 Description: Uralic Phonetic Alphabet
 Added: 2006-12-11
@@ -46201,6 +46596,13 @@
   including modern usage.
 %%
 Type: variant
+Subtag: hsistemo
+Description: Standard H-system orthographic fallback for spelling
+  Esperanto
+Added: 2017-03-14
+Prefix: eo
+%%
+Type: variant
 Subtag: ijekavsk
 Description: Serbian with Ijekavian pronunciation
 Prefix: sr
@@ -46346,6 +46748,27 @@
 Prefix: en
 %%
 Type: variant
+Subtag: pahawh2
+Description: Pahawh Hmong Second Stage Reduced orthography
+Added: 2017-01-13
+Prefix: mww
+Prefix: hnj
+%%
+Type: variant
+Subtag: pahawh3
+Description: Pahawh Hmong Third Stage Reduced orthography
+Added: 2017-01-13
+Prefix: mww
+Prefix: hnj
+%%
+Type: variant
+Subtag: pahawh4
+Description: Pahawh Hmong Final Version orthography
+Added: 2017-01-13
+Prefix: mww
+Prefix: hnj
+%%
+Type: variant
 Subtag: pamaka
 Description: Pamaka dialect
 Added: 2009-09-05
@@ -46442,6 +46865,14 @@
 Added: 2013-12-10
 %%
 Type: variant
+Subtag: spanglis
+Description: Spanglish
+Added: 2017-02-23
+Prefix: en
+Prefix: es
+Comments: A variety of contact dialects of English and Spanish
+%%
+Type: variant
 Subtag: surmiran
 Description: Surmiran idiom of Romansh
 Added: 2010-06-29
@@ -46533,6 +46964,13 @@
 Added: 2008-10-03
 Prefix: zh-Latn
 %%
+Type: variant
+Subtag: xsistemo
+Description: Standard X-system orthographic fallback for spelling
+  Esperanto
+Added: 2017-03-14
+Prefix: eo
+%%
 Type: grandfathered
 Tag: art-lojban
 Description: Lojban
--- a/make/hotspot/lib/CompileJvm.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/hotspot/lib/CompileJvm.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -114,7 +114,7 @@
     #
 
 # These files and directories are always excluded
-JVM_EXCLUDE_FILES += jsig.c args.cc
+JVM_EXCLUDE_FILES += args.cc
 JVM_EXCLUDES += adlc
 
 # Needed by vm_version.cpp
--- a/make/hotspot/lib/CompileLibjsig.gmk	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/hotspot/lib/CompileLibjsig.gmk	Mon Nov 27 17:04:45 2017 +0000
@@ -81,7 +81,7 @@
       $(error Unknown target OS $(OPENJDK_TARGET_OS) in CompileLibjsig.gmk)
     endif
 
-    LIBJSIG_SRC_FILE := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjsig/jsig.c
+    LIBJSIG_SRC_DIR := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjsig
     LIBJSIG_MAPFILE := $(wildcard $(TOPDIR)/make/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
     LIBJSIG_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/libjsig
 
@@ -91,7 +91,7 @@
 
     $(eval $(call SetupNativeCompilation, BUILD_LIBJSIG, \
         LIBRARY := jsig, \
-        EXTRA_FILES := $(LIBJSIG_SRC_FILE), \
+        SRC := $(LIBJSIG_SRC_DIR), \
         OUTPUT_DIR := $(LIB_OUTPUTDIR), \
         LANG := C, \
         CFLAGS := $(LIBJSIG_CFLAGS) $(LIBJSIG_CPU_FLAGS), \
--- a/make/mapfiles/libawt/mapfile-mawt-vers	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/mapfiles/libawt/mapfile-mawt-vers	Mon Nov 27 17:04:45 2017 +0000
@@ -177,7 +177,6 @@
         Java_sun_java2d_xr_XRBackendNative_setGCMode;
         Java_sun_java2d_xr_XRBackendNative_GCRectanglesNative;
         Java_sun_java2d_xr_XRUtils_initFormatPtrs;
-        Java_sun_java2d_xr_XRBackendNative_renderCompositeTrapezoidsNative;
         XRT_DrawGlyphList;
 
         Java_sun_java2d_opengl_OGLContext_getOGLIdString;
--- a/make/mapfiles/libawt_xawt/mapfile-vers	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/mapfiles/libawt_xawt/mapfile-vers	Mon Nov 27 17:04:45 2017 +0000
@@ -408,7 +408,6 @@
         Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative;
         Java_sun_java2d_xr_XRBackendNative_setGCMode;
         Java_sun_java2d_xr_XRBackendNative_GCRectanglesNative;
-        Java_sun_java2d_xr_XRBackendNative_renderCompositeTrapezoidsNative;
 
         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow;
         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box;
--- a/make/nashorn/build.xml	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/nashorn/build.xml	Mon Nov 27 17:04:45 2017 +0000
@@ -278,7 +278,7 @@
       <arg value="${javadoc.option}"/>
       <fileset dir="${nashorn.module.src.dir}" includes="**/*.java"/>
       <fileset dir="${dynalink.module.src.dir}" includes="**/*.java"/>
-      <link href="http://docs.oracle.com/javase/8/docs/api/"/>
+      <link offline="true" href="${javadoc.base.url}" packagelistLoc="${javadoc.pkg.list}"/>
     </javadoc>
   </target>
 
@@ -296,7 +296,7 @@
       <arg value="."/>
       <arg value="${javadoc.option}"/>
       <fileset dir="${nashorn.module.src.dir}" includes="jdk/nashorn/api/**/*.java"/>
-      <link href="http://docs.oracle.com/javase/8/docs/api/"/>
+      <link offline="true" href="${javadoc.base.url}" packagelistLoc="${javadoc.pkg.list}"/>
     </javadoc>
   </target>
 
@@ -314,7 +314,7 @@
       <arg value="."/>
       <arg value="${javadoc.option}"/>
       <fileset dir="${dynalink.module.src.dir}" includes="**/*.java"/>
-      <link href="http://docs.oracle.com/javase/8/docs/api/"/>
+      <link offline="true" href="${javadoc.base.url}" packagelistLoc="${javadoc.pkg.list}"/>
     </javadoc>
   </target>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/nashorn/package-list	Mon Nov 27 17:04:45 2017 +0000
@@ -0,0 +1,315 @@
+com.sun.jarsigner
+com.sun.java.accessibility.util
+com.sun.javadoc
+com.sun.jdi
+com.sun.jdi.connect
+com.sun.jdi.connect.spi
+com.sun.jdi.event
+com.sun.jdi.request
+com.sun.management
+com.sun.net.httpserver
+com.sun.net.httpserver.spi
+com.sun.nio.sctp
+com.sun.security.auth
+com.sun.security.auth.callback
+com.sun.security.auth.login
+com.sun.security.auth.module
+com.sun.security.jgss
+com.sun.source.doctree
+com.sun.source.tree
+com.sun.source.util
+com.sun.tools.attach
+com.sun.tools.attach.spi
+com.sun.tools.doclets
+com.sun.tools.doclets.standard
+com.sun.tools.javac
+com.sun.tools.javadoc
+com.sun.tools.jconsole
+java.applet
+java.awt
+java.awt.color
+java.awt.datatransfer
+java.awt.desktop
+java.awt.dnd
+java.awt.event
+java.awt.font
+java.awt.geom
+java.awt.im
+java.awt.im.spi
+java.awt.image
+java.awt.image.renderable
+java.awt.print
+java.beans
+java.beans.beancontext
+java.io
+java.lang
+java.lang.annotation
+java.lang.instrument
+java.lang.invoke
+java.lang.management
+java.lang.module
+java.lang.ref
+java.lang.reflect
+java.math
+java.net
+java.net.spi
+java.nio
+java.nio.channels
+java.nio.channels.spi
+java.nio.charset
+java.nio.charset.spi
+java.nio.file
+java.nio.file.attribute
+java.nio.file.spi
+java.rmi
+java.rmi.activation
+java.rmi.dgc
+java.rmi.registry
+java.rmi.server
+java.security
+java.security.acl
+java.security.cert
+java.security.interfaces
+java.security.spec
+java.sql
+java.text
+java.text.spi
+java.time
+java.time.chrono
+java.time.format
+java.time.temporal
+java.time.zone
+java.util
+java.util.concurrent
+java.util.concurrent.atomic
+java.util.concurrent.locks
+java.util.function
+java.util.jar
+java.util.logging
+java.util.prefs
+java.util.regex
+java.util.spi
+java.util.stream
+java.util.zip
+javafx.animation
+javafx.application
+javafx.beans
+javafx.beans.binding
+javafx.beans.property
+javafx.beans.property.adapter
+javafx.beans.value
+javafx.collections
+javafx.collections.transformation
+javafx.concurrent
+javafx.css
+javafx.css.converter
+javafx.embed.swing
+javafx.event
+javafx.fxml
+javafx.geometry
+javafx.print
+javafx.scene
+javafx.scene.canvas
+javafx.scene.chart
+javafx.scene.control
+javafx.scene.control.cell
+javafx.scene.control.skin
+javafx.scene.effect
+javafx.scene.image
+javafx.scene.input
+javafx.scene.layout
+javafx.scene.media
+javafx.scene.paint
+javafx.scene.shape
+javafx.scene.text
+javafx.scene.transform
+javafx.scene.web
+javafx.stage
+javafx.util
+javafx.util.converter
+javax.accessibility
+javax.activation
+javax.activity
+javax.annotation
+javax.annotation.processing
+javax.crypto
+javax.crypto.interfaces
+javax.crypto.spec
+javax.imageio
+javax.imageio.event
+javax.imageio.metadata
+javax.imageio.plugins.bmp
+javax.imageio.plugins.jpeg
+javax.imageio.plugins.tiff
+javax.imageio.spi
+javax.imageio.stream
+javax.jnlp
+javax.jws
+javax.jws.soap
+javax.lang.model
+javax.lang.model.element
+javax.lang.model.type
+javax.lang.model.util
+javax.management
+javax.management.loading
+javax.management.modelmbean
+javax.management.monitor
+javax.management.openmbean
+javax.management.relation
+javax.management.remote
+javax.management.remote.rmi
+javax.management.timer
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+javax.net
+javax.net.ssl
+javax.print
+javax.print.attribute
+javax.print.attribute.standard
+javax.print.event
+javax.rmi
+javax.rmi.CORBA
+javax.rmi.ssl
+javax.script
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.kerberos
+javax.security.auth.login
+javax.security.auth.spi
+javax.security.auth.x500
+javax.security.cert
+javax.security.sasl
+javax.smartcardio
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.sql
+javax.sql.rowset
+javax.sql.rowset.serial
+javax.sql.rowset.spi
+javax.swing
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.metal
+javax.swing.plaf.multi
+javax.swing.plaf.nimbus
+javax.swing.plaf.synth
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.tree
+javax.swing.undo
+javax.tools
+javax.transaction
+javax.transaction.xa
+javax.xml
+javax.xml.bind
+javax.xml.bind.annotation
+javax.xml.bind.annotation.adapters
+javax.xml.bind.attachment
+javax.xml.bind.helpers
+javax.xml.bind.util
+javax.xml.catalog
+javax.xml.crypto
+javax.xml.crypto.dom
+javax.xml.crypto.dsig
+javax.xml.crypto.dsig.dom
+javax.xml.crypto.dsig.keyinfo
+javax.xml.crypto.dsig.spec
+javax.xml.datatype
+javax.xml.namespace
+javax.xml.parsers
+javax.xml.soap
+javax.xml.stream
+javax.xml.stream.events
+javax.xml.stream.util
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stax
+javax.xml.transform.stream
+javax.xml.validation
+javax.xml.ws
+javax.xml.ws.handler
+javax.xml.ws.handler.soap
+javax.xml.ws.http
+javax.xml.ws.soap
+javax.xml.ws.spi
+javax.xml.ws.spi.http
+javax.xml.ws.wsaddressing
+javax.xml.xpath
+jdk.dynalink
+jdk.dynalink.beans
+jdk.dynalink.linker
+jdk.dynalink.linker.support
+jdk.dynalink.support
+jdk.incubator.http
+jdk.javadoc.doclet
+jdk.jfr
+jdk.jfr.consumer
+jdk.jshell
+jdk.jshell.execution
+jdk.jshell.spi
+jdk.jshell.tool
+jdk.management.cmm
+jdk.management.jfr
+jdk.management.resource
+jdk.nashorn.api.scripting
+jdk.nashorn.api.tree
+jdk.net
+jdk.packager.services
+jdk.security.jarsigner
+netscape.javascript
+org.ietf.jgss
+org.omg.CORBA
+org.omg.CORBA_2_3
+org.omg.CORBA_2_3.portable
+org.omg.CORBA.DynAnyPackage
+org.omg.CORBA.ORBPackage
+org.omg.CORBA.portable
+org.omg.CORBA.TypeCodePackage
+org.omg.CosNaming
+org.omg.CosNaming.NamingContextExtPackage
+org.omg.CosNaming.NamingContextPackage
+org.omg.Dynamic
+org.omg.DynamicAny
+org.omg.DynamicAny.DynAnyFactoryPackage
+org.omg.DynamicAny.DynAnyPackage
+org.omg.IOP
+org.omg.IOP.CodecFactoryPackage
+org.omg.IOP.CodecPackage
+org.omg.Messaging
+org.omg.PortableInterceptor
+org.omg.PortableInterceptor.ORBInitInfoPackage
+org.omg.PortableServer
+org.omg.PortableServer.CurrentPackage
+org.omg.PortableServer.POAManagerPackage
+org.omg.PortableServer.POAPackage
+org.omg.PortableServer.portable
+org.omg.PortableServer.ServantLocatorPackage
+org.omg.SendingContext
+org.omg.stub.java.rmi
+org.w3c.dom
+org.w3c.dom.bootstrap
+org.w3c.dom.css
+org.w3c.dom.events
+org.w3c.dom.html
+org.w3c.dom.ls
+org.w3c.dom.ranges
+org.w3c.dom.stylesheets
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.w3c.dom.xpath
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
--- a/make/nashorn/project.properties	Fri Nov 24 17:19:47 2017 +0000
+++ b/make/nashorn/project.properties	Mon Nov 27 17:04:45 2017 +0000
@@ -33,6 +33,12 @@
 # source and target levels
 build.compiler=modern
 
+jdk.build.dir=build
+nashorn.make.dir=make/nashorn
+
+javadoc.base.url=https://docs.oracle.com/javase/9/docs/api/
+javadoc.pkg.list=make/nashorn
+
 javadoc.option=\
     -tag "implSpec:a:Implementation Requirements:" \
     -tag "implNote:a:Implementation Note:" \
@@ -43,9 +49,6 @@
 nashorn.fullversion=0.1
 nashorn.product.name=Oracle Nashorn
 
-jdk.build.dir=build
-nashorn.make.dir=make/nashorn
-
 # This directory is removed when the project is cleaned:
 build.dir=${jdk.build.dir}/nashorn
 build.classes.dir=${build.dir}/classes
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -2968,7 +2968,9 @@
         CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-        Label L_cardtable_loop;
+        Label L_cardtable_loop, L_done;
+
+        __ cbz_32(count, L_done); // zero count - nothing to do
 
         __ add_ptr_scaled_int32(count, addr, count, LogBytesPerHeapOop);
         __ sub(count, count, BytesPerHeapOop);                            // last addr
@@ -2987,6 +2989,7 @@
         __ strb(zero, Address(addr, 1, post_indexed));
         __ subs(count, count, 1);
         __ b(L_cardtable_loop, ge);
+        __ BIND(L_done);
       }
       break;
     case BarrierSet::ModRef:
--- a/src/hotspot/cpu/s390/assembler_s390.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/s390/assembler_s390.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -582,7 +582,11 @@
 #define LOC_ZOPC    (unsigned long)(0xebL << 40 | 0xf2L)        // z196
 #define LOCG_ZOPC   (unsigned long)(0xebL << 40 | 0xe2L)        // z196
 
-#define LMG_ZOPC    (unsigned long)(235L << 40 | 4L)
+
+// LOAD multiple registers at once
+#define LM_ZOPC     (unsigned  int)(0x98  << 24)
+#define LMY_ZOPC    (unsigned long)(0xebL << 40 | 0x98L)
+#define LMG_ZOPC    (unsigned long)(0xebL << 40 | 0x04L)
 
 #define LE_ZOPC     (unsigned  int)(0x78 << 24)
 #define LEY_ZOPC    (unsigned long)(237L << 40 | 100L)
@@ -613,7 +617,10 @@
 #define STOC_ZOPC   (unsigned long)(0xebL << 40 | 0xf3L)        // z196
 #define STOCG_ZOPC  (unsigned long)(0xebL << 40 | 0xe3L)        // z196
 
-#define STMG_ZOPC   (unsigned long)(235L << 40 | 36L)
+// STORE multiple registers at once
+#define STM_ZOPC    (unsigned  int)(0x90  << 24)
+#define STMY_ZOPC   (unsigned long)(0xebL << 40 | 0x90L)
+#define STMG_ZOPC   (unsigned long)(0xebL << 40 | 0x24L)
 
 #define STE_ZOPC    (unsigned  int)(0x70 << 24)
 #define STEY_ZOPC   (unsigned long)(237L << 40 | 102L)
@@ -874,15 +881,19 @@
 
 // Shift
 // arithmetic
-#define SLA_ZOPC    (unsigned  int)(139 << 24)
-#define SLAG_ZOPC   (unsigned long)(235L << 40 | 11L)
-#define SRA_ZOPC    (unsigned  int)(138 << 24)
-#define SRAG_ZOPC   (unsigned long)(235L << 40 | 10L)
+#define SLA_ZOPC    (unsigned  int)(0x8b  << 24)
+#define SLAK_ZOPC   (unsigned long)(0xebL << 40 | 0xddL)
+#define SLAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0bL)
+#define SRA_ZOPC    (unsigned  int)(0x8a  << 24)
+#define SRAK_ZOPC   (unsigned long)(0xebL << 40 | 0xdcL)
+#define SRAG_ZOPC   (unsigned long)(0xebL << 40 | 0x0aL)
 // logical
-#define SLL_ZOPC    (unsigned  int)(137 << 24)
-#define SLLG_ZOPC   (unsigned long)(235L << 40 | 13L)
-#define SRL_ZOPC    (unsigned  int)(136 << 24)
-#define SRLG_ZOPC   (unsigned long)(235L << 40 | 12L)
+#define SLL_ZOPC    (unsigned  int)(0x89  << 24)
+#define SLLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdfL)
+#define SLLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0dL)
+#define SRL_ZOPC    (unsigned  int)(0x88  << 24)
+#define SRLK_ZOPC   (unsigned long)(0xebL << 40 | 0xdeL)
+#define SRLG_ZOPC   (unsigned long)(0xebL << 40 | 0x0cL)
 
 // Rotate, then AND/XOR/OR/insert
 // rotate
@@ -2262,12 +2273,16 @@
 
   // shift
   inline void z_sla( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
+  inline void z_slak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
   inline void z_slag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved!
   inline void z_sra( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended
+  inline void z_srak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, sign extended
   inline void z_srag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended
   inline void z_sll( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added
+  inline void z_sllk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int32, zeros added
   inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added
   inline void z_srl( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended
+  inline void z_srlk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, zero extended
   inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended
 
   // rotate
@@ -3035,7 +3050,11 @@
 
   inline void z_tam();
   inline void z_stckf(int64_t d2, Register b2);
+  inline void z_stm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_stmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_stmg(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lm( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lmy(Register r1, Register r3, int64_t d2, Register b2);
   inline void z_lmg(Register r1, Register r3, int64_t d2, Register b2);
 
   inline void z_cs( Register r1, Register r3, int64_t d2, Register b2);
--- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -334,12 +334,16 @@
 // SHIFT/RORATE OPERATIONS
 //-----------------------------------
 inline void Assembler::z_sla( Register r1,              int64_t d2, Register b2) { emit_32( SLA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_slak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_slag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sra( Register r1,              int64_t d2, Register b2) { emit_32( SRA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srak(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sll( Register r1,              int64_t d2, Register b2) { emit_32( SLL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_sllk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_sllg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srl( Register r1,              int64_t d2, Register b2) { emit_32( SRL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srlk(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLK_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 inline void Assembler::z_srlg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
 
 // rotate left
@@ -690,10 +694,14 @@
 
 inline void Assembler::z_tam() { emit_16( TAM_ZOPC); }
 inline void Assembler::z_stckf(int64_t d2, Register b2) { emit_32( STCKF_ZOPC | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
-inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
-inline void Assembler::z_lmg(Register r1, Register r3, int64_t d2, Register b2)  { emit_48( LMG_ZOPC  | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
+inline void Assembler::z_stm( Register r1, Register r3, int64_t d2, Register b2) { emit_32( STM_ZOPC  | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_stmy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMY_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lm(  Register r1, Register r3, int64_t d2, Register b2) { emit_32( LM_ZOPC   | reg(r1, 8, 32) | reg(r3,12,32)| reg(b2,16,32) | uimm12(d2, 20,32)); }
+inline void Assembler::z_lmy( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMY_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
+inline void Assembler::z_lmg( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LMG_ZOPC  | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) | simm20(d2) ); }
 
-inline void Assembler::z_cs(Register r1, Register r3, int64_t d2, Register b2)  { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
+inline void Assembler::z_cs( Register r1, Register r3, int64_t d2, Register b2) { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
 inline void Assembler::z_csy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSY_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_csg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
 inline void Assembler::z_cs( Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_cs( r1, r3, a.disp(), a.baseOrR0()); }
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -936,7 +936,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -956,7 +956,7 @@
 
   // Some extra safety net.
   if (!RelAddr::is_in_range_of_RelAddr32(total_distance)) {
-    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "too far away");
+    guarantee(RelAddr::is_in_range_of_RelAddr32(total_distance), "load_long_pcrelative can't handle distance " INTPTR_FORMAT, total_distance);
   }
 
   (this)->relocate(rspec, relocInfo::pcrel_addr_format);
@@ -1025,6 +1025,13 @@
   }
 }
 
+void MacroAssembler::prefetch_read(Address a) {
+  z_pfd(1, a.disp20(), a.indexOrR0(), a.base());
+}
+void MacroAssembler::prefetch_update(Address a) {
+  z_pfd(2, a.disp20(), a.indexOrR0(), a.base());
+}
+
 // Clear a register, i.e. load const zero into reg.
 // Return len (in bytes) of generated instruction(s).
 // whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -4896,77 +4903,295 @@
 
 // Intrinsics for CompactStrings
 
-// Compress char[] to byte[]. odd_reg contains cnt. Kills dst. Early clobber: result
+// Compress char[] to byte[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+//   Early clobber: result.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
 // The result is the number of characters copied before the first incompatible character was found.
-// If tmp2 is provided and the compression fails, the compression stops exactly at this point and the result is precise.
+// If precise is true, the processing stops exactly at this point. Otherwise, the result may be off
+// by a few bytes. The result always indicates the number of copied characters.
 //
 // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure:
-// - Different number of characters may have been written to dead array (if tmp2 not provided).
+// - Different number of characters may have been written to dead array (if precise is false).
 // - Returns a number <cnt instead of 0. (Result gets compared with cnt.)
-unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register odd_reg,
-                                             Register even_reg, Register tmp, Register tmp2) {
-  int block_start = offset();
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr2 = dst, ind1 = result, mask = tmp;
-  const bool precise = (tmp2 != noreg);
-
-  BLOCK_COMMENT("string_compress {");
-
-  z_sll(odd_reg, 1);       // Number of bytes to read. (Must be a positive simm32.)
-  clear_reg(ind1);         // Index to read.
-  z_llilf(mask, 0xFF00FF00);
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind1: index, even_reg: index increment, odd_reg: index limit
-  z_iihf(mask, 0xFF00FF00);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_lg(Z_R0, Address(src, ind1));
-  z_lg(Z_R1, Address(src, ind1, 8));
+unsigned int MacroAssembler::string_compress(Register result, Register src, Register dst, Register cnt,
+                                             Register tmp,    bool precise) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
+
   if (precise) {
+    BLOCK_COMMENT("encode_iso_array {");
+  } else {
+    BLOCK_COMMENT("string_compress {");
+  }
+  int  block_start = offset();
+
+  Register       Rsrc  = src;
+  Register       Rdst  = dst;
+  Register       Rix   = tmp;
+  Register       Rcnt  = cnt;
+  Register       Rmask = result;  // holds incompatibility check mask until result value is stored.
+  Label          ScalarShortcut, AllDone;
+
+  z_iilf(Rmask, 0xFF00FF00);
+  z_iihf(Rmask, 0xFF00FF00);
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    //   Strings with 4 and 8 characters were fond to occur very frequently.
+    //   Therefore, we handle them right away with minimal overhead.
+    Label     skipShortcut, skip4Shortcut, skip8Shortcut;
+    Register  Rout = Z_R0;
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_lg(Z_R0, 0, Rsrc);                 // Treat exactly 4 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ngrk(Rix, Z_R0, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brne(skip8Shortcut);                 // There's more to do...
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);          // Treat exactly 8 characters specially.
+      if (VM_Version::has_DistinctOpnds()) {
+        Rout = Z_R0;
+        z_ogrk(Rix, Z_R0, Z_R1);
+        z_ngr(Rix, Rmask);
+      } else {
+        Rout = Rix;
+        z_lgr(Rix, Z_R0);
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+      }
+      z_brnz(skipShortcut);
+      z_stcmh(Rout, 5, 0, Rdst);
+      z_stcm(Rout,  5, 2, Rdst);
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+      z_lgfr(result, Rcnt);
+      z_bru(AllDone);
+
+    bind(skip8Shortcut);
+    clear_reg(Z_R0, true, false);          // #characters already processed (none). Precond for scalar loop.
+    z_brl(ScalarShortcut);                 // Just a few characters
+
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of 2*(vector register length in chars (8 HW = 128 bits)).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone, VectorBreak;
+
+    VectorRegister Vtmp1      = Z_V16;
+    VectorRegister Vtmp2      = Z_V17;
+    VectorRegister Vmask      = Z_V18;
+    VectorRegister Vzero      = Z_V19;
+    VectorRegister Vsrc_first = Z_V20;
+    VectorRegister Vsrc_last  = Z_V23;
+
+    assert((Vsrc_last->encoding() - Vsrc_first->encoding() + 1) == min_vcnt/8, "logic error");
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // # vector loop iterations
+    z_brz(VectorDone);                     // not enough data for vector loop
+
+    z_vzero(Vzero);                        // all zeroes
+    z_vgmh(Vmask, 0, 7);                   // generate 0xff00 mask for all 2-byte elements
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Vsrc_first, Vsrc_last, 0, Rsrc);
+      add2reg(Rsrc, min_vcnt*2);
+
+      //---<  check for incompatible character  >---
+      z_vo(Vtmp1, Z_V20, Z_V21);
+      z_vo(Vtmp2, Z_V22, Z_V23);
+      z_vo(Vtmp1, Vtmp1, Vtmp2);
+      z_vn(Vtmp1, Vtmp1, Vmask);
+      z_vceqhs(Vtmp1, Vtmp1, Vzero);       // high half of all chars must be zero for successful compress.
+      z_brne(VectorBreak);                 // break vector loop, incompatible character found.
+                                           // re-process data from current iteration in break handler.
+
+      //---<  pack & store characters  >---
+      z_vpkh(Vtmp1, Z_V20, Z_V21);         // pack (src1, src2) -> tmp1
+      z_vpkh(Vtmp2, Z_V22, Z_V23);         // pack (src3, src4) -> tmp2
+      z_vstm(Vtmp1, Vtmp2, 0, Rdst);       // store packed string
+      add2reg(Rdst, min_vcnt);
+
+      z_brct(Rix, VectorLoop);
+
+    z_bru(VectorDone);
+
+    bind(VectorBreak);
+      z_sll(Rix, log_min_vcnt);            // # chars processed so far in VectorLoop, excl. current iteration.
+      z_sr(Z_R0, Rix);                     // correct # chars processed in total.
+
+    bind(VectorDone);
+  }
+
+  {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled loop.
+                                           // Otherwise just do nothing in unrolled loop.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone, UnrolledBreak;
+
     if (VM_Version::has_DistinctOpnds()) {
-      z_ogrk(tmp2, Z_R0, Z_R1);
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
     } else {
-      z_lgr(tmp2, Z_R0);
-      z_ogr(tmp2, Z_R1);
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
     }
-    z_ngr(tmp2, mask);
-    z_brne(Lslow);         // Failed fast case, retry slowly.
-  }
-  z_stcmh(Z_R0, 5, 0, addr2);
-  z_stcm(Z_R0, 5, 2, addr2);
-  if (!precise) { z_ogr(Z_R0, Z_R1); }
-  z_stcmh(Z_R1, 5, 4, addr2);
-  z_stcm(Z_R1, 5, 6, addr2);
-  if (!precise) {
-    z_ngr(Z_R0, mask);
-    z_brne(Ldone);         // Failed (more than needed was written).
-  }
-  z_aghi(addr2, 8);
-  z_brxle(ind1, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind1, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llh(Z_R0, Address(src, ind1));
-  z_tmll(Z_R0, 0xFF00);
-  z_brnaz(Ldone);          // Failed slow case: Return number of written characters.
-  z_stc(Z_R0, Address(addr2));
-  z_aghi(addr2, 1);
-  z_brxle(ind1, even_reg, Lloop2);
-
-  bind(Ldone);             // result = ind1 = 2*cnt
-  z_srl(ind1, 1);
-
-  BLOCK_COMMENT("} string_compress");
-
+    z_sra(Rix, log_min_cnt);             // unrolled loop count
+    z_brz(UnrolledDone);
+
+    bind(UnrolledLoop);
+      z_lmg(Z_R0, Z_R1, 0, Rsrc);
+      if (precise) {
+        z_ogr(Z_R1, Z_R0);                 // check all 8 chars for incompatibility
+        z_ngr(Z_R1, Rmask);
+        z_brnz(UnrolledBreak);
+
+        z_lg(Z_R1, 8, Rsrc);               // reload destroyed register
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+      } else {
+        z_stcmh(Z_R0, 5, 0, Rdst);
+        z_stcm(Z_R0,  5, 2, Rdst);
+
+        z_ogr(Z_R0, Z_R1);
+        z_ngr(Z_R0, Rmask);
+        z_brnz(UnrolledBreak);
+      }
+      z_stcmh(Z_R1, 5, 4, Rdst);
+      z_stcm(Z_R1,  5, 6, Rdst);
+
+      add2reg(Rsrc, min_cnt*2);
+      add2reg(Rdst, min_cnt);
+      z_brct(Rix, UnrolledLoop);
+
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop.
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_tmll(Rcnt, min_cnt-1);
+    z_brnaz(ScalarShortcut);               // if all bits zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_lgfr(result, Rcnt);                  // all characters processed.
+    z_sgfr(Rdst, Rcnt);                    // restore ptr
+    z_sgfr(Rsrc, Rcnt);                    // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, Rcnt);
+    z_bru(AllDone);
+
+    bind(UnrolledBreak);
+    z_lgfr(Z_R0, Rcnt);                    // # chars processed in total after unrolled loop
+    z_nilf(Z_R0, ~(min_cnt-1));
+    z_sll(Rix, log_min_cnt);               // # chars processed so far in UnrolledLoop, excl. current iteration.
+    z_sr(Z_R0, Rix);                       // correct # chars processed in total.
+    if (!precise) {
+      z_lgfr(result, Z_R0);
+      z_aghi(result, min_cnt/2);           // min_cnt/2 characters have already been written
+                                           // but ptrs were not updated yet.
+      z_sgfr(Rdst, Z_R0);                  // restore ptr
+      z_sgfr(Rsrc, Z_R0);                  // restore ptr, double the element count for Rsrc restore
+      z_sgfr(Rsrc, Z_R0);
+      z_bru(AllDone);
+    }
+    bind(UnrolledDone);
+  }
+
+  {
+    Label     ScalarLoop, ScalarDone, ScalarBreak;
+
+    bind(ScalarShortcut);
+    z_ltgfr(result, Rcnt);
+    z_brz(AllDone);
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      //---<  Special treatment for very short strings (one or two characters)  >---
+      //   For these strings, we are sure that the above code was skipped.
+      //   Thus, no registers were modified, register restore is not required.
+      Label     ScalarDoit, Scalar2Char;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDoit);
+      z_llh(Z_R1,  0, Z_R0, Rsrc);
+      z_bre(Scalar2Char);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 1, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_lghi(result, 1);
+      z_bru(AllDone);
+
+      bind(Scalar2Char);
+      z_llh(Z_R0,  2, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_lghi(result, 0);                   // cnt == 2, first char invalid, no chars successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R1,  0, Z_R0, Rdst);
+      z_tmll(Z_R0, 0xff00);
+      z_lghi(result, 1);                   // cnt == 2, second char invalid, one char successfully processed
+      z_brnaz(AllDone);
+      z_stc(Z_R0,  1, Z_R0, Rdst);
+      z_lghi(result, 2);
+      z_bru(AllDone);
+
+      bind(ScalarDoit);
+    }
+#endif
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to compress in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_lgfr(result, Rcnt);                  // # processed characters (if all runs ok).
+    z_brz(ScalarDone);
+
+    bind(ScalarLoop);
+      z_llh(Z_R1, 0, Z_R0, Rsrc);
+      z_tmll(Z_R1, 0xff00);
+      z_brnaz(ScalarBreak);
+      z_stc(Z_R1, 0, Z_R0, Rdst);
+      add2reg(Rsrc, 2);
+      add2reg(Rdst, 1);
+      z_brct(Rix, ScalarLoop);
+
+    z_bru(ScalarDone);
+
+    bind(ScalarBreak);
+    z_sr(result, Rix);
+
+    bind(ScalarDone);
+    z_sgfr(Rdst, result);                  // restore ptr
+    z_sgfr(Rsrc, result);                  // restore ptr, double the element count for Rsrc restore
+    z_sgfr(Rsrc, result);
+  }
+  bind(AllDone);
+
+  if (precise) {
+    BLOCK_COMMENT("} encode_iso_array");
+  } else {
+    BLOCK_COMMENT("} string_compress");
+  }
   return offset() - block_start;
 }
 
@@ -4997,53 +5222,432 @@
   return offset() - block_start;
 }
 
-// Inflate byte[] to char[]. odd_reg contains cnt. Kills src.
-unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register odd_reg,
-                                            Register even_reg, Register tmp) {
+// Inflate byte[] to char[].
+//   Restores: src, dst
+//   Uses:     cnt
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   cnt is signed int. Do not rely on high word!
+//       counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, cnt, tmp);
+
+  BLOCK_COMMENT("string_inflate {");
   int block_start = offset();
 
-  BLOCK_COMMENT("string_inflate {");
-
-  Label Lloop1, Lloop2, Lslow, Ldone;
-  const Register addr1 = src, ind2 = tmp;
-
-  z_sll(odd_reg, 1);       // Number of bytes to write. (Must be a positive simm32.)
-  clear_reg(ind2);         // Index to write.
-  z_ahi(odd_reg, -16);     // Last possible index for fast loop.
-  z_brl(Lslow);
-
-  // ind2: index, even_reg: index increment, odd_reg: index limit
-  clear_reg(Z_R0);
-  clear_reg(Z_R1);
-  z_lhi(even_reg, 16);
-
-  bind(Lloop1); // 8 Characters per iteration.
-  z_icmh(Z_R0, 5, 0, addr1);
-  z_icmh(Z_R1, 5, 4, addr1);
-  z_icm(Z_R0, 5, 2, addr1);
-  z_icm(Z_R1, 5, 6, addr1);
-  z_aghi(addr1, 8);
-  z_stg(Z_R0, Address(dst, ind2));
-  z_stg(Z_R1, Address(dst, ind2, 8));
-  z_brxle(ind2, even_reg, Lloop1);
-
-  bind(Lslow);
-  // Compute index limit and skip if negative.
-  z_ahi(odd_reg, 16-2);    // Last possible index for slow loop.
-  z_lhi(even_reg, 2);
-  z_cr(ind2, odd_reg);
-  z_brh(Ldone);
-
-  bind(Lloop2); // 1 Character per iteration.
-  z_llc(Z_R0, Address(addr1));
-  z_sth(Z_R0, Address(dst, ind2));
-  z_aghi(addr1, 1);
-  z_brxle(ind2, even_reg, Lloop2);
-
-  bind(Ldone);
+  Register   Rcnt = cnt;   // # characters (src: bytes, dst: char (2-byte)), remaining after current loop.
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+
+#if 0  // Sacrifice shortcuts for code compactness
+  {
+    //---<  shortcuts for short strings (very frequent)   >---
+    Label   skipShortcut, skip4Shortcut;
+    z_ltr(Rcnt, Rcnt);                     // absolutely nothing to do for strings of len == 0.
+    z_brz(AllDone);
+    clear_reg(Z_R0);                       // make sure registers are properly initialized.
+    clear_reg(Z_R1);
+    z_chi(Rcnt, 4);
+    z_brne(skip4Shortcut);                 // 4 characters are very frequent
+      z_icm(Z_R0, 5,    0, Rsrc);          // Treat exactly 4 characters specially.
+      z_icm(Z_R1, 5,    2, Rsrc);
+      z_stm(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skip4Shortcut);
+
+    z_chi(Rcnt, 8);
+    z_brh(skipShortcut);                   // There's a lot to do...
+    z_lgfr(Z_R0, Rcnt);                    // remaining #characters (<= 8). Precond for scalar loop.
+                                           // This does not destroy the "register cleared" state of Z_R0.
+    z_brl(ScalarShortcut);                 // Just a few characters
+      z_icmh(Z_R0, 5, 0, Rsrc);            // Treat exactly 8 characters specially.
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+      z_bru(AllDone);
+    bind(skipShortcut);
+  }
+#endif
+  clear_reg(Z_R0);                         // make sure register is properly initialized.
+
+  if (VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    Label      VectorLoop, VectorDone;
+
+    assert(VM_Version::has_DistinctOpnds(), "Assumption when has_VectorFacility()");
+    z_srak(Rix, Rcnt, log_min_vcnt);       // calculate # vector loop iterations
+    z_brz(VectorDone);                     // skip if none
+
+    z_sllg(Z_R0, Rix, log_min_vcnt);       // remember #chars that will be processed by vector loop
+
+    bind(VectorLoop);
+      z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+      add2reg(Rsrc, min_vcnt);
+
+      z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+      add2reg(Rdst, min_vcnt*2);
+
+      z_brct(Rix, VectorLoop);
+
+    bind(VectorDone);
+  }
+
+  const int  min_cnt     =  8;             // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+  {
+    const int  log_min_cnt = exact_log2(min_cnt);
+    Label      UnrolledLoop, UnrolledDone;
+
+
+    if (VM_Version::has_DistinctOpnds()) {
+      z_srk(Rix, Rcnt, Z_R0);              // remaining # chars to process in unrolled loop
+    } else {
+      z_lr(Rix, Rcnt);
+      z_sr(Rix, Z_R0);
+    }
+    z_sra(Rix, log_min_cnt);               // unrolled loop count
+    z_brz(UnrolledDone);
+
+    clear_reg(Z_R0);
+    clear_reg(Z_R1);
+
+    bind(UnrolledLoop);
+      z_icmh(Z_R0, 5, 0, Rsrc);
+      z_icmh(Z_R1, 5, 4, Rsrc);
+      z_icm(Z_R0,  5, 2, Rsrc);
+      z_icm(Z_R1,  5, 6, Rsrc);
+      add2reg(Rsrc, min_cnt);
+
+      z_stmg(Z_R0, Z_R1, 0, Rdst);
+
+      add2reg(Rdst, min_cnt*2);
+      z_brct(Rix, UnrolledLoop);
+
+    bind(UnrolledDone);
+    z_lgfr(Z_R0, Rcnt);                    // # chars left over after unrolled loop.
+    z_nilf(Z_R0, min_cnt-1);
+    z_brnz(ScalarShortcut);                // if zero, there is nothing left to do for scalar loop.
+                                           // Rix == 0 in all cases.
+    z_sgfr(Z_R0, Rcnt);                    // negative # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+    z_bru(AllDone);
+  }
+
+  {
+    bind(ScalarShortcut);
+    // Z_R0 must contain remaining # characters as 64-bit signed int here.
+    //      register contents is preserved over scalar processing (for register fixup).
+
+#if 0  // Sacrifice shortcuts for code compactness
+    {
+      Label      ScalarDefault;
+      z_chi(Rcnt, 2);
+      z_brh(ScalarDefault);
+      z_llc(Z_R0,  0, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  0, Z_R0, Rdst);     // 4 bytes
+      z_brl(AllDone);
+      z_llc(Z_R0,  1, Z_R0, Rsrc);     // 6 bytes
+      z_sth(Z_R0,  2, Z_R0, Rdst);     // 4 bytes
+      z_bru(AllDone);
+      bind(ScalarDefault);
+    }
+#endif
+
+    Label   CodeTable;
+    // Some comments on Rix calculation:
+    //  - Rcnt is small, therefore no bits shifted out of low word (sll(g) instructions).
+    //  - high word of both Rix and Rcnt may contain garbage
+    //  - the final lngfr takes care of that garbage, extending the sign to high word
+    z_sllg(Rix, Z_R0, 2);                // calculate 10*Rix = (4*Rix + Rix)*2
+    z_ar(Rix, Z_R0);
+    z_larl(Z_R1, CodeTable);
+    z_sll(Rix, 1);
+    z_lngfr(Rix, Rix);      // ix range: [0..7], after inversion & mult: [-(7*12)..(0*12)].
+    z_bc(Assembler::bcondAlways, 0, Rix, Z_R1);
+
+    z_llc(Z_R1,  6, Z_R0, Rsrc);  // 6 bytes
+    z_sth(Z_R1, 12, Z_R0, Rdst);  // 4 bytes
+
+    z_llc(Z_R1,  5, Z_R0, Rsrc);
+    z_sth(Z_R1, 10, Z_R0, Rdst);
+
+    z_llc(Z_R1,  4, Z_R0, Rsrc);
+    z_sth(Z_R1,  8, Z_R0, Rdst);
+
+    z_llc(Z_R1,  3, Z_R0, Rsrc);
+    z_sth(Z_R1,  6, Z_R0, Rdst);
+
+    z_llc(Z_R1,  2, Z_R0, Rsrc);
+    z_sth(Z_R1,  4, Z_R0, Rdst);
+
+    z_llc(Z_R1,  1, Z_R0, Rsrc);
+    z_sth(Z_R1,  2, Z_R0, Rdst);
+
+    z_llc(Z_R1,  0, Z_R0, Rsrc);
+    z_sth(Z_R1,  0, Z_R0, Rdst);
+    bind(CodeTable);
+
+    z_chi(Rcnt, 8);                        // no fixup for small strings. Rdst, Rsrc were not modified.
+    z_brl(AllDone);
+
+    z_sgfr(Z_R0, Rcnt);                    // # characters the ptrs have been advanced previously.
+    z_agr(Rdst, Z_R0);                     // restore ptr, double the element count for Rdst restore.
+    z_agr(Rdst, Z_R0);
+    z_agr(Rsrc, Z_R0);                     // restore ptr.
+  }
+  bind(AllDone);
 
   BLOCK_COMMENT("} string_inflate");
-
+  return offset() - block_start;
+}
+
+// Inflate byte[] to char[], length known at compile time.
+//   Restores: src, dst
+//   Kills:    tmp, Z_R0, Z_R1.
+// Note:
+//   len is signed int. Counts # characters, not bytes.
+unsigned int MacroAssembler::string_inflate_const(Register src, Register dst, Register tmp, int len) {
+  assert_different_registers(Z_R0, Z_R1, src, dst, tmp);
+
+  BLOCK_COMMENT("string_inflate_const {");
+  int block_start = offset();
+
+  Register   Rix  = tmp;   // loop index
+  Register   Rsrc = src;   // addr(src array)
+  Register   Rdst = dst;   // addr(dst array)
+  Label      ScalarShortcut, AllDone;
+  int        nprocessed = 0;
+  int        src_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  int        dst_off    = 0;  // compensate for saved (optimized away) ptr advancement.
+  bool       restore_inputs = false;
+  bool       workreg_clear  = false;
+
+  if ((len >= 32) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 32;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    Label      VectorLoop;
+
+    if (iterations == 1) {
+      z_vlm(Z_V20, Z_V21, 0+src_off, Rsrc);  // get next 32 characters (single-byte)
+      z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+      z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+      z_vuplhb(Z_V24, Z_V21);                // V4 <- (expand) V1(high)
+      z_vupllb(Z_V25, Z_V21);                // V5 <- (expand) V1(low)
+      z_vstm(Z_V22, Z_V25, 0+dst_off, Rdst); // store next 32 bytes
+
+      src_off += min_vcnt;
+      dst_off += min_vcnt*2;
+    } else {
+      restore_inputs = true;
+
+      z_lgfi(Rix, len>>log_min_vcnt);
+      bind(VectorLoop);
+        z_vlm(Z_V20, Z_V21, 0, Rsrc);        // get next 32 characters (single-byte)
+        add2reg(Rsrc, min_vcnt);
+
+        z_vuplhb(Z_V22, Z_V20);              // V2 <- (expand) V0(high)
+        z_vupllb(Z_V23, Z_V20);              // V3 <- (expand) V0(low)
+        z_vuplhb(Z_V24, Z_V21);              // V4 <- (expand) V1(high)
+        z_vupllb(Z_V25, Z_V21);              // V5 <- (expand) V1(low)
+        z_vstm(Z_V22, Z_V25, 0, Rdst);       // store next 32 bytes
+        add2reg(Rdst, min_vcnt*2);
+
+        z_brct(Rix, VectorLoop);
+    }
+  }
+
+  if (((len-nprocessed) >= 16) && VM_Version::has_VectorFacility()) {
+    const int  min_vcnt     = 16;          // Minimum #characters required to use vector instructions.
+                                           // Otherwise just do nothing in vector mode.
+                                           // Must be multiple of vector register length (16 bytes = 128 bits).
+    const int  log_min_vcnt = exact_log2(min_vcnt);
+    const int  iterations   = (len - nprocessed) >> log_min_vcnt;
+    nprocessed             += iterations << log_min_vcnt;
+    assert(iterations == 1, "must be!");
+
+    z_vl(Z_V20, 0+src_off, Z_R0, Rsrc);    // get next 16 characters (single-byte)
+    z_vuplhb(Z_V22, Z_V20);                // V2 <- (expand) V0(high)
+    z_vupllb(Z_V23, Z_V20);                // V3 <- (expand) V0(low)
+    z_vstm(Z_V22, Z_V23, 0+dst_off, Rdst); // store next 32 bytes
+
+    src_off += min_vcnt;
+    dst_off += min_vcnt*2;
+  }
+
+  if ((len-nprocessed) > 8) {
+    const int  min_cnt     =  8;           // Minimum #characters required to use unrolled scalar loop.
+                                           // Otherwise just do nothing in unrolled scalar mode.
+                                           // Must be multiple of 8.
+    const int  log_min_cnt = exact_log2(min_cnt);
+    const int  iterations  = (len - nprocessed) >> log_min_cnt;
+    nprocessed     += iterations << log_min_cnt;
+
+    //---<  avoid loop overhead/ptr increment for small # iterations  >---
+    if (iterations <= 2) {
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations == 2) {
+      z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+      z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+      z_icm(Z_R0,  5, 2+src_off, Rsrc);
+      z_icm(Z_R1,  5, 6+src_off, Rsrc);
+      z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+
+      src_off += min_cnt;
+      dst_off += min_cnt*2;
+    }
+
+    if (iterations > 2) {
+      Label      UnrolledLoop;
+      restore_inputs  = true;
+
+      clear_reg(Z_R0);
+      clear_reg(Z_R1);
+      workreg_clear = true;
+
+      z_lgfi(Rix, iterations);
+      bind(UnrolledLoop);
+        z_icmh(Z_R0, 5, 0, Rsrc);
+        z_icmh(Z_R1, 5, 4, Rsrc);
+        z_icm(Z_R0,  5, 2, Rsrc);
+        z_icm(Z_R1,  5, 6, Rsrc);
+        add2reg(Rsrc, min_cnt);
+
+        z_stmg(Z_R0, Z_R1, 0, Rdst);
+        add2reg(Rdst, min_cnt*2);
+
+        z_brct(Rix, UnrolledLoop);
+    }
+  }
+
+  if ((len-nprocessed) > 0) {
+    switch (len-nprocessed) {
+      case 8:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icmh(Z_R0, 5, 0+src_off, Rsrc);
+        z_icmh(Z_R1, 5, 4+src_off, Rsrc);
+        z_icm(Z_R0,  5, 2+src_off, Rsrc);
+        z_icm(Z_R1,  5, 6+src_off, Rsrc);
+        z_stmg(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 7:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0,  5, 0+src_off, Rsrc);
+        z_icm(Z_R1,  5, 2+src_off, Rsrc);
+        z_icm(Rix,   5, 4+src_off, Rsrc);
+        z_stm(Z_R0,  Z_R1, 0+dst_off, Rdst);
+        z_llc(Z_R0,  6+src_off, Z_R0, Rsrc);
+        z_st(Rix,    8+dst_off, Z_R0, Rdst);
+        z_sth(Z_R0, 12+dst_off, Z_R0, Rdst);
+        break;
+      case 6:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        clear_reg(Rix);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_icm(Rix,  5, 4+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_st(Rix,   8+dst_off, Z_R0, Rdst);
+        break;
+      case 5:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_llc(Rix,  4+src_off, Z_R0, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        z_sth(Rix,  8+dst_off, Z_R0, Rdst);
+        break;
+      case 4:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+          clear_reg(Z_R1);
+        }
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_icm(Z_R1, 5, 2+src_off, Rsrc);
+        z_stm(Z_R0, Z_R1, 0+dst_off, Rdst);
+        break;
+      case 3:
+        if (!workreg_clear) {
+          clear_reg(Z_R0);
+        }
+        z_llc(Z_R1, 2+src_off, Z_R0, Rsrc);
+        z_icm(Z_R0, 5, 0+src_off, Rsrc);
+        z_sth(Z_R1, 4+dst_off, Z_R0, Rdst);
+        z_st(Z_R0,  0+dst_off, Rdst);
+        break;
+      case 2:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_llc(Z_R1, 1+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        z_sth(Z_R1, 2+dst_off, Z_R0, Rdst);
+        break;
+      case 1:
+        z_llc(Z_R0, 0+src_off, Z_R0, Rsrc);
+        z_sth(Z_R0, 0+dst_off, Z_R0, Rdst);
+        break;
+      default:
+        guarantee(false, "Impossible");
+        break;
+    }
+    src_off   +=  len-nprocessed;
+    dst_off   += (len-nprocessed)*2;
+    nprocessed = len;
+  }
+
+  //---< restore modified input registers  >---
+  if ((nprocessed > 0) && restore_inputs) {
+    z_agfi(Rsrc, -(nprocessed-src_off));
+    if (nprocessed < 1000000000) { // avoid int overflow
+      z_agfi(Rdst, -(nprocessed*2-dst_off));
+    } else {
+      z_agfi(Rdst, -(nprocessed-dst_off));
+      z_agfi(Rdst, -nprocessed);
+    }
+  }
+
+  BLOCK_COMMENT("} string_inflate_const");
   return offset() - block_start;
 }
 
--- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -198,6 +198,9 @@
   // Test a bit in a register. Result is reflected in CC.
   void testbit(Register r, unsigned int bitPos);
 
+  void prefetch_read(Address a);
+  void prefetch_update(Address a);
+
   // Clear a register, i.e. load const zero into reg. Return len (in bytes) of
   // generated instruction(s).
   //   whole_reg: Clear 64 bits if true, 32 bits otherwise.
@@ -836,7 +839,7 @@
   void load_mirror(Register mirror, Register method);
 
   //--------------------------
-  //---  perations on arrays.
+  //---  Operations on arrays.
   //--------------------------
   unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len);
   unsigned int Clear_Array_Const(long cnt, Register base);
@@ -849,20 +852,34 @@
   // Special String Intrinsics Implementation.
   //-------------------------------------------
   // Intrinsics for CompactStrings
-  // Compress char[] to byte[]. odd_reg contains cnt. tmp3 is only needed for precise behavior in failure case. Kills dst.
-  unsigned int string_compress(Register result, Register src, Register dst, Register odd_reg,
-                               Register even_reg, Register tmp, Register tmp2 = noreg);
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  //   Early clobber: result.
+  //   Boolean precise controls accuracy of result value.
+  unsigned int string_compress(Register result, Register src, Register dst, Register cnt,
+                               Register tmp,    bool precise);
+
+  // Inflate byte[] to char[].
+  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[].
+  //   Restores: src, dst
+  //   Uses:     cnt
+  //   Kills:    tmp, Z_R0, Z_R1.
+  unsigned int string_inflate(Register src, Register dst, Register cnt, Register tmp);
+
+  // Inflate byte[] to char[], length known at compile time.
+  //   Restores: src, dst
+  //   Kills:    tmp, Z_R0, Z_R1.
+  // Note:
+  //   len is signed int. Counts # characters, not bytes.
+  unsigned int string_inflate_const(Register src, Register dst, Register tmp, int len);
 
   // Kills src.
   unsigned int has_negatives(Register result, Register src, Register cnt,
                              Register odd_reg, Register even_reg, Register tmp);
 
-  // Inflate byte[] to char[].
-  unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp);
-  // Odd_reg contains cnt. Kills src.
-  unsigned int string_inflate(Register src, Register dst, Register odd_reg,
-                              Register even_reg, Register tmp);
-
   unsigned int string_compare(Register str1, Register str2, Register cnt1, Register cnt2,
                               Register odd_reg, Register even_reg, Register result, int ae);
 
--- a/src/hotspot/cpu/s390/s390.ad	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/s390/s390.ad	Mon Nov 27 17:04:45 2017 +0000
@@ -10267,14 +10267,14 @@
 %}
 
 // char[] to byte[] compression
-instruct string_compress(iRegP src, rarg5RegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (StrCompressedCopy src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL dst, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Compress $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register);
+                       $tmp$$Register, false);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10293,13 +10293,25 @@
 //%}
 
 // byte[] to char[] inflation
-instruct string_inflate(Universe dummy, rarg5RegP src, iRegP dst, roddRegI len, revenRegI evenReg, iRegI tmp, flagsReg cr) %{
+instruct string_inflate(Universe dummy, iRegP src, iRegP dst, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set dummy (StrInflatedCopy src (Binary dst len)));
-  effect(USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "String Inflate $src->$dst($len)" %}
   ins_encode %{
-    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $evenReg$$Register, $tmp$$Register);
+    __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register);
+  %}
+  ins_pipe(pipe_class_dummy);
+%}
+
+// byte[] to char[] inflation
+instruct string_inflate_const(Universe dummy, iRegP src, iRegP dst, iRegI tmp, immI len, flagsReg cr) %{
+  match(Set dummy (StrInflatedCopy src (Binary dst len)));
+  effect(TEMP tmp, KILL cr); // R0, R1 are killed, too.
+  ins_cost(300);
+  format %{ "String Inflate (constLen) $src->$dst($len)" %}
+  ins_encode %{
+    __ string_inflate_const($src$$Register, $dst$$Register, $tmp$$Register, $len$$constant);
   %}
   ins_pipe(pipe_class_dummy);
 %}
@@ -10318,14 +10330,14 @@
 %}
 
 // encode char[] to byte[] in ISO_8859_1
-instruct encode_iso_array(rarg5RegP src, iRegP dst, iRegI result, roddRegI len, revenRegI evenReg, iRegI tmp, iRegI tmp2, flagsReg cr) %{
+instruct encode_iso_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{
   match(Set result (EncodeISOArray src (Binary dst len)));
-  effect(TEMP_DEF result, USE_KILL src, USE_KILL len, TEMP evenReg, TEMP tmp, TEMP tmp2, KILL cr); // R0, R1 are killed, too.
+  effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too.
   ins_cost(300);
   format %{ "Encode array $src->$dst($len) -> $result" %}
   ins_encode %{
     __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register,
-                       $evenReg$$Register, $tmp$$Register, $tmp2$$Register);
+                       $tmp$$Register, true);
   %}
   ins_pipe(pipe_class_dummy);
 %}
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -398,8 +398,13 @@
   if (o == NULL) {
     __ set(NULL_WORD, reg);
   } else {
+#ifdef ASSERT
+    {
+      ThreadInVMfromNative tiv(JavaThread::current());
+      assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
+    }
+#endif
     int oop_index = __ oop_recorder()->find_index(o);
-    assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(o)), "should be real oop");
     RelocationHolder rspec = oop_Relocation::spec(oop_index);
     __ set(NULL_WORD, reg, rspec); // Will be set when the nmethod is created
   }
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -898,7 +898,9 @@
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
           assert_different_registers(addr, count, tmp);
 
-          Label L_loop;
+          Label L_loop, L_done;
+
+          __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
 
           __ sll_ptr(count, LogBytesPerHeapOop, count);
           __ sub(count, BytesPerHeapOop, count);
@@ -914,6 +916,7 @@
           __ subcc(count, 1, count);
           __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
           __ delayed()->add(addr, 1, addr);
+        __ BIND(L_done);
         }
         break;
       case BarrierSet::ModRef:
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1264,9 +1264,12 @@
           CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
           assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
-          Label L_loop;
+          Label L_loop, L_done;
           const Register end = count;
 
+          __ testl(count, count);
+          __ jcc(Assembler::zero, L_done); // zero count - nothing to do
+
           __ leaq(end, Address(start, count, TIMES_OOP, 0));  // end == start+count*oop_size
           __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
           __ shrptr(start, CardTableModRefBS::card_shift);
@@ -1280,6 +1283,7 @@
           __ movb(Address(start, count, Address::times_1), 0);
           __ decrement(count);
           __ jcc(Assembler::greaterEqual, L_loop);
+        __ BIND(L_done);
         }
         break;
       default:
--- a/src/hotspot/os/linux/os_linux.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/os/linux/os_linux.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -59,6 +59,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timer.hpp"
 #include "semaphore_posix.hpp"
 #include "services/attachListener.hpp"
@@ -1646,7 +1647,10 @@
         //
         // Dynamic loader will make all stacks executable after
         // this function returns, and will not do that again.
-        assert(Threads::first() == NULL, "no Java threads should exist yet.");
+#ifdef ASSERT
+        ThreadsListHandle tlh;
+        assert(tlh.length() == 0, "no Java threads should exist yet.");
+#endif
       } else {
         warning("You have loaded library %s which might have disabled stack guard. "
                 "The VM will try to fix the stack guard now.\n"
@@ -1874,16 +1878,13 @@
   // may have been queued at the same time.
 
   if (!_stack_is_executable) {
-    JavaThread *jt = Threads::first();
-
-    while (jt) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
       if (!jt->stack_guard_zone_unused() &&     // Stack not yet fully initialized
           jt->stack_guards_enabled()) {         // No pending stack overflow exceptions
         if (!os::guard_memory((char *)jt->stack_end(), jt->stack_guard_zone_size())) {
           warning("Attempt to reguard stack yellow zone failed.");
         }
       }
-      jt = jt->next();
     }
   }
 
@@ -4947,25 +4948,20 @@
         UseNUMA = false;
       }
     }
-    // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
-    // we can make the adaptive lgrp chunk resizing work. If the user specified
-    // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
-    // disable adaptive resizing.
-    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
-      if (FLAG_IS_DEFAULT(UseNUMA)) {
-        UseNUMA = false;
-      } else {
-        if (FLAG_IS_DEFAULT(UseLargePages) &&
-            FLAG_IS_DEFAULT(UseSHM) &&
-            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
-          UseLargePages = false;
-        } else if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
-          warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
-          UseAdaptiveSizePolicy = false;
-          UseAdaptiveNUMAChunkSizing = false;
-        }
+
+    if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
+      // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
+      // we can make the adaptive lgrp chunk resizing work. If the user specified both
+      // UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn
+      // and disable adaptive resizing.
+      if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
+        warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, "
+                "disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
+        UseAdaptiveSizePolicy = false;
+        UseAdaptiveNUMAChunkSizing = false;
       }
     }
+
     if (!UseNUMA && ForceNUMA) {
       UseNUMA = true;
     }
--- a/src/hotspot/os/posix/os_posix.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/os/posix/os_posix.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -478,8 +478,7 @@
 // interrupt support
 
 void os::interrupt(Thread* thread) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
@@ -499,12 +498,10 @@
 
   ParkEvent * ev = thread->_ParkEvent ;
   if (ev != NULL) ev->unpark() ;
-
 }
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
 
--- a/src/hotspot/os/windows/os_windows.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/os/windows/os_windows.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -3490,9 +3490,7 @@
 void os::hint_no_preempt() {}
 
 void os::interrupt(Thread* thread) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread ||
-         Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   osthread->set_interrupted(true);
@@ -3513,8 +3511,7 @@
 
 
 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
-         "possibility of dangling Thread pointer");
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   OSThread* osthread = thread->osthread();
   // There is no synchronization between the setting of the interrupt
--- a/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/os_cpu/linux_zero/atomic_linux_zero.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -30,74 +30,6 @@
 
 // Implementation of class atomic
 
-#ifdef M68K
-
-/*
- * __m68k_cmpxchg
- *
- * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
- * Returns newval on success and oldval if no exchange happened.
- * This implementation is processor specific and works on
- * 68020 68030 68040 and 68060.
- *
- * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
- * instruction.
- * Using a kernelhelper would be better for arch complete implementation.
- *
- */
-
-static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
-  int ret;
-  __asm __volatile ("cas%.l %0,%2,%1"
-                   : "=d" (ret), "+m" (*(ptr))
-                   : "d" (newval), "0" (oldval));
-  return ret;
-}
-
-/* Perform an atomic compare and swap: if the current value of `*PTR'
-   is OLDVAL, then write NEWVAL into `*PTR'.  Return the contents of
-   `*PTR' before the operation.*/
-static inline int m68k_compare_and_swap(int newval,
-                                        volatile int *ptr,
-                                        int oldval) {
-  for (;;) {
-      int prev = *ptr;
-      if (prev != oldval)
-        return prev;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == newval)
-        // Success.
-        return prev;
-
-      // We failed even though prev == oldval.  Try again.
-    }
-}
-
-/* Atomically add an int to memory.  */
-static inline int m68k_add_and_fetch(int add_value, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
-        return prev + add_value;
-    }
-}
-
-/* Atomically write VALUE into `*PTR' and returns the previous
-   contents of `*PTR'.  */
-static inline int m68k_lock_test_and_set(int newval, volatile int *ptr) {
-  for (;;) {
-      // Loop until success.
-      int prev = *ptr;
-
-      if (__m68k_cmpxchg (prev, newval, ptr) == prev)
-        return prev;
-    }
-}
-#endif // M68K
-
 #ifdef ARM
 
 /*
@@ -176,11 +108,7 @@
 #ifdef ARM
   return add_using_helper<int>(arm_add_and_fetch, add_value, dest);
 #else
-#ifdef M68K
-  return add_using_helper<int>(m68k_add_and_fetch, add_value, dest);
-#else
   return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
 #endif // ARM
 }
 
@@ -201,9 +129,6 @@
 #ifdef ARM
   return xchg_using_helper<int>(arm_lock_test_and_set, exchange_value, dest);
 #else
-#ifdef M68K
-  return xchg_using_helper<int>(m68k_lock_test_and_set, exchange_value, dest);
-#else
   // __sync_lock_test_and_set is a bizarrely named atomic exchange
   // operation.  Note that some platforms only support this with the
   // limitation that the only valid value to store is the immediate
@@ -215,7 +140,6 @@
   // barrier.
   __sync_synchronize();
   return result;
-#endif // M68K
 #endif // ARM
 }
 
@@ -243,11 +167,7 @@
 #ifdef ARM
   return cmpxchg_using_helper<int>(arm_compare_and_swap, exchange_value, dest, compare_value);
 #else
-#ifdef M68K
-  return cmpxchg_using_helper<int>(m68k_compare_and_swap, exchange_value, dest, compare_value);
-#else
   return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
-#endif // M68K
 #endif // ARM
 }
 
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -3441,6 +3441,7 @@
   if ( callee->is_native())            return "native method";
   if ( callee->is_abstract())          return "abstract method";
   if (!callee->can_be_compiled())      return "not compilable (disabled)";
+  if (!callee->can_be_parsed())        return "cannot be parsed";
   return NULL;
 }
 
--- a/src/hotspot/share/ci/ciMethod.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/ci/ciMethod.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -87,6 +87,7 @@
   _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
   _is_c1_compilable   = !h_m()->is_not_c1_compilable();
   _is_c2_compilable   = !h_m()->is_not_c2_compilable();
+  _can_be_parsed      = true;
   _has_reserved_stack_access = h_m()->has_reserved_stack_access();
   // Lazy fields, filled in on demand.  Require allocation.
   _code               = NULL;
@@ -99,12 +100,13 @@
 #endif // COMPILER2
 
   ciEnv *env = CURRENT_ENV;
-  if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) {
+  if (env->jvmti_can_hotswap_or_post_breakpoint()) {
     // 6328518 check hotswap conditions under the right lock.
     MutexLocker locker(Compile_lock);
     if (Dependencies::check_evol_method(h_m()) != NULL) {
       _is_c1_compilable = false;
       _is_c2_compilable = false;
+      _can_be_parsed = false;
     }
   } else {
     CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
--- a/src/hotspot/share/ci/ciMethod.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/ci/ciMethod.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -87,6 +87,7 @@
   bool _balanced_monitors;
   bool _is_c1_compilable;
   bool _is_c2_compilable;
+  bool _can_be_parsed;
   bool _can_be_statically_bound;
   bool _has_reserved_stack_access;
 
@@ -291,6 +292,7 @@
   bool has_option(const char *option);
   bool has_option_value(const char* option, double& value);
   bool can_be_compiled();
+  bool can_be_parsed() const { return _can_be_parsed; }
   bool can_be_osr_compiled(int entry_bci);
   void set_not_compilable(const char* reason = NULL);
   bool has_compiled_code();
--- a/src/hotspot/share/classfile/classLoader.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/classfile/classLoader.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -26,6 +26,7 @@
 #define SHARE_VM_CLASSFILE_CLASSLOADER_HPP
 
 #include "jimage.hpp"
+#include "runtime/handles.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/perfData.hpp"
 #include "utilities/exceptions.hpp"
@@ -42,6 +43,7 @@
 class JImageFile;
 class ClassFileStream;
 class PackageEntry;
+template <typename T> class GrowableArray;
 
 class ClassPathEntry : public CHeapObj<mtClass> {
 private:
--- a/src/hotspot/share/code/codeCache.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/code/codeCache.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -259,12 +259,12 @@
   }
 
   // We do not need the profiled CodeHeap, use all space for the non-profiled CodeHeap
-  if(!heap_available(CodeBlobType::MethodProfiled)) {
+  if (!heap_available(CodeBlobType::MethodProfiled)) {
     non_profiled_size += profiled_size;
     profiled_size = 0;
   }
   // We do not need the non-profiled CodeHeap, use all space for the non-nmethod CodeHeap
-  if(!heap_available(CodeBlobType::MethodNonProfiled)) {
+  if (!heap_available(CodeBlobType::MethodNonProfiled)) {
     non_nmethod_size += non_profiled_size;
     non_profiled_size = 0;
   }
@@ -282,10 +282,11 @@
   FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, profiled_size);
   FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, non_profiled_size);
 
-  // Align CodeHeaps
-  size_t alignment = heap_alignment();
+  // If large page support is enabled, align code heaps according to large
+  // page size to make sure that code cache is covered by large pages.
+  const size_t alignment = MAX2(page_size(false), (size_t) os::vm_allocation_granularity());
   non_nmethod_size = align_up(non_nmethod_size, alignment);
-  profiled_size   = align_down(profiled_size, alignment);
+  profiled_size    = align_down(profiled_size, alignment);
 
   // Reserve one continuous chunk of memory for CodeHeaps and split it into
   // parts for the individual heaps. The memory layout looks like this:
@@ -308,37 +309,29 @@
   add_heap(non_profiled_space, "CodeHeap 'non-profiled nmethods'", CodeBlobType::MethodNonProfiled);
 }
 
-size_t CodeCache::heap_alignment() {
-  // If large page support is enabled, align code heaps according to large
-  // page size to make sure that code cache is covered by large pages.
-  const size_t page_size = os::can_execute_large_page_memory() ?
-             os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8) :
-             os::vm_page_size();
-  return MAX2(page_size, (size_t) os::vm_allocation_granularity());
+size_t CodeCache::page_size(bool aligned) {
+  if (os::can_execute_large_page_memory()) {
+    return aligned ? os::page_size_for_region_aligned(ReservedCodeCacheSize, 8) :
+                     os::page_size_for_region_unaligned(ReservedCodeCacheSize, 8);
+  } else {
+    return os::vm_page_size();
+  }
 }
 
 ReservedCodeSpace CodeCache::reserve_heap_memory(size_t size) {
-  // Determine alignment
-  const size_t page_size = os::can_execute_large_page_memory() ?
-          MIN2(os::page_size_for_region_aligned(InitialCodeCacheSize, 8),
-               os::page_size_for_region_aligned(size, 8)) :
-          os::vm_page_size();
-  const size_t granularity = os::vm_allocation_granularity();
-  const size_t r_align = MAX2(page_size, granularity);
-  const size_t r_size = align_up(size, r_align);
-  const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 :
-    MAX2(page_size, granularity);
-
-  ReservedCodeSpace rs(r_size, rs_align, rs_align > 0);
-
+  // Align and reserve space for code cache
+  const size_t rs_ps = page_size();
+  const size_t rs_align = MAX2(rs_ps, (size_t) os::vm_allocation_granularity());
+  const size_t rs_size = align_up(size, rs_align);
+  ReservedCodeSpace rs(rs_size, rs_align, rs_ps > (size_t) os::vm_page_size());
   if (!rs.is_reserved()) {
-    vm_exit_during_initialization("Could not reserve enough space for code cache");
+    vm_exit_during_initialization(err_msg("Could not reserve enough space for code cache (" SIZE_FORMAT "K)",
+                                          rs_size/K));
   }
 
   // Initialize bounds
   _low_bound = (address)rs.base();
   _high_bound = _low_bound + rs.size();
-
   return rs;
 }
 
@@ -415,7 +408,8 @@
   size_t size_initial = MIN2(InitialCodeCacheSize, rs.size());
   size_initial = align_up(size_initial, os::vm_page_size());
   if (!heap->reserve(rs, size_initial, CodeCacheSegmentSize)) {
-    vm_exit_during_initialization("Could not reserve enough space for code cache");
+    vm_exit_during_initialization(err_msg("Could not reserve enough space in %s (" SIZE_FORMAT "K)",
+                                          heap->name(), size_initial/K));
   }
 
   // Register the CodeHeap
--- a/src/hotspot/share/code/codeCache.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/code/codeCache.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -107,7 +107,7 @@
   static CodeHeap* get_code_heap(int code_blob_type);         // Returns the CodeHeap for the given CodeBlobType
   // Returns the name of the VM option to set the size of the corresponding CodeHeap
   static const char* get_code_heap_flag_name(int code_blob_type);
-  static size_t heap_alignment();                             // Returns the alignment of the CodeHeaps in bytes
+  static size_t page_size(bool aligned = true);               // Returns the page size used by the CodeCache
   static ReservedCodeSpace reserve_heap_memory(size_t size);  // Reserves one continuous chunk of memory for the CodeHeaps
 
   // Iteration
--- a/src/hotspot/share/code/debugInfo.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/code/debugInfo.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -28,6 +28,8 @@
 #include "code/nmethod.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/thread.hpp"
 
 // Constructors
 
@@ -209,14 +211,24 @@
 // ConstantOopWriteValue
 
 void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
-  assert(JNIHandles::resolve(value()) == NULL ||
-         Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
-         "Should be in heap");
+#ifdef ASSERT
+  {
+    // cannot use ThreadInVMfromNative here since in case of JVMCI compiler,
+    // thread is already in VM state.
+    ThreadInVMfromUnknown tiv;
+    assert(JNIHandles::resolve(value()) == NULL ||
+           Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
+           "Should be in heap");
+ }
+#endif
   stream->write_int(CONSTANT_OOP_CODE);
   stream->write_handle(value());
 }
 
 void ConstantOopWriteValue::print_on(outputStream* st) const {
+  // using ThreadInVMfromUnknown here since in case of JVMCI compiler,
+  // thread is already in VM state.
+  ThreadInVMfromUnknown tiv;
   JNIHandles::resolve(value())->print_value_on(st);
 }
 
--- a/src/hotspot/share/code/stubs.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/code/stubs.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -78,7 +78,6 @@
   _queue_begin     = 0;
   _queue_end       = 0;
   _number_of_stubs = 0;
-  register_queue(this);
 }
 
 
@@ -205,36 +204,6 @@
 }
 
 
-enum { StubQueueLimit = 10 };  // there are only a few in the world
-static StubQueue* registered_stub_queues[StubQueueLimit];
-
-void StubQueue::register_queue(StubQueue* sq) {
-  for (int i = 0; i < StubQueueLimit; i++) {
-    if (registered_stub_queues[i] == NULL) {
-      registered_stub_queues[i] = sq;
-      return;
-    }
-  }
-  ShouldNotReachHere();
-}
-
-
-void StubQueue::queues_do(void f(StubQueue* sq)) {
-  for (int i = 0; i < StubQueueLimit; i++) {
-    if (registered_stub_queues[i] != NULL) {
-      f(registered_stub_queues[i]);
-    }
-  }
-}
-
-
-void StubQueue::stubs_do(void f(Stub* s)) {
-  debug_only(verify();)
-  MutexLockerEx lock(_mutex);
-  for (Stub* s = first(); s != NULL; s = next(s)) f(s);
-}
-
-
 void StubQueue::verify() {
   // verify only if initialized
   if (_stub_buffer == NULL) return;
--- a/src/hotspot/share/code/stubs.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/code/stubs.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -172,8 +172,6 @@
   void  stub_verify(Stub* s)                     { _stub_interface->verify(s); }
   void  stub_print(Stub* s)                      { _stub_interface->print(s); }
 
-  static void register_queue(StubQueue*);
-
  public:
   StubQueue(StubInterface* stub_interface, int buffer_size, Mutex* lock,
             const char* name);
@@ -204,8 +202,6 @@
   void deallocate_unused_tail();                 // deallocate the unused tail of the underlying CodeBlob
                                                  // only used from TemplateInterpreter::initialize()
   // Iteration
-  static void queues_do(void f(StubQueue* s));   // call f with each StubQueue
-  void  stubs_do(void f(Stub* s));               // call f with all stubs
   Stub* first() const                            { return number_of_stubs() > 0 ? stub_at(_queue_begin) : NULL; }
   Stub* next(Stub* s) const                      { int i = index_of(s) + stub_size(s);
                                                    // Only wrap around in the non-contiguous case (see stubss.cpp)
@@ -213,9 +209,6 @@
                                                    return (i == _queue_end) ? NULL : stub_at(i);
                                                  }
 
-  address stub_code_begin(Stub* s) const         { return _stub_interface->code_begin(s); }
-  address stub_code_end(Stub* s) const           { return _stub_interface->code_end(s);   }
-
   // Debugging/printing
   void  verify();                                // verifies the stub queue
   void  print();                                 // prints information about the stub queue
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -71,6 +71,6 @@
 }
 
 void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
-  // initialize the policy counters - 2 collectors, 3 generations
-  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3);
+  // initialize the policy counters - 2 collectors, 2 generations
+  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 2);
 }
--- a/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/dirtyCardQueue.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 
 // Closure used for updating remembered sets and recording references that
 // point into the collection set while the mutator is running.
@@ -319,7 +320,7 @@
   clear();
   // Since abandon is done only at safepoints, we can safely manipulate
   // these queues.
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->dirty_card_queue().reset();
   }
   shared_dirty_card_queue()->reset();
@@ -338,7 +339,7 @@
   int save_max_completed_queue = _max_completed_queue;
   _max_completed_queue = max_jint;
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     concatenate_log(t->dirty_card_queue());
   }
   concatenate_log(_shared_dirty_card_queue);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -39,7 +39,6 @@
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1FullCollector.hpp"
-#include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HeapSizingPolicy.hpp"
 #include "gc/g1/g1HeapTransition.hpp"
@@ -81,6 +80,7 @@
 #include "runtime/atomic.hpp"
 #include "runtime/init.hpp"
 #include "runtime/orderAccess.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -1217,34 +1217,6 @@
 #endif
 }
 
-void G1CollectedHeap::do_full_collection_inner(G1FullGCScope* scope) {
-  GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
-  g1_policy()->record_full_collection_start();
-
-  print_heap_before_gc();
-  print_heap_regions();
-
-  abort_concurrent_cycle();
-  verify_before_full_collection(scope->is_explicit_gc());
-
-  gc_prologue(true);
-  prepare_heap_for_full_collection();
-
-  G1FullCollector collector(scope, ref_processor_stw(), concurrent_mark()->next_mark_bitmap(), workers()->active_workers());
-  collector.prepare_collection();
-  collector.collect();
-  collector.complete_collection();
-
-  prepare_heap_for_mutators();
-
-  g1_policy()->record_full_collection_end();
-  gc_epilogue(true);
-
-  verify_after_full_collection();
-
-  print_heap_after_full_collection(scope->heap_transition());
-}
-
 bool G1CollectedHeap::do_full_collection(bool explicit_gc,
                                          bool clear_all_soft_refs) {
   assert_at_safepoint(true /* should_be_vm_thread */);
@@ -1257,8 +1229,12 @@
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
       collector_policy()->should_clear_all_soft_refs();
 
-  G1FullGCScope scope(explicit_gc, do_clear_all_soft_refs);
-  do_full_collection_inner(&scope);
+  G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs);
+  GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
+
+  collector.prepare_collection();
+  collector.collect();
+  collector.complete_collection();
 
   // Full collection was successfully completed.
   return true;
@@ -2653,11 +2629,9 @@
 
 size_t G1CollectedHeap::pending_card_num() {
   size_t extra_cards = 0;
-  JavaThread *curr = Threads::first();
-  while (curr != NULL) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *curr = jtiwh.next(); ) {
     DirtyCardQueue& dcq = curr->dirty_card_queue();
     extra_cards += dcq.size();
-    curr = curr->next();
   }
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   size_t buffer_size = dcqs.buffer_size();
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -42,11 +42,11 @@
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc/g1/g1SurvivorRegions.hpp"
 #include "gc/g1/g1YCTypes.hpp"
-#include "gc/g1/hSpaceCounters.hpp"
 #include "gc/g1/heapRegionManager.hpp"
 #include "gc/g1/heapRegionSet.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/plab.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "memory/memRegion.hpp"
@@ -126,6 +126,7 @@
   friend class VM_G1IncCollectionPause;
   friend class VMStructs;
   friend class MutatorAllocRegion;
+  friend class G1FullCollector;
   friend class G1GCAllocRegion;
   friend class G1HeapVerifier;
 
@@ -517,7 +518,6 @@
 private:
   // Internal helpers used during full GC to split it up to
   // increase readability.
-  void do_full_collection_inner(G1FullGCScope* scope);
   void abort_concurrent_cycle();
   void verify_before_full_collection(bool explicit_gc);
   void prepare_heap_for_full_collection();
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1756,28 +1756,24 @@
   G1ConcurrentMark* _cm;
 public:
   void work(uint worker_id) {
-    // Since all available tasks are actually started, we should
-    // only proceed if we're supposed to be active.
-    if (worker_id < _cm->active_tasks()) {
-      G1CMTask* task = _cm->task(worker_id);
-      task->record_start_time();
-      {
-        ResourceMark rm;
-        HandleMark hm;
-
-        G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
-        Threads::threads_do(&threads_f);
-      }
-
-      do {
-        task->do_marking_step(1000000000.0 /* something very large */,
-                              true         /* do_termination       */,
-                              false        /* is_serial            */);
-      } while (task->has_aborted() && !_cm->has_overflown());
-      // If we overflow, then we do not want to restart. We instead
-      // want to abort remark and do concurrent marking again.
-      task->record_end_time();
+    G1CMTask* task = _cm->task(worker_id);
+    task->record_start_time();
+    {
+      ResourceMark rm;
+      HandleMark hm;
+
+      G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
+      Threads::threads_do(&threads_f);
     }
+
+    do {
+      task->do_marking_step(1000000000.0 /* something very large */,
+                            true         /* do_termination       */,
+                            false        /* is_serial            */);
+    } while (task->has_aborted() && !_cm->has_overflown());
+    // If we overflow, then we do not want to restart. We instead
+    // want to abort remark and do concurrent marking again.
+    task->record_end_time();
   }
 
   G1CMRemarkTask(G1ConcurrentMark* cm, uint active_workers) :
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -33,6 +33,107 @@
 #include "utilities/pair.hpp"
 #include <math.h>
 
+G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
+  G1ConcurrentRefineThread* result = NULL;
+  if (initializing || !InjectGCWorkerCreationFailure) {
+    result = new G1ConcurrentRefineThread(_cr, worker_id);
+  }
+  if (result == NULL || result->osthread() == NULL) {
+    log_warning(gc)("Failed to create refinement thread %u, no more %s",
+                    worker_id,
+                    result == NULL ? "memory" : "OS threads");
+  }
+  return result;
+}
+
+G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
+  _cr(NULL),
+  _threads(NULL),
+  _num_max_threads(0)
+{
+}
+
+G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    G1ConcurrentRefineThread* t = _threads[i];
+    if (t != NULL) {
+      delete t;
+    }
+  }
+  FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
+}
+
+jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint num_max_threads) {
+  assert(cr != NULL, "G1ConcurrentRefine must not be NULL");
+  _cr = cr;
+  _num_max_threads = num_max_threads;
+
+  _threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, num_max_threads, mtGC);
+  if (_threads == NULL) {
+    vm_shutdown_during_initialization("Could not allocate thread holder array.");
+    return JNI_ENOMEM;
+  }
+
+  for (uint i = 0; i < num_max_threads; i++) {
+    if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) {
+      _threads[i] = NULL;
+    } else {
+      _threads[i] = create_refinement_thread(i, true);
+      if (_threads[i] == NULL) {
+        vm_shutdown_during_initialization("Could not allocate refinement threads.");
+        return JNI_ENOMEM;
+      }
+    }
+  }
+  return JNI_OK;
+}
+
+void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) {
+  assert(cur_worker_id < _num_max_threads,
+         "Activating another thread from %u not allowed since there can be at most %u",
+         cur_worker_id, _num_max_threads);
+  if (cur_worker_id == (_num_max_threads - 1)) {
+    // Already the last thread, there is no more thread to activate.
+    return;
+  }
+
+  uint worker_id = cur_worker_id + 1;
+  G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
+  if (thread_to_activate == NULL) {
+    // Still need to create the thread...
+    _threads[worker_id] = create_refinement_thread(worker_id, false);
+    thread_to_activate = _threads[worker_id];
+  }
+  if (thread_to_activate != NULL && !thread_to_activate->is_active()) {
+    thread_to_activate->activate();
+  }
+}
+
+void G1ConcurrentRefineThreadControl::print_on(outputStream* st) const {
+  for (uint i = 0; i < _num_max_threads; ++i) {
+    if (_threads[i] != NULL) {
+      _threads[i]->print_on(st);
+      st->cr();
+    }
+  }
+}
+
+void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    if (_threads[i] != NULL) {
+      tc->do_thread(_threads[i]);
+    }
+  }
+}
+
+void G1ConcurrentRefineThreadControl::stop() {
+  for (uint i = 0; i < _num_max_threads; i++) {
+    if (_threads[i] != NULL) {
+      _threads[i]->stop();
+    }
+  }
+}
+
 // Arbitrary but large limits, to simplify some of the zone calculations.
 // The general idea is to allow expressions like
 //   MIN2(x OP y, max_XXX_zone)
@@ -96,7 +197,7 @@
                                   size_t yellow_zone,
                                   uint worker_i) {
   double yellow_size = yellow_zone - green_zone;
-  double step = yellow_size / G1ConcurrentRefine::thread_num();
+  double step = yellow_size / G1ConcurrentRefine::max_num_threads();
   if (worker_i == 0) {
     // Potentially activate worker 0 more aggressively, to keep
     // available buffers near green_zone value.  When yellow_size is
@@ -115,8 +216,7 @@
                                        size_t yellow_zone,
                                        size_t red_zone,
                                        size_t min_yellow_zone_size) :
-  _threads(NULL),
-  _n_worker_threads(thread_num()),
+  _thread_control(),
   _green_zone(green_zone),
   _yellow_zone(yellow_zone),
   _red_zone(red_zone),
@@ -125,9 +225,13 @@
   assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
 }
 
+jint G1ConcurrentRefine::initialize() {
+  return _thread_control.initialize(this, max_num_threads());
+}
+
 static size_t calc_min_yellow_zone_size() {
   size_t step = G1ConcRefinementThresholdStep;
-  uint n_workers = G1ConcurrentRefine::thread_num();
+  uint n_workers = G1ConcurrentRefine::max_num_threads();
   if ((max_yellow_zone / step) < n_workers) {
     return max_yellow_zone;
   } else {
@@ -191,77 +295,27 @@
     return NULL;
   }
 
-  cr->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, cr->_n_worker_threads, mtGC);
-  if (cr->_threads == NULL) {
-    *ecode = JNI_ENOMEM;
-    vm_shutdown_during_initialization("Could not allocate an array for G1ConcurrentRefineThread");
-    return NULL;
-  }
-
-  uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
-
-  G1ConcurrentRefineThread *next = NULL;
-  for (uint i = cr->_n_worker_threads - 1; i != UINT_MAX; i--) {
-    Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
-    G1ConcurrentRefineThread* t =
-      new G1ConcurrentRefineThread(cr,
-                                   next,
-                                   worker_id_offset,
-                                   i,
-                                   activation_level(thresholds),
-                                   deactivation_level(thresholds));
-    assert(t != NULL, "Conc refine should have been created");
-    if (t->osthread() == NULL) {
-      *ecode = JNI_ENOMEM;
-      vm_shutdown_during_initialization("Could not create G1ConcurrentRefineThread");
-      return NULL;
-    }
-
-    assert(t->cr() == cr, "Conc refine thread should refer to this");
-    cr->_threads[i] = t;
-    next = t;
-  }
-
-  *ecode = JNI_OK;
+  *ecode = cr->initialize();
   return cr;
 }
 
 void G1ConcurrentRefine::stop() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    _threads[i]->stop();
-  }
-}
-
-void G1ConcurrentRefine::update_thread_thresholds() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
-    _threads[i]->update_thresholds(activation_level(thresholds),
-                                   deactivation_level(thresholds));
-  }
+  _thread_control.stop();
 }
 
 G1ConcurrentRefine::~G1ConcurrentRefine() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    delete _threads[i];
-  }
-  FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
 }
 
 void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    tc->do_thread(_threads[i]);
-  }
+  _thread_control.worker_threads_do(tc);
 }
 
-uint G1ConcurrentRefine::thread_num() {
+uint G1ConcurrentRefine::max_num_threads() {
   return G1ConcRefinementThreads;
 }
 
 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
-  for (uint i = 0; i < _n_worker_threads; ++i) {
-    _threads[i]->print_on(st);
-    st->cr();
-  }
+  _thread_control.print_on(st);
 }
 
 static size_t calc_new_green_zone(size_t green,
@@ -326,16 +380,15 @@
 
   if (G1UseAdaptiveConcRefinement) {
     update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
-    update_thread_thresholds();
 
     // Change the barrier params
-    if (_n_worker_threads == 0) {
+    if (max_num_threads() == 0) {
       // Disable dcqs notification when there are no threads to notify.
       dcqs.set_process_completed_threshold(INT_MAX);
     } else {
       // Worker 0 is the primary; wakeup is via dcqs notification.
       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
-      size_t activate = _threads[0]->activation_threshold();
+      size_t activate = activation_threshold(0);
       dcqs.set_process_completed_threshold((int)activate);
     }
     dcqs.set_max_completed_queue((int)red_zone());
@@ -349,3 +402,42 @@
   }
   dcqs.notify_if_necessary();
 }
+
+size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
+  Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
+  return activation_level(thresholds);
+}
+
+size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const {
+  Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
+  return deactivation_level(thresholds);
+}
+
+uint G1ConcurrentRefine::worker_id_offset() {
+  return DirtyCardQueueSet::num_par_ids();
+}
+
+void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers) {
+  if (num_cur_buffers > activation_threshold(worker_id + 1)) {
+    _thread_control.maybe_activate_next(worker_id);
+  }
+}
+
+bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+
+  size_t curr_buffer_num = dcqs.completed_buffers_num();
+  // If the number of the buffers falls down into the yellow zone,
+  // that means that the transition period after the evacuation pause has ended.
+  // Since the value written to the DCQS is the same for all threads, there is no
+  // need to synchronize.
+  if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= yellow_zone()) {
+    dcqs.set_completed_queue_padding(0);
+  }
+
+  maybe_activate_more_threads(worker_id, curr_buffer_num);
+
+  // Process the next buffer, if there are enough left.
+  return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
+                                                   deactivation_threshold(worker_id));
+}
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -30,30 +30,63 @@
 
 // Forward decl
 class CardTableEntryClosure;
+class G1ConcurrentRefine;
 class G1ConcurrentRefineThread;
 class outputStream;
 class ThreadClosure;
 
+// Helper class for refinement thread management. Used to start, stop and
+// iterate over them.
+class G1ConcurrentRefineThreadControl VALUE_OBJ_CLASS_SPEC {
+  G1ConcurrentRefine* _cr;
+
+  G1ConcurrentRefineThread** _threads;
+  uint _num_max_threads;
+
+  // Create the refinement thread for the given worker id.
+  // If initializing is true, ignore InjectGCWorkerCreationFailure.
+  G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing);
+public:
+  G1ConcurrentRefineThreadControl();
+  ~G1ConcurrentRefineThreadControl();
+
+  jint initialize(G1ConcurrentRefine* cr, uint num_max_threads);
+
+  // If there is a "successor" thread that can be activated given the current id,
+  // activate it.
+  void maybe_activate_next(uint cur_worker_id);
+
+  void print_on(outputStream* st) const;
+  void worker_threads_do(ThreadClosure* tc);
+  void stop();
+};
+
+// Controls refinement threads and their activation based on the number of completed
+// buffers currently available in the global dirty card queue.
+// Refinement threads pick work from the queue based on these thresholds. They are activated
+// gradually based on the amount of work to do.
+// Refinement thread n activates thread n+1 if the instance of this class determines there
+// is enough work available. Threads deactivate themselves if the current amount of
+// completed buffers falls below their individual threshold.
 class G1ConcurrentRefine : public CHeapObj<mtGC> {
-  G1ConcurrentRefineThread** _threads;
-  uint _n_worker_threads;
- /*
-  * The value of the update buffer queue length falls into one of 3 zones:
-  * green, yellow, red. If the value is in [0, green) nothing is
-  * done, the buffers are left unprocessed to enable the caching effect of the
-  * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
-  * threads are gradually activated. In [yellow, red) all threads are
-  * running. If the length becomes red (max queue length) the mutators start
-  * processing the buffers.
-  *
-  * There are some interesting cases (when G1UseAdaptiveConcRefinement
-  * is turned off):
-  * 1) green = yellow = red = 0. In this case the mutator will process all
-  *    buffers. Except for those that are created by the deferred updates
-  *    machinery during a collection.
-  * 2) green = 0. Means no caching. Can be a good way to minimize the
-  *    amount of time spent updating rsets during a collection.
-  */
+  G1ConcurrentRefineThreadControl _thread_control;
+  /*
+   * The value of the completed dirty card queue length falls into one of 3 zones:
+   * green, yellow, red. If the value is in [0, green) nothing is
+   * done, the buffers are left unprocessed to enable the caching effect of the
+   * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
+   * threads are gradually activated. In [yellow, red) all threads are
+   * running. If the length becomes red (max queue length) the mutators start
+   * processing the buffers.
+   *
+   * There are some interesting cases (when G1UseAdaptiveConcRefinement
+   * is turned off):
+   * 1) green = yellow = red = 0. In this case the mutator will process all
+   *    buffers. Except for those that are created by the deferred updates
+   *    machinery during a collection.
+   * 2) green = 0. Means no caching. Can be a good way to minimize the
+   *    amount of time spent updating remembered sets during a collection.
+   */
   size_t _green_zone;
   size_t _yellow_zone;
   size_t _red_zone;
@@ -69,24 +102,32 @@
                     size_t update_rs_processed_buffers,
                     double goal_ms);
 
-  // Update thread thresholds to account for updated zone values.
-  void update_thread_thresholds();
+  static uint worker_id_offset();
+  void maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers);
 
- public:
+  jint initialize();
+public:
   ~G1ConcurrentRefine();
 
-  // Returns a G1ConcurrentRefine instance if succeeded to create/initialize G1ConcurrentRefine and G1ConcurrentRefineThreads.
-  // Otherwise, returns NULL with error code.
+  // Returns a G1ConcurrentRefine instance if succeeded to create/initialize the
+  // G1ConcurrentRefine instance. Otherwise, returns NULL with error code.
   static G1ConcurrentRefine* create(jint* ecode);
 
   void stop();
 
+  // Adjust refinement thresholds based on work done during the pause and the goal time.
   void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
 
+  size_t activation_threshold(uint worker_id) const;
+  size_t deactivation_threshold(uint worker_id) const;
+  // Perform a single refinement step. Called by the refinement threads when woken up.
+  bool do_refinement_step(uint worker_id);
+
   // Iterate over all concurrent refinement threads applying the given closure.
   void threads_do(ThreadClosure *tc);
 
-  static uint thread_num();
+  // Maximum number of refinement threads.
+  static uint max_num_threads();
 
   void print_threads_on(outputStream* st) const;
 
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -25,32 +25,20 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1ConcurrentRefineThread.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1RemSet.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
 
-G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr,
-                                                   G1ConcurrentRefineThread *next,
-                                                   uint worker_id_offset,
-                                                   uint worker_id,
-                                                   size_t activate,
-                                                   size_t deactivate) :
+G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
   ConcurrentGCThread(),
-  _worker_id_offset(worker_id_offset),
   _worker_id(worker_id),
   _active(false),
-  _next(next),
   _monitor(NULL),
   _cr(cr),
-  _vtime_accum(0.0),
-  _activation_threshold(activate),
-  _deactivation_threshold(deactivate)
+  _vtime_accum(0.0)
 {
-
   // Each thread has its own monitor. The i-th thread is responsible for signaling
   // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
   // thread. Monitors are also used to wake up the threads during termination.
@@ -67,13 +55,6 @@
   create_and_start();
 }
 
-void G1ConcurrentRefineThread::update_thresholds(size_t activate,
-                                                 size_t deactivate) {
-  assert(deactivate < activate, "precondition");
-  _activation_threshold = activate;
-  _deactivation_threshold = deactivate;
-}
-
 void G1ConcurrentRefineThread::wait_for_completed_buffers() {
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   while (!should_terminate() && !is_active()) {
@@ -118,9 +99,9 @@
     }
 
     size_t buffers_processed = 0;
-    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-    log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                          _worker_id, _activation_threshold, dcqs.completed_buffers_num());
+    log_debug(gc, refine)("Activated worker %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
+                          _worker_id, _cr->activation_threshold(_worker_id),
+                           JavaThread::dirty_card_queue_set().completed_buffers_num());
 
     {
       SuspendibleThreadSetJoiner sts_join;
@@ -131,33 +112,18 @@
           continue;             // Re-check for termination after yield delay.
         }
 
-        size_t curr_buffer_num = dcqs.completed_buffers_num();
-        // If the number of the buffers falls down into the yellow zone,
-        // that means that the transition period after the evacuation pause has ended.
-        if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cr()->yellow_zone()) {
-          dcqs.set_completed_queue_padding(0);
-        }
-
-        // Check if we need to activate the next thread.
-        if ((_next != NULL) &&
-            !_next->is_active() &&
-            (curr_buffer_num > _next->_activation_threshold)) {
-          _next->activate();
-        }
-
-        // Process the next buffer, if there are enough left.
-        if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
-          break; // Deactivate, number of buffers fell below threshold.
+        if (!_cr->do_refinement_step(_worker_id)) {
+          break;
         }
         ++buffers_processed;
       }
     }
 
     deactivate();
-    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
+    log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT
                           ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
-                          _worker_id, _deactivation_threshold,
-                          dcqs.completed_buffers_num(),
+                          _worker_id, _cr->deactivation_threshold(_worker_id),
+                          JavaThread::dirty_card_queue_set().completed_buffers_num(),
                           buffers_processed);
 
     if (os::supports_vtime()) {
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -43,43 +43,29 @@
   uint _worker_id;
   uint _worker_id_offset;
 
-  // The refinement threads collection is linked list. A predecessor can activate a successor
-  // when the number of the rset update buffer crosses a certain threshold. A successor
-  // would self-deactivate when the number of the buffers falls below the threshold.
   bool _active;
-  G1ConcurrentRefineThread* _next;
   Monitor* _monitor;
   G1ConcurrentRefine* _cr;
 
-  // This thread's activation/deactivation thresholds
-  size_t _activation_threshold;
-  size_t _deactivation_threshold;
-
   void wait_for_completed_buffers();
 
   void set_active(bool x) { _active = x; }
-  bool is_active();
-  void activate();
+  // Deactivate this thread.
   void deactivate();
 
   bool is_primary() { return (_worker_id == 0); }
 
   void run_service();
   void stop_service();
+public:
+  G1ConcurrentRefineThread(G1ConcurrentRefine* cg1r, uint worker_id);
 
-public:
-  // Constructor
-  G1ConcurrentRefineThread(G1ConcurrentRefine* cr, G1ConcurrentRefineThread* next,
-                           uint worker_id_offset, uint worker_id,
-                           size_t activate, size_t deactivate);
-
-  void update_thresholds(size_t activate, size_t deactivate);
-  size_t activation_threshold() const { return _activation_threshold; }
+  bool is_active();
+  // Activate this thread.
+  void activate();
 
   // Total virtual time so far.
   double vtime_accum() { return _vtime_accum; }
-
-  G1ConcurrentRefine* cr() { return _cr;     }
 };
 
 #endif // SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP
--- a/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -52,7 +52,7 @@
   _analytics(new G1Analytics(&_predictor)),
   _mmu_tracker(new G1MMUTrackerQueue(GCPauseIntervalMillis / 1000.0, MaxGCPauseMillis / 1000.0)),
   _ihop_control(create_ihop_control(&_predictor)),
-  _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 3)),
+  _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 2)),
   _young_list_fixed_length(0),
   _short_lived_surv_rate_group(new SurvRateGroup()),
   _survivor_surv_rate_group(new SurvRateGroup()),
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -35,6 +35,7 @@
 #include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1OopClosures.hpp"
+#include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/preservedMarks.hpp"
@@ -62,20 +63,24 @@
 #endif
 }
 
-G1FullCollector::G1FullCollector(G1FullGCScope* scope,
-                                 ReferenceProcessor* reference_processor,
-                                 G1CMBitMap* bitmap,
-                                 uint workers) :
-    _scope(scope),
-    _num_workers(workers),
-    _mark_bitmap(bitmap),
+G1CMBitMap* G1FullCollector::mark_bitmap() {
+  return _heap->concurrent_mark()->next_mark_bitmap();
+}
+
+ReferenceProcessor* G1FullCollector::reference_processor() {
+  return _heap->ref_processor_stw();
+}
+
+G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs) :
+    _heap(heap),
+    _scope(explicit_gc, clear_soft_refs),
+    _num_workers(heap->workers()->active_workers()),
     _oop_queue_set(_num_workers),
     _array_queue_set(_num_workers),
     _preserved_marks_set(true),
-    _reference_processor(reference_processor),
     _serial_compaction_point(),
-    _is_alive(_mark_bitmap),
-    _is_alive_mutator(_reference_processor, &_is_alive) {
+    _is_alive(heap->concurrent_mark()->next_mark_bitmap()),
+    _is_alive_mutator(heap->ref_processor_stw(), &_is_alive) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
 
   _preserved_marks_set.init(_num_workers);
@@ -99,8 +104,19 @@
 }
 
 void G1FullCollector::prepare_collection() {
-  _reference_processor->enable_discovery();
-  _reference_processor->setup_policy(scope()->should_clear_soft_refs());
+  _heap->g1_policy()->record_full_collection_start();
+
+  _heap->print_heap_before_gc();
+  _heap->print_heap_regions();
+
+  _heap->abort_concurrent_cycle();
+  _heap->verify_before_full_collection(scope()->is_explicit_gc());
+
+  _heap->gc_prologue(true);
+  _heap->prepare_heap_for_full_collection();
+
+  reference_processor()->enable_discovery();
+  reference_processor()->setup_policy(scope()->should_clear_soft_refs());
 
   // When collecting the permanent generation Method*s may be moving,
   // so we either have to flush all bcp data or convert it into bci.
@@ -139,6 +155,15 @@
   BiasedLocking::restore_marks();
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
+
+  _heap->prepare_heap_for_mutators();
+
+  _heap->g1_policy()->record_full_collection_end();
+  _heap->gc_epilogue(true);
+
+  _heap->verify_after_full_collection();
+
+  _heap->print_heap_after_full_collection(scope()->heap_transition());
 }
 
 void G1FullCollector::phase1_mark_live_objects() {
@@ -164,11 +189,11 @@
     GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer());
     // Unload classes and purge the SystemDictionary.
     bool purged_class = SystemDictionary::do_unloading(&_is_alive, scope()->timer());
-    G1CollectedHeap::heap()->complete_cleaning(&_is_alive, purged_class);
+    _heap->complete_cleaning(&_is_alive, purged_class);
   } else {
     GCTraceTime(Debug, gc, phases) debug("Phase 1: String and Symbol Tables Cleanup", scope()->timer());
     // If no class unloading just clean out strings and symbols.
-    G1CollectedHeap::heap()->partial_cleaning(&_is_alive, true, true, G1StringDedup::is_enabled());
+    _heap->partial_cleaning(&_is_alive, true, true, G1StringDedup::is_enabled());
   }
 
   scope()->tracer()->report_object_count_after_gc(&_is_alive);
@@ -210,13 +235,13 @@
 }
 
 void G1FullCollector::restore_marks() {
-  SharedRestorePreservedMarksTaskExecutor task_executor(G1CollectedHeap::heap()->workers());
+  SharedRestorePreservedMarksTaskExecutor task_executor(_heap->workers());
   _preserved_marks_set.restore(&task_executor);
   _preserved_marks_set.reclaim();
 }
 
 void G1FullCollector::run_task(AbstractGangTask* task) {
-  G1CollectedHeap::heap()->workers()->run_task(task, _num_workers);
+  _heap->workers()->run_task(task, _num_workers);
 }
 
 void G1FullCollector::verify_after_marking() {
@@ -229,7 +254,7 @@
 #if COMPILER2_OR_JVMCI
   DerivedPointerTableDeactivate dpt_deact;
 #endif
-  G1CollectedHeap::heap()->prepare_for_verify();
+  _heap->prepare_for_verify();
   // Note: we can verify only the heap here. When an object is
   // marked, the previous value of the mark word (including
   // identity hash values, ages, etc) is preserved, and the mark
@@ -241,5 +266,5 @@
   // (including hash values) are restored to the appropriate
   // objects.
   GCTraceTime(Info, gc, verify)("During GC (full)");
-  G1CollectedHeap::heap()->verify(VerifyOption_G1UseFullMarking);
+  _heap->verify(VerifyOption_G1UseFullMarking);
 }
--- a/src/hotspot/share/gc/g1/g1FullCollector.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -28,6 +28,7 @@
 #include "gc/g1/g1FullGCCompactionPoint.hpp"
 #include "gc/g1/g1FullGCMarker.hpp"
 #include "gc/g1/g1FullGCOopClosures.hpp"
+#include "gc/g1/g1FullGCScope.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/taskqueue.hpp"
@@ -42,41 +43,36 @@
 
 // The G1FullCollector holds data associated with the current Full GC.
 class G1FullCollector : StackObj {
-  G1FullGCScope*            _scope;
+  G1CollectedHeap*          _heap;
+  G1FullGCScope             _scope;
   uint                      _num_workers;
   G1FullGCMarker**          _markers;
   G1FullGCCompactionPoint** _compaction_points;
-  G1CMBitMap*               _mark_bitmap;
   OopQueueSet               _oop_queue_set;
   ObjArrayTaskQueueSet      _array_queue_set;
   PreservedMarksSet         _preserved_marks_set;
-  ReferenceProcessor*       _reference_processor;
   G1FullGCCompactionPoint   _serial_compaction_point;
-
   G1IsAliveClosure          _is_alive;
   ReferenceProcessorIsAliveMutator _is_alive_mutator;
 
 public:
-  G1FullCollector(G1FullGCScope* scope,
-                  ReferenceProcessor* reference_processor,
-                  G1CMBitMap* mark_bitmap,
-                  uint workers);
+  G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs);
   ~G1FullCollector();
 
   void prepare_collection();
   void collect();
   void complete_collection();
 
-  G1FullGCScope*           scope() { return _scope; }
+  G1FullGCScope*           scope() { return &_scope; }
   uint                     workers() { return _num_workers; }
   G1FullGCMarker*          marker(uint id) { return _markers[id]; }
   G1FullGCCompactionPoint* compaction_point(uint id) { return _compaction_points[id]; }
-  G1CMBitMap*              mark_bitmap() { return _mark_bitmap; }
   OopQueueSet*             oop_queue_set() { return &_oop_queue_set; }
   ObjArrayTaskQueueSet*    array_queue_set() { return &_array_queue_set; }
   PreservedMarksSet*       preserved_mark_set() { return &_preserved_marks_set; }
-  ReferenceProcessor*      reference_processor() { return _reference_processor; }
   G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; }
+  G1CMBitMap*              mark_bitmap();
+  ReferenceProcessor*      reference_processor();
 
 private:
   void phase1_mark_live_objects();
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -26,6 +26,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1MonitoringSupport.hpp"
 #include "gc/g1/g1Policy.hpp"
+#include "gc/shared/hSpaceCounters.hpp"
 
 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
                                            const char* name,
@@ -128,10 +129,10 @@
   //  name  "generation.1.space.0"
   // Counters are created from maxCapacity, capacity, initCapacity,
   // and used.
-  _old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
+  _old_space_counters = new HSpaceCounters(_old_collection_counters->name_space(),
+    "space", 0 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(old_space_committed()) /* init_capacity */,
-   _old_collection_counters);
+    pad_capacity(old_space_committed()) /* init_capacity */);
 
   //   Young collection set
   //  name "generation.0".  This is logically the young generation.
@@ -139,27 +140,29 @@
   // See  _old_collection_counters for additional counters
   _young_collection_counters = new G1YoungGenerationCounters(this, "young");
 
+  const char* young_collection_name_space = _young_collection_counters->name_space();
+
   //  name "generation.0.space.0"
   // See _old_space_counters for additional counters
-  _eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
+  _eden_counters = new HSpaceCounters(young_collection_name_space,
+    "eden", 0 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(eden_space_committed()) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(eden_space_committed()) /* init_capacity */);
 
   //  name "generation.0.space.1"
   // See _old_space_counters for additional counters
   // Set the arguments to indicate that this survivor space is not used.
-  _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
+  _from_counters = new HSpaceCounters(young_collection_name_space,
+    "s0", 1 /* ordinal */,
     pad_capacity(0) /* max_capacity */,
-    pad_capacity(0) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(0) /* init_capacity */);
 
   //  name "generation.0.space.2"
   // See _old_space_counters for additional counters
-  _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
+  _to_counters = new HSpaceCounters(young_collection_name_space,
+    "s1", 2 /* ordinal */,
     pad_capacity(overall_reserved()) /* max_capacity */,
-    pad_capacity(survivor_space_committed()) /* init_capacity */,
-    _young_collection_counters);
+    pad_capacity(survivor_space_committed()) /* init_capacity */);
 
   if (UsePerfData) {
     // Given that this survivor space is not used, we update it here
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -25,9 +25,11 @@
 #ifndef SHARE_VM_GC_G1_G1MONITORINGSUPPORT_HPP
 #define SHARE_VM_GC_G1_G1MONITORINGSUPPORT_HPP
 
-#include "gc/g1/hSpaceCounters.hpp"
+#include "gc/shared/generationCounters.hpp"
 
+class CollectorCounters;
 class G1CollectedHeap;
+class HSpaceCounters;
 
 // Class for monitoring logical spaces in G1. It provides data for
 // both G1's jstat counters as well as G1's memory pools.
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -298,7 +298,7 @@
 }
 
 uint G1RemSet::num_par_rem_sets() {
-  return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::thread_num(), ParallelGCThreads);
+  return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads(), ParallelGCThreads);
 }
 
 void G1RemSet::initialize(size_t capacity, uint max_regions) {
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -86,7 +86,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(G1ConcurrentRefine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
 
@@ -99,7 +99,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(G1ConcurrentRefine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
   update();
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -175,6 +175,9 @@
 
 void
 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr) {
+  if (mr.is_empty()) {
+    return;
+  }
   volatile jbyte* byte = byte_for(mr.start());
   jbyte* last_byte = byte_for(mr.last());
   Thread* thr = Thread::current();
--- a/src/hotspot/share/gc/g1/hSpaceCounters.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/hSpaceCounters.hpp"
-#include "gc/shared/generation.hpp"
-#include "memory/resourceArea.hpp"
-
-HSpaceCounters::HSpaceCounters(const char* name,
-                               int ordinal,
-                               size_t max_size,
-                               size_t initial_capacity,
-                               GenerationCounters* gc) {
-
-  if (UsePerfData) {
-    EXCEPTION_MARK;
-    ResourceMark rm;
-
-    const char* cns =
-      PerfDataManager::name_space(gc->name_space(), "space", ordinal);
-
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
-    strcpy(_name_space, cns);
-
-    const char* cname = PerfDataManager::counter_name(_name_space, "name");
-    PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
-    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-                                     (jlong)max_size, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "capacity");
-    _capacity = PerfDataManager::create_variable(SUN_GC, cname,
-                                                 PerfData::U_Bytes,
-                                                 initial_capacity, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "used");
-    _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
-                                             (jlong) 0, CHECK);
-
-    cname = PerfDataManager::counter_name(_name_space, "initCapacity");
-    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-                                     initial_capacity, CHECK);
-  }
-}
--- a/src/hotspot/share/gc/g1/hSpaceCounters.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
-#define SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
-
-#include "gc/shared/generation.hpp"
-#include "gc/shared/generationCounters.hpp"
-#include "runtime/perfData.hpp"
-#include "utilities/macros.hpp"
-
-// A HSpaceCounter is a holder class for performance counters
-// that track a collections (logical spaces) in a heap;
-
-class HeapSpaceUsedHelper;
-class G1SpaceMonitoringSupport;
-
-class HSpaceCounters: public CHeapObj<mtGC> {
-  friend class VMStructs;
-
- private:
-  PerfVariable*        _capacity;
-  PerfVariable*        _used;
-
-  // Constant PerfData types don't need to retain a reference.
-  // However, it's a good idea to document them here.
-
-  char*             _name_space;
-
- public:
-
-  HSpaceCounters(const char* name, int ordinal, size_t max_size,
-                 size_t initial_capacity, GenerationCounters* gc);
-
-  ~HSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
-
-  inline void update_capacity(size_t v) {
-    _capacity->set_value(v);
-  }
-
-  inline void update_used(size_t v) {
-    _used->set_value(v);
-  }
-
-  debug_only(
-    // for security reasons, we do not allow arbitrary reads from
-    // the counters as they may live in shared memory.
-    jlong used() {
-      return _used->get_value();
-    }
-    jlong capacity() {
-      return _used->get_value();
-    }
-  )
-
-  inline void update_all(size_t capacity, size_t used) {
-    update_capacity(capacity);
-    update_used(used);
-  }
-
-  const char* name_space() const        { return _name_space; }
-};
-#endif // SHARE_VM_GC_G1_HSPACECOUNTERS_HPP
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 
 SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent) :
@@ -214,7 +215,7 @@
   log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
   log_error(gc, verify)("Actual SATB active states:");
   log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     log_error(gc, verify)("  Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
   }
   log_error(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
@@ -228,7 +229,7 @@
   }
 
   // Verify thread queue states
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     if (t->satb_mark_queue().is_active() != expected_active) {
       dump_active_states(expected_active);
       guarantee(false, "Thread SATB queue has an unexpected active state");
@@ -249,14 +250,14 @@
   verify_active_states(expected_active);
 #endif // ASSERT
   _all_active = active;
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().set_active(active);
   }
   shared_satb_queue()->set_active(active);
 }
 
 void SATBMarkQueueSet::filter_thread_buffers() {
-  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().filter();
   }
   shared_satb_queue()->filter();
@@ -309,7 +310,7 @@
     i += 1;
   }
 
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
     t->satb_mark_queue().print(buffer);
   }
@@ -341,8 +342,8 @@
   }
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   // So we can safely manipulate these queues.
-  for (JavaThread* t = Threads::first(); t; t = t->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     t->satb_mark_queue().reset();
   }
- shared_satb_queue()->reset();
+  shared_satb_queue()->reset();
 }
--- a/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/parallel/mutableNUMASpace.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -29,6 +29,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/align.hpp"
 
 MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment), _must_use_large_pages(false) {
@@ -287,7 +288,7 @@
     FREE_C_HEAP_ARRAY(int, lgrp_ids);
 
     if (changed) {
-      for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+      for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
         thread->set_lgrp_id(-1);
       }
     }
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -105,9 +105,9 @@
     (old_gen()->virtual_space()->high_boundary() ==
      young_gen()->virtual_space()->low_boundary()),
     "Boundaries must meet");
-  // initialize the policy counters - 2 collectors, 3 generations
+  // initialize the policy counters - 2 collectors, 2 generations
   _gc_policy_counters =
-    new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy);
+    new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 2, _size_policy);
 
   // Set up the GCTaskManager
   _gc_task_manager = GCTaskManager::create(ParallelGCThreads);
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -40,6 +40,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "services/heapDumper.hpp"
 #include "utilities/align.hpp"
 
@@ -540,10 +541,11 @@
   const bool deferred = _defer_initial_card_mark;
   // The main thread starts allocating via a TLAB even before it
   // has added itself to the threads list at vm boot-up.
-  assert(!use_tlab || Threads::first() != NULL,
+  JavaThreadIteratorWithHandle jtiwh;
+  assert(!use_tlab || jtiwh.length() > 0,
          "Attempt to fill tlabs before main thread has been added"
          " to threads list is doomed to failure!");
-  for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+  for (; JavaThread *thread = jtiwh.next(); ) {
      if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
 #if COMPILER2_OR_JVMCI
      // The deferred store barriers must all have been flushed to the
--- a/src/hotspot/share/gc/shared/collectorCounters.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorCounters.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/shared/collectorCounters.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/os.hpp"
 
 CollectorCounters::CollectorCounters(const char* name, int ordinal) {
 
@@ -59,3 +60,24 @@
                                                        CHECK);
   }
 }
+
+CollectorCounters::~CollectorCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
+TraceCollectorStats::TraceCollectorStats(CollectorCounters* c) :
+    PerfTraceTimedEvent(c->time_counter(), c->invocation_counter()),
+    _c(c) {
+
+  if (UsePerfData) {
+     _c->last_entry_counter()->set_value(os::elapsed_counter());
+  }
+}
+
+TraceCollectorStats::~TraceCollectorStats() {
+  if (UsePerfData) {
+    _c->last_exit_counter()->set_value(os::elapsed_counter());
+  }
+}
--- a/src/hotspot/share/gc/shared/collectorCounters.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorCounters.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -49,9 +49,7 @@
 
     CollectorCounters(const char* name, int ordinal);
 
-    ~CollectorCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-    }
+    ~CollectorCounters();
 
     inline PerfCounter* invocation_counter() const  { return _invocations; }
 
@@ -70,18 +68,9 @@
     CollectorCounters* _c;
 
   public:
-    inline TraceCollectorStats(CollectorCounters* c) :
-           PerfTraceTimedEvent(c->time_counter(), c->invocation_counter()),
-           _c(c) {
+    TraceCollectorStats(CollectorCounters* c);
 
-      if (UsePerfData) {
-         _c->last_entry_counter()->set_value(os::elapsed_counter());
-      }
-    }
-
-    inline ~TraceCollectorStats() {
-      if (UsePerfData) _c->last_exit_counter()->set_value(os::elapsed_counter());
-    }
+    ~TraceCollectorStats();
 };
 
 #endif // SHARE_VM_GC_SHARED_COLLECTORCOUNTERS_HPP
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -911,7 +911,7 @@
 }
 
 void MarkSweepPolicy::initialize_gc_policy_counters() {
-  // Initialize the policy counters - 2 collectors, 3 generations.
-  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
+  // Initialize the policy counters - 2 collectors, 2 generations.
+  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 2);
 }
 
--- a/src/hotspot/share/gc/shared/gcLocker.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcLocker.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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 "logging/log.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 
 volatile jint GCLocker::_jni_lock_count = 0;
 volatile bool GCLocker::_needs_gc       = false;
@@ -45,14 +46,16 @@
     assert(!needs_gc() || _debug_jni_lock_count == _jni_lock_count, "must agree");
     int count = 0;
     // Count the number of threads with critical operations in progress
-    for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) {
+    JavaThreadIteratorWithHandle jtiwh;
+    for (; JavaThread *thr = jtiwh.next(); ) {
       if (thr->in_critical()) {
         count++;
       }
     }
     if (_jni_lock_count != count) {
       log_error(gc, verify)("critical counts don't match: %d != %d", _jni_lock_count, count);
-      for (JavaThread* thr = Threads::first(); thr; thr = thr->next()) {
+      jtiwh.rewind();
+      for (; JavaThread *thr = jtiwh.next(); ) {
         if (thr->in_critical()) {
           log_error(gc, verify)(INTPTR_FORMAT " in_critical %d", p2i(thr), thr->in_critical());
         }
--- a/src/hotspot/share/gc/shared/generationCounters.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/generationCounters.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -78,6 +78,12 @@
   initialize(name, ordinal, spaces, min_capacity, max_capacity, curr_capacity);
 }
 
+GenerationCounters::~GenerationCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
 void GenerationCounters::update_all() {
   assert(_virtual_space != NULL, "otherwise, override this method");
   _current_size->set_value(_virtual_space->committed_size());
--- a/src/hotspot/share/gc/shared/generationCounters.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/generationCounters.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -68,9 +68,7 @@
   GenerationCounters(const char* name, int ordinal, int spaces,
                      size_t min_capacity, size_t max_capacity, VirtualSpace* v);
 
-  ~GenerationCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
-  }
+  ~GenerationCounters();
 
   virtual void update_all();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/hSpaceCounters.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/hSpaceCounters.hpp"
+#include "memory/allocation.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/perfData.hpp"
+
+HSpaceCounters::HSpaceCounters(const char* name_space,
+                               const char* name,
+                               int ordinal,
+                               size_t max_size,
+                               size_t initial_capacity) {
+
+  if (UsePerfData) {
+    EXCEPTION_MARK;
+    ResourceMark rm;
+
+    const char* cns =
+      PerfDataManager::name_space(name_space, "space", ordinal);
+
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
+    strcpy(_name_space, cns);
+
+    const char* cname = PerfDataManager::counter_name(_name_space, "name");
+    PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
+    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
+                                     (jlong)max_size, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "capacity");
+    _capacity = PerfDataManager::create_variable(SUN_GC, cname,
+                                                 PerfData::U_Bytes,
+                                                 initial_capacity, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "used");
+    _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
+                                             (jlong) 0, CHECK);
+
+    cname = PerfDataManager::counter_name(_name_space, "initCapacity");
+    PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
+                                     initial_capacity, CHECK);
+  }
+}
+
+HSpaceCounters::~HSpaceCounters() {
+  if (_name_space != NULL) {
+    FREE_C_HEAP_ARRAY(char, _name_space);
+  }
+}
+
+void HSpaceCounters::update_capacity(size_t v) {
+  _capacity->set_value(v);
+}
+
+void HSpaceCounters::update_used(size_t v) {
+  _used->set_value(v);
+}
+
+void HSpaceCounters::update_all(size_t capacity, size_t used) {
+  update_capacity(capacity);
+  update_used(used);
+}
+
+debug_only(
+  // for security reasons, we do not allow arbitrary reads from
+  // the counters as they may live in shared memory.
+  jlong HSpaceCounters::used() {
+    return _used->get_value();
+  }
+  jlong HSpaceCounters::capacity() {
+    return _used->get_value();
+  }
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/hSpaceCounters.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
+#define SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/perfData.hpp"
+#include "utilities/macros.hpp"
+
+// A HSpaceCounter is a holder class for performance counters
+// that track a collections (logical spaces) in a heap;
+
+class HSpaceCounters: public CHeapObj<mtGC> {
+  friend class VMStructs;
+
+ private:
+  PerfVariable* _capacity;
+  PerfVariable* _used;
+
+  // Constant PerfData types don't need to retain a reference.
+  // However, it's a good idea to document them here.
+
+  char*         _name_space;
+
+ public:
+
+  HSpaceCounters(const char* name_space, const char* name, int ordinal,
+                 size_t max_size, size_t initial_capacity);
+
+  ~HSpaceCounters();
+
+  void update_capacity(size_t v);
+  void update_used(size_t v);
+
+  void update_all(size_t capacity, size_t used);
+
+  debug_only(
+    // for security reasons, we do not allow arbitrary reads from
+    // the counters as they may live in shared memory.
+    jlong used();
+    jlong capacity();
+  )
+
+  const char* name_space() const        { return _name_space; }
+};
+#endif // SHARE_VM_GC_SHARED_HSPACECOUNTERS_HPP
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -30,6 +30,7 @@
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/copy.hpp"
 
 // Thread-Local Edens support
@@ -48,7 +49,7 @@
 void ThreadLocalAllocBuffer::accumulate_statistics_before_gc() {
   global_stats()->initialize();
 
-  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     thread->tlab().accumulate_statistics();
     thread->tlab().initialize_statistics();
   }
@@ -130,7 +131,7 @@
 
 void ThreadLocalAllocBuffer::resize_all_tlabs() {
   if (ResizeTLAB) {
-    for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
       thread->tlab().resize();
     }
   }
--- a/src/hotspot/share/gc/shared/workgroup.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/workgroup.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -261,6 +261,10 @@
     _dispatcher(create_dispatcher())
 { }
 
+WorkGang::~WorkGang() {
+  delete _dispatcher;
+}
+
 AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
   return new GangWorker(this, worker_id);
 }
--- a/src/hotspot/share/gc/shared/workgroup.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/gc/shared/workgroup.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -122,6 +122,8 @@
   // Printing support.
   const char* _name;
 
+  ~AbstractWorkGang() {}
+
  private:
   // Initialize only instance data.
   const bool _are_GC_task_threads;
@@ -206,9 +208,6 @@
   // To get access to the GangTaskDispatcher instance.
   friend class GangWorker;
 
-  // Never deleted.
-  ~WorkGang();
-
   GangTaskDispatcher* const _dispatcher;
   GangTaskDispatcher* dispatcher() const {
     return _dispatcher;
@@ -220,6 +219,8 @@
            bool are_GC_task_threads,
            bool are_ConcurrentGC_threads);
 
+  ~WorkGang();
+
   // Run a task using the current active number of workers, returns when the task is done.
   virtual void run_task(AbstractGangTask* task);
   // Run a task with the given number of workers, returns
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -42,6 +42,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/sharedRuntime.hpp"
+#include "runtime/threadSMR.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/macros.hpp"
@@ -598,12 +599,13 @@
 JRT_END
 
 JRT_ENTRY(jboolean, JVMCIRuntime::thread_is_interrupted(JavaThread* thread, oopDesc* receiver, jboolean clear_interrupted))
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate.
-  // This locking requires thread_in_vm which is why this method cannot be JRT_LEAF.
   Handle receiverHandle(thread, receiver);
-  MutexLockerEx ml(thread->threadObj() == (void*)receiver ? NULL : Threads_lock);
+  // A nested ThreadsListHandle may require the Threads_lock which
+  // requires thread_in_vm which is why this method cannot be JRT_LEAF.
+  ThreadsListHandle tlh;
+
   JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
-  if (receiverThread == NULL) {
+  if (receiverThread == NULL || (EnableThreadSMRExtraValidityChecks && !tlh.includes(receiverThread))) {
     // The other thread may exit during this process, which is ok so return false.
     return JNI_FALSE;
   } else {
--- a/src/hotspot/share/logging/logTag.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/logging/logTag.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -121,6 +121,7 @@
   LOG_TAG(safepoint) \
   LOG_TAG(scavenge) \
   LOG_TAG(scrub) \
+  LOG_TAG(smr) \
   LOG_TAG(stacktrace) \
   LOG_TAG(stackwalk) \
   LOG_TAG(start) \
--- a/src/hotspot/share/memory/universe.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/memory/universe.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -687,6 +687,10 @@
 
   Metaspace::global_initialize();
 
+  // Initialize performance counters for metaspaces
+  MetaspaceCounters::initialize_performance_counters();
+  CompressedClassSpaceCounters::initialize_performance_counters();
+
   AOTLoader::universe_init();
 
   // Checks 'AfterMemoryInit' constraints.
@@ -1085,10 +1089,6 @@
   // ("weak") refs processing infrastructure initialization
   Universe::heap()->post_initialize();
 
-  // Initialize performance counters for metaspaces
-  MetaspaceCounters::initialize_performance_counters();
-  CompressedClassSpaceCounters::initialize_performance_counters();
-
   MemoryService::add_metaspace_memory_pools();
 
   MemoryService::set_universe_heap(Universe::heap());
--- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -71,10 +71,15 @@
         Devirtualizer<nv>::do_klass(closure, klass);
       }
     } else {
-      // If klass is NULL then this a mirror for a primitive type.
-      // We don't have to follow them, since they are handled as strong
-      // roots in Universe::oops_do.
-      assert(java_lang_Class::is_primitive(obj), "Sanity check");
+      // We would like to assert here (as below) that if klass has been NULL, then
+      // this has been a mirror for a primitive type that we do not need to follow
+      // as they are always strong roots.
+      // However, we might get across a klass that just changed during CMS concurrent
+      // marking if allocation occurred in the old generation.
+      // This is benign here, as we keep alive all CLDs that were loaded during the
+      // CMS concurrent phase in the class loading, i.e. they will be iterated over
+      // and kept alive during remark.
+      // assert(java_lang_Class::is_primitive(obj), "Sanity check");
     }
   }
 
--- a/src/hotspot/share/opto/bytecodeInfo.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/opto/bytecodeInfo.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -480,6 +480,7 @@
   if ( callee->is_abstract())                   return "abstract method";
   if (!callee->has_balanced_monitors())         return "not compilable (unbalanced monitors)";
   if ( callee->get_flow_analysis()->failing())  return "not compilable (flow analysis failed)";
+  if (!callee->can_be_parsed())                 return "cannot be parsed";
   return NULL;
 }
 
--- a/src/hotspot/share/opto/idealGraphPrinter.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/opto/idealGraphPrinter.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, 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 "opto/machnode.hpp"
 #include "opto/parse.hpp"
 #include "runtime/threadCritical.hpp"
+#include "runtime/threadSMR.hpp"
 
 #ifndef PRODUCT
 
@@ -91,8 +92,7 @@
 }
 
 void IdealGraphPrinter::clean_up() {
-  JavaThread *p;
-  for (p = Threads::first(); p; p = p->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *p = jtiwh.next(); ) {
     if (p->is_Compiler_thread()) {
       CompilerThread *c = (CompilerThread *)p;
       IdealGraphPrinter *printer = c->ideal_graph_printer();
--- a/src/hotspot/share/prims/jni.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jni.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -4119,7 +4119,7 @@
   thread->initialize_thread_current();
 
   if (!os::create_attached_thread(thread)) {
-    delete thread;
+    thread->smr_delete();
     return JNI_ERR;
   }
   // Enable stack overflow checks
@@ -4250,7 +4250,7 @@
   // (platform-dependent) methods where we do alternate stack
   // maintenance work?)
   thread->exit(false, JavaThread::jni_detach);
-  delete thread;
+  thread->smr_delete();
 
   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(JNI_OK);
   return JNI_OK;
--- a/src/hotspot/share/prims/jvm.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvm.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -66,6 +66,7 @@
 #include "runtime/perfData.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vm_operations.hpp"
 #include "runtime/vm_version.hpp"
@@ -2737,16 +2738,12 @@
 
 // java.lang.Thread //////////////////////////////////////////////////////////////////////////////
 
-// In most of the JVM Thread support functions we need to be sure to lock the Threads_lock
-// to prevent the target thread from exiting after we have a pointer to the C++ Thread or
-// OSThread objects.  The exception to this rule is when the target object is the thread
-// doing the operation, in which case we know that the thread won't exit until the
-// operation is done (all exits being voluntary).  There are a few cases where it is
-// rather silly to do operations on yourself, like resuming yourself or asking whether
-// you are alive.  While these can still happen, they are not subject to deadlocks if
-// the lock is held while the operation occurs (this is not the case for suspend, for
-// instance), and are very unlikely.  Because IsAlive needs to be fast and its
-// implementation is local to this file, we always lock Threads_lock for that one.
+// In most of the JVM thread support functions we need to access the
+// thread through a ThreadsListHandle to prevent it from exiting and
+// being reclaimed while we try to operate on it. The exceptions to this
+// rule are when operating on the current thread, or if the monitor of
+// the target java.lang.Thread is locked at the Java level - in both
+// cases the target cannot exit.
 
 static void thread_entry(JavaThread* thread, TRAPS) {
   HandleMark hm(THREAD);
@@ -2821,7 +2818,7 @@
 
   if (native_thread->osthread() == NULL) {
     // No one should hold a reference to the 'native_thread'.
-    delete native_thread;
+    native_thread->smr_delete();
     if (JvmtiExport::should_post_resource_exhausted()) {
       JvmtiExport::post_resource_exhausted(
         JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,
@@ -2835,41 +2832,45 @@
 
 JVM_END
 
+
 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints
 // before the quasi-asynchronous exception is delivered.  This is a little obtrusive,
 // but is thought to be reliable and simple. In the case, where the receiver is the
-// same thread as the sender, no safepoint is needed.
+// same thread as the sender, no VM_Operation is needed.
 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))
   JVMWrapper("JVM_StopThread");
 
+  // A nested ThreadsListHandle will grab the Threads_lock so create
+  // tlh before we resolve throwable.
+  ThreadsListHandle tlh(thread);
   oop java_throwable = JNIHandles::resolve(throwable);
   if (java_throwable == NULL) {
     THROW(vmSymbols::java_lang_NullPointerException());
   }
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  JavaThread* receiver = java_lang_Thread::thread(java_thread);
-  Events::log_exception(JavaThread::current(),
+  oop java_thread = NULL;
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);
+  Events::log_exception(thread,
                         "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",
                         p2i(receiver), p2i((address)java_thread), p2i(throwable));
-  // First check if thread is alive
-  if (receiver != NULL) {
-    // Check if exception is getting thrown at self (use oop equality, since the
-    // target object might exit)
-    if (java_thread == thread->threadObj()) {
+
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    if (thread == receiver) {
+      // Exception is getting thrown at self so no VM_Operation needed.
       THROW_OOP(java_throwable);
     } else {
-      // Enques a VM_Operation to stop all threads and then deliver the exception...
-      Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
+      // Use a VM_Operation to throw the exception.
+      Thread::send_async_exception(java_thread, java_throwable);
     }
-  }
-  else {
+  } else {
     // Either:
     // - target thread has not been started before being stopped, or
     // - target thread already terminated
     // We could read the threadStatus to determine which case it is
     // but that is overkill as it doesn't matter. We must set the
     // stillborn flag for the first case, and if the thread has already
-    // exited setting this flag has no affect
+    // exited setting this flag has no effect.
     java_lang_Thread::set_stillborn(java_thread);
   }
 JVM_END
@@ -2885,12 +2886,12 @@
 
 JVM_ENTRY(void, JVM_SuspendThread(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_SuspendThread");
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  JavaThread* receiver = java_lang_Thread::thread(java_thread);
-
-  if (receiver != NULL) {
-    // thread has run and has not exited (still on threads list)
-
+
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
     {
       MutexLockerEx ml(receiver->SR_lock(), Mutex::_no_safepoint_check_flag);
       if (receiver->is_external_suspend()) {
@@ -2922,30 +2923,49 @@
 
 JVM_ENTRY(void, JVM_ResumeThread(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_ResumeThread");
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate.
-  // We need to *always* get the threads lock here, since this operation cannot be allowed during
-  // a safepoint. The safepoint code relies on suspending a thread to examine its state. If other
-  // threads randomly resumes threads, then a thread might not be suspended when the safepoint code
-  // looks at it.
-  MutexLocker ml(Threads_lock);
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr != NULL) {
-    // the thread has run and is not in the process of exiting
-    thr->java_resume();
+
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+
+    // This is the original comment for this Threads_lock grab:
+    //   We need to *always* get the threads lock here, since this operation cannot be allowed during
+    //   a safepoint. The safepoint code relies on suspending a thread to examine its state. If other
+    //   threads randomly resumes threads, then a thread might not be suspended when the safepoint code
+    //   looks at it.
+    //
+    // The above comment dates back to when we had both internal and
+    // external suspend APIs that shared a common underlying mechanism.
+    // External suspend is now entirely cooperative and doesn't share
+    // anything with internal suspend. That said, there are some
+    // assumptions in the VM that an external resume grabs the
+    // Threads_lock. We can't drop the Threads_lock grab here until we
+    // resolve the assumptions that exist elsewhere.
+    //
+    MutexLocker ml(Threads_lock);
+    receiver->java_resume();
   }
 JVM_END
 
 
 JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
   JVMWrapper("JVM_SetThreadPriority");
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  MutexLocker ml(Threads_lock);
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
+
+  ThreadsListHandle tlh(thread);
+  oop java_thread = NULL;
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, &java_thread);
   java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
-  JavaThread* thr = java_lang_Thread::thread(java_thread);
-  if (thr != NULL) {                  // Thread not yet started; priority pushed down when it is
-    Thread::set_priority(thr, (ThreadPriority)prio);
+
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    Thread::set_priority(receiver, (ThreadPriority)prio);
   }
+  // Implied else: If the JavaThread hasn't started yet, then the
+  // priority set in the java.lang.Thread object above will be pushed
+  // down when it does start.
 JVM_END
 
 
@@ -3016,67 +3036,39 @@
 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_CountStackFrames");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  bool throw_illegal_thread_state = false;
+  uint32_t debug_bits = 0;
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
   int count = 0;
-
-  {
-    MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-    // We need to re-resolve the java_thread, since a GC might have happened during the
-    // acquire of the lock
-    JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-
-    if (thr == NULL) {
-      // do nothing
-    } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {
-      // Check whether this java thread has been suspended already. If not, throws
-      // IllegalThreadStateException. We defer to throw that exception until
-      // Threads_lock is released since loading exception class has to leave VM.
-      // The correct way to test a thread is actually suspended is
-      // wait_for_ext_suspend_completion(), but we can't call that while holding
-      // the Threads_lock. The above tests are sufficient for our purposes
-      // provided the walkability of the stack is stable - which it isn't
-      // 100% but close enough for most practical purposes.
-      throw_illegal_thread_state = true;
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    if (receiver->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
+      // Count all java activation, i.e., number of vframes.
+      for (vframeStream vfst(receiver); !vfst.at_end(); vfst.next()) {
+        // Native frames are not counted.
+        if (!vfst.method()->is_native()) count++;
+      }
     } else {
-      // Count all java activation, i.e., number of vframes
-      for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {
-        // Native frames are not counted
-        if (!vfst.method()->is_native()) count++;
-       }
+      THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
+                  "this thread is not suspended");
     }
   }
-
-  if (throw_illegal_thread_state) {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalThreadStateException(),
-                "this thread is not suspended");
-  }
+  // Implied else: if JavaThread is not alive simply return a count of 0.
+
   return count;
 JVM_END
 
-// Consider: A better way to implement JVM_Interrupt() is to acquire
-// Threads_lock to resolve the jthread into a Thread pointer, fetch
-// Thread->platformevent, Thread->native_thr, Thread->parker, etc.,
-// drop Threads_lock, and the perform the unpark() and thr_kill() operations
-// outside the critical section.  Threads_lock is hot so we want to minimize
-// the hold-time.  A cleaner interface would be to decompose interrupt into
-// two steps.  The 1st phase, performed under Threads_lock, would return
-// a closure that'd be invoked after Threads_lock was dropped.
-// This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and
-// admit spurious wakeups.
 
 JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
   JVMWrapper("JVM_Interrupt");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr != NULL) {
-    Thread::interrupt(thr);
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    Thread::interrupt(receiver);
   }
 JVM_END
 
@@ -3084,16 +3076,14 @@
 JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
   JVMWrapper("JVM_IsInterrupted");
 
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  oop java_thread = JNIHandles::resolve_non_null(jthread);
-  MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-  JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
-  if (thr == NULL) {
+  ThreadsListHandle tlh(thread);
+  JavaThread* receiver = NULL;
+  bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
+  if (is_alive) {
+    // jthread refers to a live JavaThread.
+    return (jboolean) Thread::is_interrupted(receiver, clear_interrupted != 0);
+  } else {
     return JNI_FALSE;
-  } else {
-    return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
   }
 JVM_END
 
@@ -3122,14 +3112,16 @@
 
 JVM_ENTRY(void, JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring name))
   JVMWrapper("JVM_SetNativeThreadName");
-  ResourceMark rm(THREAD);
+
+  // We don't use a ThreadsListHandle here because the current thread
+  // must be alive.
   oop java_thread = JNIHandles::resolve_non_null(jthread);
   JavaThread* thr = java_lang_Thread::thread(java_thread);
-  // Thread naming only supported for the current thread, doesn't work for
-  // target threads.
-  if (Thread::current() == thr && !thr->has_attached_via_jni()) {
+  if (thread == thr && !thr->has_attached_via_jni()) {
+    // Thread naming is only supported for the current thread and
     // we don't set the name of an attached thread to avoid stepping
-    // on other programs
+    // on other programs.
+    ResourceMark rm(thread);
     const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
     os::set_native_thread_name(thread_name);
   }
@@ -3671,6 +3663,8 @@
     thread_handle_array->append(h);
   }
 
+  // The JavaThread references in thread_handle_array are validated
+  // in VM_ThreadDump::doit().
   Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);
   return (jobjectArray)JNIHandles::make_local(env, stacktraces());
 
--- a/src/hotspot/share/prims/jvmtiEnter.xsl	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnter.xsl	Mon Nov 27 17:04:45 2017 +0000
@@ -45,6 +45,7 @@
 # include "prims/jvmtiEnter.hpp"
 # include "prims/jvmtiRawMonitor.hpp"
 # include "prims/jvmtiUtil.hpp"
+# include "runtime/threadSMR.hpp"
 
 </xsl:text>
 
@@ -769,47 +770,27 @@
 
 <xsl:template match="jthread" mode="dochecksbody">
   <xsl:param name="name"/>
-    <xsl:text>    oop thread_oop = JNIHandles::resolve_external_guard(</xsl:text>
+    <xsl:text>    err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), </xsl:text>
     <xsl:value-of select="$name"/>
-    <xsl:text>);
-    if (thread_oop == NULL) {
+    <xsl:text>, &amp;java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
 </xsl:text>
     <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = " PTR_FORMAT "</xsl:with-param>
+      <xsl:with-param name="err">err</xsl:with-param>
+      <xsl:with-param name="comment"> - jthread did not convert to a JavaThread - jthread = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
     }
-    if (!thread_oop-&gt;is_a(SystemDictionary::Thread_klass())) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param>
-      <xsl:with-param name="comment"> - oop is not a thread - jthread = " PTR_FORMAT "</xsl:with-param>
-      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
-    </xsl:apply-templates>
-    <xsl:text>
-    }
-    java_thread = java_lang_Thread::thread(thread_oop); 
-    if (java_thread == NULL) {
-</xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
-      <xsl:with-param name="err">
-        <xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text>
-      </xsl:with-param>
-      <xsl:with-param name="comment"> - not a Java thread - jthread = " PTR_FORMAT "</xsl:with-param>
-      <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
-    </xsl:apply-templates>
-    <xsl:text>
-    }
-</xsl:text>  
 </xsl:template>
 
 <xsl:template match="jthread" mode="dochecks">
   <xsl:param name="name"/>
   <!-- If we convert and test threads -->
   <xsl:if test="count(@impl)=0 or not(contains(@impl,'noconvert'))">
-    <xsl:text>  JavaThread* java_thread;
+    <xsl:text>  JavaThread* java_thread = NULL;
+  ThreadsListHandle tlh(this_thread);
 </xsl:text>
     <xsl:choose>
       <xsl:when test="count(@null)=0">
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -62,6 +62,7 @@
 #include "runtime/reflectionUtils.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timerTrace.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
@@ -162,7 +163,6 @@
     *data_ptr = (state == NULL) ? NULL :
       state->env_thread_state(this)->get_agent_thread_local_storage_data();
   } else {
-
     // jvmti_GetThreadLocalStorage is "in native" and doesn't transition
     // the thread to _thread_in_vm. However, when the TLS for a thread
     // other than the current thread is required we need to transition
@@ -172,17 +172,13 @@
     VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
     debug_only(VMNativeEntryWrapper __vew;)
 
-    oop thread_oop = JNIHandles::resolve_external_guard(thread);
-    if (thread_oop == NULL) {
-      return JVMTI_ERROR_INVALID_THREAD;
+    JavaThread* java_thread = NULL;
+    ThreadsListHandle tlh(current_thread);
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      return err;
     }
-    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      return JVMTI_ERROR_INVALID_THREAD;
-    }
-    JavaThread* java_thread = java_lang_Thread::thread(thread_oop);
-    if (java_thread == NULL) {
-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
+
     JvmtiThreadState* state = java_thread->jvmti_thread_state();
     *data_ptr = (state == NULL) ? NULL :
       state->env_thread_state(this)->get_agent_thread_local_storage_data();
@@ -518,43 +514,61 @@
 // event_thread - NULL is a valid value, must be checked
 jvmtiError
 JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread,   ...) {
-  JavaThread* java_thread = NULL;
-  if (event_thread != NULL) {
-    oop thread_oop = JNIHandles::resolve_external_guard(event_thread);
-    if (thread_oop == NULL) {
-      return JVMTI_ERROR_INVALID_THREAD;
+  if (event_thread == NULL) {
+    // Can be called at Agent_OnLoad() time with event_thread == NULL
+    // when Thread::current() does not work yet so we cannot create a
+    // ThreadsListHandle that is common to both thread-specific and
+    // global code paths.
+
+    // event_type must be valid
+    if (!JvmtiEventController::is_valid_event_type(event_type)) {
+      return JVMTI_ERROR_INVALID_EVENT_TYPE;
     }
-    if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      return JVMTI_ERROR_INVALID_THREAD;
+
+    bool enabled = (mode == JVMTI_ENABLE);
+
+    // assure that needed capabilities are present
+    if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
+      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
     }
-    java_thread = java_lang_Thread::thread(thread_oop);
-    if (java_thread == NULL) {
-      return JVMTI_ERROR_THREAD_NOT_ALIVE;
+
+    if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
+      record_class_file_load_hook_enabled();
     }
+    JvmtiEventController::set_user_enabled(this, (JavaThread*) NULL, event_type, enabled);
+  } else {
+    // We have a specified event_thread.
+
+    JavaThread* java_thread = NULL;
+    ThreadsListHandle tlh;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), event_thread, &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      return err;
+    }
+
+    // event_type must be valid
+    if (!JvmtiEventController::is_valid_event_type(event_type)) {
+      return JVMTI_ERROR_INVALID_EVENT_TYPE;
+    }
+
+    // global events cannot be controlled at thread level.
+    if (JvmtiEventController::is_global_event(event_type)) {
+      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+    }
+
+    bool enabled = (mode == JVMTI_ENABLE);
+
+    // assure that needed capabilities are present
+    if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
+      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+    }
+
+    if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
+      record_class_file_load_hook_enabled();
+    }
+    JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
   }
 
-  // event_type must be valid
-  if (!JvmtiEventController::is_valid_event_type(event_type)) {
-    return JVMTI_ERROR_INVALID_EVENT_TYPE;
-  }
-
-  // global events cannot be controlled at thread level.
-  if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) {
-    return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-  }
-
-  bool enabled = (mode == JVMTI_ENABLE);
-
-  // assure that needed capabilities are present
-  if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
-    return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-  }
-
-  if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
-    record_class_file_load_hook_enabled();
-  }
-  JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
-
   return JVMTI_ERROR_NONE;
 } /* end SetEventNotificationMode */
 
@@ -817,35 +831,45 @@
 // thread_state_ptr - pre-checked for NULL
 jvmtiError
 JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {
-  jint state;
-  oop thread_oop;
-  JavaThread* thr;
+  JavaThread* current_thread = JavaThread::current();
+  JavaThread* java_thread = NULL;
+  oop thread_oop = NULL;
+  ThreadsListHandle tlh(current_thread);
 
   if (thread == NULL) {
-    thread_oop = JavaThread::current()->threadObj();
+    java_thread = current_thread;
+    thread_oop = java_thread->threadObj();
+
+    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+      return JVMTI_ERROR_INVALID_THREAD;
+    }
   } else {
-    thread_oop = JNIHandles::resolve_external_guard(thread);
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        return err;
+      }
+      // We have a valid thread_oop so we can return some thread state.
+    }
   }
 
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
-    return JVMTI_ERROR_INVALID_THREAD;
-  }
-
   // get most state bits
-  state = (jint)java_lang_Thread::get_thread_status(thread_oop);
-
-  // add more state bits
-  thr = java_lang_Thread::thread(thread_oop);
-  if (thr != NULL) {
-    JavaThreadState jts = thr->thread_state();
-
-    if (thr->is_being_ext_suspended()) {
+  jint state = (jint)java_lang_Thread::get_thread_status(thread_oop);
+
+  if (java_thread != NULL) {
+    // We have a JavaThread* so add more state bits.
+    JavaThreadState jts = java_thread->thread_state();
+
+    if (java_thread->is_being_ext_suspended()) {
       state |= JVMTI_THREAD_STATE_SUSPENDED;
     }
     if (jts == _thread_in_native) {
       state |= JVMTI_THREAD_STATE_IN_NATIVE;
     }
-    OSThread* osThread = thr->osthread();
+    OSThread* osThread = java_thread->osthread();
     if (osThread != NULL && osThread->interrupted()) {
       state |= JVMTI_THREAD_STATE_INTERRUPTED;
     }
@@ -891,7 +915,6 @@
     thread_objs[i] = Handle(tle.get_threadObj(i));
   }
 
-  // have to make global handles outside of Threads_lock
   jthread *jthreads  = new_jthreadArray(nthreads, thread_objs);
   NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);
 
@@ -935,19 +958,12 @@
 jvmtiError
 JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
   int needSafepoint = 0;  // > 0 if we need a safepoint
+  ThreadsListHandle tlh;
   for (int i = 0; i < request_count; i++) {
-    JavaThread *java_thread = get_JavaThread(request_list[i]);
-    if (java_thread == NULL) {
-      results[i] = JVMTI_ERROR_INVALID_THREAD;
-      continue;
-    }
-    // the thread has not yet run or has exited (not on threads list)
-    if (java_thread->threadObj() == NULL) {
-      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
-      continue;
-    }
-    if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
-      results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
+    JavaThread *java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      results[i] = err;
       continue;
     }
     // don't allow hidden thread suspend request.
@@ -1018,10 +1034,12 @@
 // results - pre-checked for NULL
 jvmtiError
 JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
+  ThreadsListHandle tlh;
   for (int i = 0; i < request_count; i++) {
-    JavaThread *java_thread = get_JavaThread(request_list[i]);
-    if (java_thread == NULL) {
-      results[i] = JVMTI_ERROR_INVALID_THREAD;
+    JavaThread* java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
+    if (err != JVMTI_ERROR_NONE) {
+      results[i] = err;
       continue;
     }
     // don't allow hidden thread resume request.
@@ -1039,7 +1057,7 @@
       continue;
     }
 
-    results[i] = JVMTI_ERROR_NONE;  // indicate successful suspend
+    results[i] = JVMTI_ERROR_NONE;  // indicate successful resume
   }
   // per-thread resume results returned via results parameter
   return JVMTI_ERROR_NONE;
@@ -1064,20 +1082,14 @@
 // thread - NOT pre-checked
 jvmtiError
 JvmtiEnv::InterruptThread(jthread thread) {
-  oop thread_oop = JNIHandles::resolve_external_guard(thread);
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
-    return JVMTI_ERROR_INVALID_THREAD;
-
+  // TODO: this is very similar to JVM_Interrupt(); share code in future
   JavaThread* current_thread  = JavaThread::current();
-
-  // Todo: this is a duplicate of JVM_Interrupt; share code in future
-  // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
-  MutexLockerEx ml(current_thread->threadObj() == thread_oop ? NULL : Threads_lock);
-  // We need to re-resolve the java_thread, since a GC might have happened during the
-  // acquire of the lock
-
-  JavaThread* java_thread = java_lang_Thread::thread(JNIHandles::resolve_external_guard(thread));
-  NULL_CHECK(java_thread, JVMTI_ERROR_THREAD_NOT_ALIVE);
+  JavaThread* java_thread = NULL;
+  ThreadsListHandle tlh(current_thread);
+  jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
+  if (err != JVMTI_ERROR_NONE) {
+    return err;
+  }
 
   Thread::interrupt(java_thread);
 
@@ -1094,16 +1106,28 @@
   HandleMark hm;
 
   JavaThread* current_thread = JavaThread::current();
+  ThreadsListHandle tlh(current_thread);
 
   // if thread is NULL the current thread is used
-  oop thread_oop;
+  oop thread_oop = NULL;
   if (thread == NULL) {
     thread_oop = current_thread->threadObj();
+    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+      return JVMTI_ERROR_INVALID_THREAD;
+    }
   } else {
-    thread_oop = JNIHandles::resolve_external_guard(thread);
+    JavaThread* java_thread = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        return err;
+      }
+      // We have a valid thread_oop so we can return some thread info.
+    }
   }
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass()))
-    return JVMTI_ERROR_INVALID_THREAD;
 
   Handle thread_obj(current_thread, thread_oop);
   Handle name;
@@ -1272,17 +1296,31 @@
 // arg - NULL is a valid value, must be checked
 jvmtiError
 JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
-  oop thread_oop = JNIHandles::resolve_external_guard(thread);
-  if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
+  JavaThread* current_thread = JavaThread::current();
+
+  JavaThread* java_thread = NULL;
+  oop thread_oop = NULL;
+  ThreadsListHandle tlh(current_thread);
+  jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
+  if (err != JVMTI_ERROR_NONE) {
+    // We got an error code so we don't have a JavaThread *, but
+    // only return an error from here if we didn't get a valid
+    // thread_oop.
+    if (thread_oop == NULL) {
+      return err;
+    }
+    // We have a valid thread_oop.
+  }
+
+  if (java_thread != NULL) {
+    // 'thread' refers to an existing JavaThread.
     return JVMTI_ERROR_INVALID_THREAD;
   }
+
   if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
     return JVMTI_ERROR_INVALID_PRIORITY;
   }
 
-  //Thread-self
-  JavaThread* current_thread = JavaThread::current();
-
   Handle thread_hndl(current_thread, thread_oop);
   {
     MutexLocker mu(Threads_lock); // grab Threads_lock
@@ -1292,7 +1330,9 @@
     // At this point it may be possible that no osthread was created for the
     // JavaThread due to lack of memory.
     if (new_thread == NULL || new_thread->osthread() == NULL) {
-      if (new_thread) delete new_thread;
+      if (new_thread != NULL) {
+        new_thread->smr_delete();
+      }
       return JVMTI_ERROR_OUT_OF_MEMORY;
     }
 
@@ -1394,36 +1434,53 @@
   int ngroups = 0;
   int hidden_threads = 0;
 
-  ResourceMark rm;
-  HandleMark hm;
+  ResourceMark rm(current_thread);
+  HandleMark hm(current_thread);
 
   Handle group_hdl(current_thread, group_obj);
 
-  { MutexLocker mu(Threads_lock);
+  { // Cannot allow thread or group counts to change.
+    MutexLocker mu(Threads_lock);
 
     nthreads = java_lang_ThreadGroup::nthreads(group_hdl());
     ngroups  = java_lang_ThreadGroup::ngroups(group_hdl());
 
     if (nthreads > 0) {
+      ThreadsListHandle tlh(current_thread);
       objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());
       assert(nthreads <= threads->length(), "too many threads");
       thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);
       for (int i=0, j=0; i<nthreads; i++) {
         oop thread_obj = threads->obj_at(i);
         assert(thread_obj != NULL, "thread_obj is NULL");
-        JavaThread *javathread = java_lang_Thread::thread(thread_obj);
-        // Filter out hidden java threads.
-        if (javathread != NULL && javathread->is_hidden_from_external_view()) {
-          hidden_threads++;
-          continue;
+        JavaThread *java_thread = NULL;
+        jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &java_thread);
+        if (err == JVMTI_ERROR_NONE) {
+          // Have a valid JavaThread*.
+          if (java_thread->is_hidden_from_external_view()) {
+            // Filter out hidden java threads.
+            hidden_threads++;
+            continue;
+          }
+        } else {
+          // We couldn't convert thread_obj into a JavaThread*.
+          if (err == JVMTI_ERROR_INVALID_THREAD) {
+            // The thread_obj does not refer to a java.lang.Thread object
+            // so skip it.
+            hidden_threads++;
+            continue;
+          }
+          // We have a valid thread_obj, but no JavaThread*; the caller
+          // can still have limited use for the thread_obj.
         }
         thread_objs[j++] = Handle(current_thread, thread_obj);
       }
       nthreads -= hidden_threads;
-    }
+    } // ThreadsListHandle is destroyed here.
+
     if (ngroups > 0) {
       objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());
-      assert(ngroups <= groups->length(), "too many threads");
+      assert(ngroups <= groups->length(), "too many groups");
       group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);
       for (int i=0; i<ngroups; i++) {
         oop group_obj = groups->obj_at(i);
@@ -1556,7 +1613,7 @@
   }
 
   // Check if java_thread is fully suspended
-  if (!is_thread_fully_suspended(java_thread, true /* wait for suspend completion */, &debug_bits)) {
+  if (!java_thread->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
     return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
   // Check to see if a PopFrame was already in progress
@@ -1686,8 +1743,8 @@
     return JVMTI_ERROR_THREAD_NOT_ALIVE;
   }
 
-  if (!JvmtiEnv::is_thread_fully_suspended(java_thread, true, &debug_bits)) {
-      return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
+  if (!java_thread->is_thread_fully_suspended(true, &debug_bits)) {
+    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
 
   if (TraceJVMTICalls) {
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -44,6 +44,7 @@
 #include "runtime/objectMonitor.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vmThread.hpp"
@@ -487,37 +488,6 @@
   }
 }
 
-// Called from JVMTI entry points which perform stack walking. If the
-// associated JavaThread is the current thread, then wait_for_suspend
-// is not used. Otherwise, it determines if we should wait for the
-// "other" thread to complete external suspension. (NOTE: in future
-// releases the suspension mechanism should be reimplemented so this
-// is not necessary.)
-//
-bool
-JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) {
-  // "other" threads require special handling
-  if (thr != JavaThread::current()) {
-    if (wait_for_suspend) {
-      // We are allowed to wait for the external suspend to complete
-      // so give the other thread a chance to get suspended.
-      if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount,
-          SuspendRetryDelay, bits)) {
-        // didn't make it so let the caller know
-        return false;
-      }
-    }
-    // We aren't allowed to wait for the external suspend to complete
-    // so if the other thread isn't externally suspended we need to
-    // let the caller know.
-    else if (!thr->is_ext_suspend_completed_with_lock(bits)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 
 // In the fullness of time, all users of the method should instead
 // directly use allocate, besides being cleaner and faster, this will
@@ -560,19 +530,6 @@
   return (jthreadGroup *) new_jobjectArray(length,handles);
 }
 
-
-JavaThread *
-JvmtiEnvBase::get_JavaThread(jthread jni_thread) {
-  oop t = JNIHandles::resolve_external_guard(jni_thread);
-  if (t == NULL || !t->is_a(SystemDictionary::Thread_klass())) {
-    return NULL;
-  }
-  // The following returns NULL if the thread has not yet run or is in
-  // process of exiting
-  return java_lang_Thread::thread(t);
-}
-
-
 // return the vframe on the specified thread and depth, NULL if no such frame
 vframe*
 JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
@@ -670,7 +627,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   oop obj = NULL;
   ObjectMonitor *mon = java_thread->current_waiting_monitor();
@@ -709,7 +666,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
 
   if (java_thread->has_last_Java_frame()) {
@@ -831,7 +788,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   int count = 0;
   if (java_thread->has_last_Java_frame()) {
@@ -914,7 +871,7 @@
   uint32_t debug_bits = 0;
 #endif
   assert((SafepointSynchronize::is_at_safepoint() ||
-          is_thread_fully_suspended(java_thread, false, &debug_bits)),
+          java_thread->is_thread_fully_suspended(false, &debug_bits)),
          "at safepoint or target thread is suspended");
   Thread* current_thread = Thread::current();
   ResourceMark rm(current_thread);
@@ -976,7 +933,7 @@
   // first derive the object's owner and entry_count (if any)
   {
     // Revoke any biases before querying the mark word
-    if (SafepointSynchronize::is_at_safepoint()) {
+    if (at_safepoint) {
       BiasedLocking::revoke_at_safepoint(hobj);
     } else {
       BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
@@ -1008,11 +965,11 @@
     }
 
     if (owner != NULL) {
+      // Use current thread since function can be called from a
+      // JavaThread or the VMThread.
+      ThreadsListHandle tlh;
       // This monitor is owned so we have to find the owning JavaThread.
-      // Since owning_thread_from_monitor_owner() grabs a lock, GC can
-      // move our object at this point. However, our owner value is safe
-      // since it is either the Lock word on a stack or a JavaThread *.
-      owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
+      owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
       // Cannot assume (owning_thread != NULL) here because this function
       // may not have been called at a safepoint and the owning_thread
       // might not be suspended.
@@ -1021,7 +978,7 @@
         // or it has to be suspended. Any of these conditions will prevent both
         // contending and waiting threads from modifying the state of
         // the monitor.
-        if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
+        if (!at_safepoint && !owning_thread->is_thread_fully_suspended(true, &debug_bits)) {
           // Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED
           // will not make it back to the JVM/TI agent. The error code will
           // get intercepted in JvmtiEnv::GetObjectMonitorUsage() which
@@ -1033,7 +990,7 @@
         ret.owner = (jthread)jni_reference(calling_thread, th);
       }
       // implied else: no owner
-    }
+    } // ThreadsListHandle is destroyed here.
 
     if (owning_thread != NULL) {  // monitor is owned
       // The recursions field of a monitor does not reflect recursions
@@ -1084,13 +1041,15 @@
     if (ret.waiter_count > 0) {
       // we have contending and/or waiting threads
       HandleMark hm;
+      // Use current thread since function can be called from a
+      // JavaThread or the VMThread.
+      ThreadsListHandle tlh;
       if (nWant > 0) {
         // we have contending threads
         ResourceMark rm;
         // get_pending_threads returns only java thread so we do not need to
-        // check for  non java threads.
-        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(
-          nWant, (address)mon, !at_safepoint);
+        // check for non java threads.
+        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon);
         if (wantList->length() < nWant) {
           // robustness: the pending list has gotten smaller
           nWant = wantList->length();
@@ -1101,7 +1060,7 @@
           // thread could potentially change the state of the monitor by
           // entering it. The JVM/TI spec doesn't allow this.
           if (owning_thread == NULL && !at_safepoint &
-              !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) {
+              !pending_thread->is_thread_fully_suspended(true, &debug_bits)) {
             if (ret.owner != NULL) {
               destroy_jni_reference(calling_thread, ret.owner);
             }
@@ -1139,7 +1098,7 @@
           waiter = mon->next_waiter(waiter);
         }
       }
-    }
+    } // ThreadsListHandle is destroyed here.
 
     // Adjust count. nWant and nWait count values may be less than original.
     ret.waiter_count = nWant + nWait;
@@ -1291,14 +1250,23 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   ResourceMark rm;
+  ThreadsListHandle tlh;
   for (int i = 0; i < _thread_count; ++i) {
     jthread jt = _thread_list[i];
-    oop thread_oop = JNIHandles::resolve_external_guard(jt);
-    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) {
-      set_result(JVMTI_ERROR_INVALID_THREAD);
-      return;
+    JavaThread* java_thread = NULL;
+    oop thread_oop = NULL;
+    jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), jt, &java_thread, &thread_oop);
+    if (err != JVMTI_ERROR_NONE) {
+      // We got an error code so we don't have a JavaThread *, but
+      // only return an error from here if we didn't get a valid
+      // thread_oop.
+      if (thread_oop == NULL) {
+        set_result(err);
+        return;
+      }
+      // We have a valid thread_oop.
     }
-    fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop);
+    fill_frames(jt, java_thread, thread_oop);
   }
   allocate_and_fill_stacks(_thread_count);
 }
@@ -1309,7 +1277,7 @@
 
   ResourceMark rm;
   _final_thread_count = 0;
-  for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     oop thread_oop = jt->threadObj();
     if (thread_oop != NULL &&
         !jt->is_exiting() &&
@@ -1404,9 +1372,7 @@
   }
 
   // Check if java_thread is fully suspended
-  if (!is_thread_fully_suspended(java_thread,
-                                 true /* wait for suspend completion */,
-                                 &debug_bits)) {
+  if (!java_thread->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) {
     return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
 
@@ -1521,3 +1487,79 @@
   return JVMTI_ERROR_NONE;
 }
 
+void
+VM_UpdateForPopTopFrame::doit() {
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    _state->update_for_pop_top_frame();
+  } else {
+    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+}
+
+void
+VM_SetFramePop::doit() {
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    int frame_number = _state->count_frames() - _depth;
+    _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
+  } else {
+    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+}
+
+void
+VM_GetOwnedMonitorInfo::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
+                                                          _owned_monitors_list);
+  }
+}
+
+void
+VM_GetCurrentContendedMonitor::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
+  }
+}
+
+void
+VM_GetStackTrace::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
+                                                      _start_depth, _max_count,
+                                                      _frame_buffer, _count_ptr);
+  }
+}
+
+void
+VM_GetFrameCount::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  JavaThread* jt = _state->get_thread();
+  ThreadsListHandle tlh;
+  if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
+  }
+}
+
+void
+VM_GetFrameLocation::doit() {
+  _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+  ThreadsListHandle tlh;
+  if (_java_thread != NULL && tlh.includes(_java_thread)
+      && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
+    _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
+                                                        _method_ptr, _location_ptr);
+  }
+}
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -280,9 +280,6 @@
   jthread * new_jthreadArray(int length, Handle *handles);
   jthreadGroup * new_jthreadGroupArray(int length, Handle *handles);
 
-  // convert from JNIHandle to JavaThread *
-  JavaThread  * get_JavaThread(jthread jni_thread);
-
   // convert to a jni jclass from a non-null Klass*
   jclass get_jni_class_non_null(Klass* k);
 
@@ -297,11 +294,6 @@
  public:
   // get a field descriptor for the specified class and field
   static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
-  // test for suspend - most (all?) of these should go away
-  static bool is_thread_fully_suspended(JavaThread *thread,
-                                        bool wait_for_suspend,
-                                        uint32_t *bits);
-
 
   // JVMTI API helper functions which are called at safepoint or thread is suspended.
   jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
@@ -360,14 +352,7 @@
   }
   VMOp_Type type() const { return VMOp_UpdateForPopTopFrame; }
   jvmtiError result() { return _result; }
-  void doit() {
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      _state->update_for_pop_top_frame();
-    } else {
-      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
-  }
+  void doit();
 };
 
 // VM operation to set frame pop.
@@ -390,15 +375,7 @@
   bool allow_nested_vm_operations() const { return true; }
   VMOp_Type type() const { return VMOp_SetFramePop; }
   jvmtiError result() { return _result; }
-  void doit() {
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      int frame_number = _state->count_frames() - _depth;
-      _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
-    } else {
-      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    }
-  }
+  void doit();
 };
 
 
@@ -422,14 +399,7 @@
     _result = JVMTI_ERROR_NONE;
   }
   VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
-                                        && _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
-                                                            _owned_monitors_list);
-    }
-  }
+  void doit();
   jvmtiError result() { return _result; }
 };
 
@@ -476,13 +446,7 @@
   }
   VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
   jvmtiError result() { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
-        _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
-    }
-  }
+  void doit();
 };
 
 // VM operation to get stack trace at safepoint.
@@ -509,15 +473,7 @@
   }
   jvmtiError result() { return _result; }
   VMOp_Type type() const { return VMOp_GetStackTrace; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting()
-                                        && _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread,
-                                                        _start_depth, _max_count,
-                                                        _frame_buffer, _count_ptr);
-    }
-  }
+  void doit();
 };
 
 // forward declaration
@@ -607,13 +563,7 @@
   }
   VMOp_Type type() const { return VMOp_GetFrameCount; }
   jvmtiError result()    { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    JavaThread* jt = _state->get_thread();
-    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr);
-    }
-  }
+  void doit();
 };
 
 // VM operation to frame location at safepoint.
@@ -637,14 +587,7 @@
   }
   VMOp_Type type() const { return VMOp_GetFrameLocation; }
   jvmtiError result()    { return _result; }
-  void doit() {
-    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
-    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
-        _java_thread->threadObj() != NULL) {
-      _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth,
-                                                          _method_ptr, _location_ptr);
-    }
-  }
+  void doit();
 };
 
 
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vm_operations.hpp"
 
--- a/src/hotspot/share/prims/jvmtiEventController.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -33,7 +33,8 @@
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiThreadState.inline.hpp"
 #include "runtime/frame.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vmThread.hpp"
@@ -580,13 +581,10 @@
   // filtered events and there weren't last time
   if (    (any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) != 0 &&
       (was_any_env_thread_enabled & THREAD_FILTERED_EVENT_BITS) == 0) {
-    {
-      MutexLocker mu(Threads_lock);   //hold the Threads_lock for the iteration
-      for (JavaThread *tp = Threads::first(); tp != NULL; tp = tp->next()) {
-        // state_for_while_locked() makes tp->is_exiting() check
-        JvmtiThreadState::state_for_while_locked(tp);  // create the thread state if missing
-      }
-    }// release Threads_lock
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *tp = jtiwh.next(); ) {
+      // state_for_while_locked() makes tp->is_exiting() check
+      JvmtiThreadState::state_for_while_locked(tp);  // create the thread state if missing
+    }
   }
 
   // compute and set thread-filtered events
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -53,6 +53,7 @@
 #include "runtime/objectMonitor.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "services/serviceUtil.hpp"
 #include "utilities/macros.hpp"
@@ -721,6 +722,108 @@
   }
 }
 
+// Convert an external thread reference to a JavaThread found on the
+// specified ThreadsList. The ThreadsListHandle in the caller "protects"
+// the returned JavaThread *.
+//
+// If thread_oop_p is not NULL, then the caller wants to use the oop
+// after this call so the oop is returned. On success, *jt_pp is set
+// to the converted JavaThread * and JVMTI_ERROR_NONE is returned.
+// On error, returns various JVMTI_ERROR_* values.
+//
+jvmtiError
+JvmtiExport::cv_external_thread_to_JavaThread(ThreadsList * t_list,
+                                              jthread thread,
+                                              JavaThread ** jt_pp,
+                                              oop * thread_oop_p) {
+  assert(t_list != NULL, "must have a ThreadsList");
+  assert(jt_pp != NULL, "must have a return JavaThread pointer");
+  // thread_oop_p is optional so no assert()
+
+  oop thread_oop = JNIHandles::resolve_external_guard(thread);
+  if (thread_oop == NULL) {
+    // NULL jthread, GC'ed jthread or a bad JNI handle.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like an oop at this point.
+
+  if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
+    // The oop is not a java.lang.Thread.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like a java.lang.Thread oop at this point.
+
+  if (thread_oop_p != NULL) {
+    // Return the oop to the caller; the caller may still want
+    // the oop even if this function returns an error.
+    *thread_oop_p = thread_oop;
+  }
+
+  JavaThread * java_thread = java_lang_Thread::thread(thread_oop);
+  if (java_thread == NULL) {
+    // The java.lang.Thread does not contain a JavaThread * so it has
+    // not yet run or it has died.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+  // Looks like a live JavaThread at this point.
+
+  // We do not check the EnableThreadSMRExtraValidityChecks option
+  // for this includes() call because JVM/TI's spec is tighter.
+  if (!t_list->includes(java_thread)) {
+    // Not on the JavaThreads list so it is not alive.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+
+  // Return a live JavaThread that is "protected" by the
+  // ThreadsListHandle in the caller.
+  *jt_pp = java_thread;
+
+  return JVMTI_ERROR_NONE;
+}
+
+// Convert an oop to a JavaThread found on the specified ThreadsList.
+// The ThreadsListHandle in the caller "protects" the returned
+// JavaThread *.
+//
+// On success, *jt_pp is set to the converted JavaThread * and
+// JVMTI_ERROR_NONE is returned. On error, returns various
+// JVMTI_ERROR_* values.
+//
+jvmtiError
+JvmtiExport::cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,
+                                  JavaThread ** jt_pp) {
+  assert(t_list != NULL, "must have a ThreadsList");
+  assert(thread_oop != NULL, "must have an oop");
+  assert(jt_pp != NULL, "must have a return JavaThread pointer");
+
+  if (!thread_oop->is_a(SystemDictionary::Thread_klass())) {
+    // The oop is not a java.lang.Thread.
+    return JVMTI_ERROR_INVALID_THREAD;
+  }
+  // Looks like a java.lang.Thread oop at this point.
+
+  JavaThread * java_thread = java_lang_Thread::thread(thread_oop);
+  if (java_thread == NULL) {
+    // The java.lang.Thread does not contain a JavaThread * so it has
+    // not yet run or it has died.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+  // Looks like a live JavaThread at this point.
+
+  // We do not check the EnableThreadSMRExtraValidityChecks option
+  // for this includes() call because JVM/TI's spec is tighter.
+  if (!t_list->includes(java_thread)) {
+    // Not on the JavaThreads list so it is not alive.
+    return JVMTI_ERROR_THREAD_NOT_ALIVE;
+  }
+
+  // Return a live JavaThread that is "protected" by the
+  // ThreadsListHandle in the caller.
+  *jt_pp = java_thread;
+
+  return JVMTI_ERROR_NONE;
+}
+
 class JvmtiClassFileLoadHookPoster : public StackObj {
  private:
   Symbol*            _h_name;
@@ -2685,8 +2788,7 @@
     return;
   }
 
-  // Runs at safepoint. So no need to acquire Threads_lock.
-  for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jthr = jtiwh.next(); ) {
     JvmtiThreadState *state = jthr->jvmti_thread_state();
     if (state != NULL) {
       JvmtiVMObjectAllocEventCollector *collector;
--- a/src/hotspot/share/prims/jvmtiExport.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiExport.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -399,6 +399,14 @@
 
   // SetNativeMethodPrefix support
   static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(NULL);
+
+  // JavaThread lifecycle support:
+  static jvmtiError cv_external_thread_to_JavaThread(ThreadsList * t_list,
+                                                     jthread thread,
+                                                     JavaThread ** jt_pp,
+                                                     oop * thread_oop_p);
+  static jvmtiError cv_oop_to_JavaThread(ThreadsList * t_list, oop thread_oop,
+                                         JavaThread ** jt_pp);
 };
 
 // Support class used by JvmtiDynamicCodeEventCollector and others. It
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -46,6 +46,7 @@
 #include "runtime/serviceThread.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframe_hp.hpp"
 #include "runtime/vm_operations.hpp"
@@ -878,10 +879,9 @@
 
 void JvmtiSuspendControl::print() {
 #ifndef PRODUCT
-  MutexLocker mu(Threads_lock);
   LogStreamHandle(Trace, jvmti) log_stream;
   log_stream.print("Suspended Threads: [");
-  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
 #ifdef JVMTI_TRACE
     const char *name   = JvmtiTrace::safe_get_thread_name(thread);
 #else
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -43,6 +43,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
+#include "prims/jvmtiThreadState.inline.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "prims/methodComparator.hpp"
 #include "runtime/deoptimization.hpp"
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -45,6 +45,8 @@
 #include "runtime/mutex.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/reflectionUtils.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -3174,7 +3176,7 @@
 // stack to find all references and local JNI refs.
 inline bool VM_HeapWalkOperation::collect_stack_roots() {
   JNILocalRootsClosure blk;
-  for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     oop threadObj = thread->threadObj();
     if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
       // Collect the simple root for this thread before we
--- a/src/hotspot/share/prims/jvmtiThreadState.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiThreadState.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -336,34 +336,10 @@
 
   // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState
   // Can return NULL if JavaThread is exiting.
-  inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) {
-    assert(JvmtiThreadState_lock->is_locked(), "sanity check");
-
-    JvmtiThreadState *state = thread->jvmti_thread_state();
-    if (state == NULL) {
-      if (thread->is_exiting()) {
-        // don't add a JvmtiThreadState to a thread that is exiting
-        return NULL;
-      }
-
-      state = new JvmtiThreadState(thread);
-    }
-    return state;
-  }
-
+  static JvmtiThreadState *state_for_while_locked(JavaThread *thread);
   // retrieve or create JvmtiThreadState
   // Can return NULL if JavaThread is exiting.
-  inline static JvmtiThreadState *state_for(JavaThread *thread) {
-    JvmtiThreadState *state = thread->jvmti_thread_state();
-    if (state == NULL) {
-      MutexLocker mu(JvmtiThreadState_lock);
-      // check again with the lock held
-      state = state_for_while_locked(thread);
-    } else {
-      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
-    }
-    return state;
-  }
+  static JvmtiThreadState *state_for(JavaThread *thread);
 
   // JVMTI ForceEarlyReturn support
 
--- a/src/hotspot/share/prims/jvmtiThreadState.inline.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiThreadState.inline.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -68,4 +68,31 @@
   _head_env_thread_state = ets;
 }
 
+inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *thread) {
+  assert(JvmtiThreadState_lock->is_locked(), "sanity check");
+
+  JvmtiThreadState *state = thread->jvmti_thread_state();
+  if (state == NULL) {
+    if (thread->is_exiting()) {
+      // don't add a JvmtiThreadState to a thread that is exiting
+      return NULL;
+    }
+
+    state = new JvmtiThreadState(thread);
+  }
+  return state;
+}
+
+inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread) {
+  JvmtiThreadState *state = thread->jvmti_thread_state();
+  if (state == NULL) {
+    MutexLocker mu(JvmtiThreadState_lock);
+    // check again with the lock held
+    state = state_for_while_locked(thread);
+  } else {
+    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
+  }
+  return state;
+}
+
 #endif // SHARE_VM_PRIMS_JVMTITHREADSTATE_INLINE_HPP
--- a/src/hotspot/share/prims/perf.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/perf.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -30,7 +30,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
-#include "runtime/perfData.hpp"
+#include "runtime/perfData.inline.hpp"
 #include "runtime/perfMemory.hpp"
 
 /*
--- a/src/hotspot/share/prims/unsafe.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/unsafe.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -39,6 +39,8 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "runtime/reflection.hpp"
+#include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/threadService.hpp"
 #include "trace/tracing.hpp"
@@ -937,8 +939,12 @@
   Parker* p = NULL;
 
   if (jthread != NULL) {
-    oop java_thread = JNIHandles::resolve_non_null(jthread);
+    ThreadsListHandle tlh;
+    JavaThread* thr = NULL;
+    oop java_thread = NULL;
+    (void) tlh.cv_internal_thread_to_JavaThread(jthread, &thr, &java_thread);
     if (java_thread != NULL) {
+      // This is a valid oop.
       jlong lp = java_lang_Thread::park_event(java_thread);
       if (lp != 0) {
         // This cast is OK even though the jlong might have been read
@@ -946,22 +952,19 @@
         // always be zero anyway and the value set is always the same
         p = (Parker*)addr_from_java(lp);
       } else {
-        // Grab lock if apparently null or using older version of library
-        MutexLocker mu(Threads_lock);
-        java_thread = JNIHandles::resolve_non_null(jthread);
-
-        if (java_thread != NULL) {
-          JavaThread* thr = java_lang_Thread::thread(java_thread);
-          if (thr != NULL) {
-            p = thr->parker();
-            if (p != NULL) { // Bind to Java thread for next time.
-              java_lang_Thread::set_park_event(java_thread, addr_to_java(p));
-            }
+        // Not cached in the java.lang.Thread oop yet (could be an
+        // older version of library).
+        if (thr != NULL) {
+          // The JavaThread is alive.
+          p = thr->parker();
+          if (p != NULL) {
+            // Cache the Parker in the java.lang.Thread oop for next time.
+            java_lang_Thread::set_park_event(java_thread, addr_to_java(p));
           }
         }
       }
     }
-  }
+  } // ThreadsListHandle is destroyed here.
 
   if (p != NULL) {
     HOTSPOT_THREAD_UNPARK((uintptr_t) p);
--- a/src/hotspot/share/prims/whitebox.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/prims/whitebox.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -55,6 +55,7 @@
 #include "runtime/os.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
@@ -665,7 +666,7 @@
   int  result() const { return _result; }
 
   void doit() {
-    for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
       if (t->has_last_Java_frame()) {
         for (StackFrameStream fst(t, UseBiasedLocking); !fst.is_done(); fst.next()) {
           frame* f = fst.current();
--- a/src/hotspot/share/runtime/arguments.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/arguments.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -497,7 +497,7 @@
   SpecialFlag flag;
   if (lookup_special_flag(flag_name, flag)) {
     if (!flag.obsolete_in.is_undefined()) {
-      if (version_less_than(JDK_Version::current(), flag.expired_in)) {
+      if (!version_less_than(JDK_Version::current(), flag.obsolete_in)) {
         *version = flag.obsolete_in;
         return true;
       }
@@ -2152,12 +2152,7 @@
   // Check lower bounds of the code cache
   // Template Interpreter code is approximately 3X larger in debug builds.
   uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
-  if (InitialCodeCacheSize < (uintx)os::vm_page_size()) {
-    jio_fprintf(defaultStream::error_stream(),
-                "Invalid InitialCodeCacheSize=%dK. Must be at least %dK.\n", InitialCodeCacheSize/K,
-                os::vm_page_size()/K);
-    status = false;
-  } else if (ReservedCodeCacheSize < InitialCodeCacheSize) {
+  if (ReservedCodeCacheSize < InitialCodeCacheSize) {
     jio_fprintf(defaultStream::error_stream(),
                 "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n",
                 ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
@@ -2770,18 +2765,6 @@
       if (FLAG_SET_CMDLINE(intx, ThreadStackSize, value) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-    } else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) {
-      julong long_CodeCacheExpansionSize = 0;
-      ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size());
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                   "Invalid argument: %s. Must be at least %luK.\n", option->optionString,
-                   os::vm_page_size()/K);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
     } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
                match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
       julong long_ReservedCodeCacheSize = 0;
@@ -2795,45 +2778,6 @@
       if (FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
-      // -XX:NonNMethodCodeHeapSize=
-    } else if (match_option(option, "-XX:NonNMethodCodeHeapSize=", &tail)) {
-      julong long_NonNMethodCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_NonNMethodCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum non-nmethod code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, NonNMethodCodeHeapSize, (uintx)long_NonNMethodCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
-      // -XX:ProfiledCodeHeapSize=
-    } else if (match_option(option, "-XX:ProfiledCodeHeapSize=", &tail)) {
-      julong long_ProfiledCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_ProfiledCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum profiled code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, ProfiledCodeHeapSize, (uintx)long_ProfiledCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
-      // -XX:NonProfiledCodeHeapSizee=
-    } else if (match_option(option, "-XX:NonProfiledCodeHeapSize=", &tail)) {
-      julong long_NonProfiledCodeHeapSize = 0;
-
-      ArgsRange errcode = parse_memory_size(tail, &long_NonProfiledCodeHeapSize, 1);
-      if (errcode != arg_in_range) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum non-profiled code heap size: %s.\n", option->optionString);
-        return JNI_EINVAL;
-      }
-      if (FLAG_SET_CMDLINE(uintx, NonProfiledCodeHeapSize, (uintx)long_NonProfiledCodeHeapSize) != Flag::SUCCESS) {
-        return JNI_EINVAL;
-      }
     // -green
     } else if (match_option(option, "-green")) {
       jio_fprintf(defaultStream::error_stream(),
--- a/src/hotspot/share/runtime/arguments.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/arguments.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -27,6 +27,7 @@
 
 #include "logging/logLevel.hpp"
 #include "logging/logTag.hpp"
+#include "memory/allocation.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/perfData.hpp"
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -32,6 +32,7 @@
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/task.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -214,12 +215,8 @@
   if (requesting_thread == biased_thread) {
     thread_is_alive = true;
   } else {
-    for (JavaThread* cur_thread = Threads::first(); cur_thread != NULL; cur_thread = cur_thread->next()) {
-      if (cur_thread == biased_thread) {
-        thread_is_alive = true;
-        break;
-      }
-    }
+    ThreadsListHandle tlh;
+    thread_is_alive = tlh.includes(biased_thread);
   }
   if (!thread_is_alive) {
     if (allow_rebias) {
@@ -390,72 +387,76 @@
   Klass* k_o = o->klass();
   Klass* klass = k_o;
 
-  if (bulk_rebias) {
-    // Use the epoch in the klass of the object to implicitly revoke
-    // all biases of objects of this data type and force them to be
-    // reacquired. However, we also need to walk the stacks of all
-    // threads and update the headers of lightweight locked objects
-    // with biases to have the current epoch.
+  {
+    JavaThreadIteratorWithHandle jtiwh;
 
-    // If the prototype header doesn't have the bias pattern, don't
-    // try to update the epoch -- assume another VM operation came in
-    // and reset the header to the unbiased state, which will
-    // implicitly cause all existing biases to be revoked
-    if (klass->prototype_header()->has_bias_pattern()) {
-      int prev_epoch = klass->prototype_header()->bias_epoch();
-      klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch());
-      int cur_epoch = klass->prototype_header()->bias_epoch();
+    if (bulk_rebias) {
+      // Use the epoch in the klass of the object to implicitly revoke
+      // all biases of objects of this data type and force them to be
+      // reacquired. However, we also need to walk the stacks of all
+      // threads and update the headers of lightweight locked objects
+      // with biases to have the current epoch.
 
-      // Now walk all threads' stacks and adjust epochs of any biased
-      // and locked objects of this data type we encounter
-      for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
+      // If the prototype header doesn't have the bias pattern, don't
+      // try to update the epoch -- assume another VM operation came in
+      // and reset the header to the unbiased state, which will
+      // implicitly cause all existing biases to be revoked
+      if (klass->prototype_header()->has_bias_pattern()) {
+        int prev_epoch = klass->prototype_header()->bias_epoch();
+        klass->set_prototype_header(klass->prototype_header()->incr_bias_epoch());
+        int cur_epoch = klass->prototype_header()->bias_epoch();
+
+        // Now walk all threads' stacks and adjust epochs of any biased
+        // and locked objects of this data type we encounter
+        for (; JavaThread *thr = jtiwh.next(); ) {
+          GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
+          for (int i = 0; i < cached_monitor_info->length(); i++) {
+            MonitorInfo* mon_info = cached_monitor_info->at(i);
+            oop owner = mon_info->owner();
+            markOop mark = owner->mark();
+            if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
+              // We might have encountered this object already in the case of recursive locking
+              assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
+              owner->set_mark(mark->set_bias_epoch(cur_epoch));
+            }
+          }
+        }
+      }
+
+      // At this point we're done. All we have to do is potentially
+      // adjust the header of the given object to revoke its bias.
+      revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
+    } else {
+      if (log_is_enabled(Info, biasedlocking)) {
+        ResourceMark rm;
+        log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
+      }
+
+      // Disable biased locking for this data type. Not only will this
+      // cause future instances to not be biased, but existing biased
+      // instances will notice that this implicitly caused their biases
+      // to be revoked.
+      klass->set_prototype_header(markOopDesc::prototype());
+
+      // Now walk all threads' stacks and forcibly revoke the biases of
+      // any locked and biased objects of this data type we encounter.
+      for (; JavaThread *thr = jtiwh.next(); ) {
         GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
         for (int i = 0; i < cached_monitor_info->length(); i++) {
           MonitorInfo* mon_info = cached_monitor_info->at(i);
           oop owner = mon_info->owner();
           markOop mark = owner->mark();
           if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
-            // We might have encountered this object already in the case of recursive locking
-            assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
-            owner->set_mark(mark->set_bias_epoch(cur_epoch));
+            revoke_bias(owner, false, true, requesting_thread, NULL);
           }
         }
       }
+
+      // Must force the bias of the passed object to be forcibly revoked
+      // as well to ensure guarantees to callers
+      revoke_bias(o, false, true, requesting_thread, NULL);
     }
-
-    // At this point we're done. All we have to do is potentially
-    // adjust the header of the given object to revoke its bias.
-    revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
-  } else {
-    if (log_is_enabled(Info, biasedlocking)) {
-      ResourceMark rm;
-      log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
-    }
-
-    // Disable biased locking for this data type. Not only will this
-    // cause future instances to not be biased, but existing biased
-    // instances will notice that this implicitly caused their biases
-    // to be revoked.
-    klass->set_prototype_header(markOopDesc::prototype());
-
-    // Now walk all threads' stacks and forcibly revoke the biases of
-    // any locked and biased objects of this data type we encounter.
-    for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
-      GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
-      for (int i = 0; i < cached_monitor_info->length(); i++) {
-        MonitorInfo* mon_info = cached_monitor_info->at(i);
-        oop owner = mon_info->owner();
-        markOop mark = owner->mark();
-        if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
-          revoke_bias(owner, false, true, requesting_thread, NULL);
-        }
-      }
-    }
-
-    // Must force the bias of the passed object to be forcibly revoked
-    // as well to ensure guarantees to callers
-    revoke_bias(o, false, true, requesting_thread, NULL);
-  }
+  } // ThreadsListHandle is destroyed here.
 
   log_info(biasedlocking)("* Ending bulk revocation");
 
@@ -481,7 +482,7 @@
 
 static void clean_up_cached_monitor_info() {
   // Walk the thread list clearing out the cached monitors
-  for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
     thr->set_cached_monitor_info(NULL);
   }
 }
@@ -768,7 +769,7 @@
 
   ResourceMark rm;
   Thread* cur = Thread::current();
-  for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     if (thread->has_last_Java_frame()) {
       RegisterMap rm(thread);
       for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
--- a/src/hotspot/share/runtime/deoptimization.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -50,6 +50,7 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/vframe_hp.hpp"
@@ -1297,7 +1298,7 @@
 
   assert(SafepointSynchronize::is_at_safepoint(), "must only be called from safepoint");
   GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-  for (JavaThread* jt = Threads::first(); jt != NULL ; jt = jt->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     if (jt->has_last_Java_frame()) {
       StackFrameStream sfs(jt, true);
       while (!sfs.is_done()) {
--- a/src/hotspot/share/runtime/globals.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/globals.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -2484,6 +2484,12 @@
   LP64_ONLY(range(-1, max_intx/MICROUNITS))                                 \
   NOT_LP64(range(-1, max_intx))                                             \
                                                                             \
+  diagnostic(bool, EnableThreadSMRExtraValidityChecks, true,                \
+             "Enable Thread SMR extra validity checks")                     \
+                                                                            \
+  diagnostic(bool, EnableThreadSMRStatistics, true,                         \
+             "Enable Thread SMR Statistics")                                \
+                                                                            \
   product(bool, Inline, true,                                               \
           "Enable inlining")                                                \
                                                                             \
@@ -3359,7 +3365,7 @@
                                                                             \
   product_pd(uintx, InitialCodeCacheSize,                                   \
           "Initial code cache size (in bytes)")                             \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   develop_pd(uintx, CodeCacheMinimumUseSpace,                               \
           "Minimum code cache size (in bytes) required to start VM.")       \
@@ -3370,7 +3376,7 @@
                                                                             \
   product_pd(uintx, ReservedCodeCacheSize,                                  \
           "Reserved code cache size (in bytes) - maximum code cache size")  \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   product_pd(uintx, NonProfiledCodeHeapSize,                                \
           "Size of code heap with non-profiled methods (in bytes)")         \
@@ -3382,11 +3388,11 @@
                                                                             \
   product_pd(uintx, NonNMethodCodeHeapSize,                                 \
           "Size of code heap with non-nmethods (in bytes)")                 \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   product_pd(uintx, CodeCacheExpansionSize,                                 \
           "Code cache expansion size (in bytes)")                           \
-          range(0, max_uintx)                                               \
+          range(os::vm_page_size(), max_uintx)                              \
                                                                             \
   diagnostic_pd(uintx, CodeCacheMinBlockLength,                             \
           "Minimum number of segments in a code cache block")               \
--- a/src/hotspot/share/runtime/handshake.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/handshake.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -37,8 +37,6 @@
 #include "utilities/formatBuffer.hpp"
 #include "utilities/preserveException.hpp"
 
-#define ALL_JAVA_THREADS(X) for (JavaThread* X = Threads::first(); X; X = X->next())
-
 class HandshakeOperation: public StackObj {
 public:
   virtual void do_handshake(JavaThread* thread) = 0;
@@ -94,8 +92,7 @@
 
 void VM_Handshake::handle_timeout() {
   LogStreamHandle(Warning, handshake) log_stream;
-  MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-  ALL_JAVA_THREADS(thr) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
     if (thr->has_handshake()) {
       log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
       thr->print_thread_state_on(&log_stream);
@@ -117,8 +114,8 @@
     TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 
     {
-      MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      if (Threads::includes(_target)) {
+      ThreadsListHandle tlh;
+      if (tlh.includes(_target)) {
         set_handshake(_target);
         _thread_alive = true;
       }
@@ -139,9 +136,24 @@
         handle_timeout();
       }
 
+      // We need to re-think this with SMR ThreadsList.
+      // There is an assumption in the code that the Threads_lock should be
+      // locked during certain phases.
       MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      _target->handshake_process_by_vmthread();
-
+      ThreadsListHandle tlh;
+      if (tlh.includes(_target)) {
+        // Warning _target's address might be re-used.
+        // handshake_process_by_vmthread will check the semaphore for us again.
+        // Since we can't have more then one handshake in flight a reuse of
+        // _target's address should be okay since the new thread will not have
+        // an operation.
+        _target->handshake_process_by_vmthread();
+      } else {
+        // We can't warn here since the thread does cancel_handshake after
+        // it has been removed from the ThreadsList. So we should just keep
+        // looping here until while below returns false. If we have a bug,
+        // then we hang here, which is good for debugging.
+      }
     } while (!poll_for_completed_thread());
   }
 
@@ -157,15 +169,15 @@
   void doit() {
     TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
 
-    int number_of_threads_issued = -1;
-    int number_of_threads_completed = 0;
-    {
-      MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-      number_of_threads_issued = Threads::number_of_threads();
+    int number_of_threads_issued = 0;
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+      set_handshake(thr);
+      number_of_threads_issued++;
+    }
 
-      ALL_JAVA_THREADS(thr) {
-        set_handshake(thr);
-      }
+    if (number_of_threads_issued < 1) {
+      log_debug(handshake)("No threads to handshake.");
+      return;
     }
 
     if (!UseMembar) {
@@ -174,6 +186,7 @@
 
     log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
     const jlong start_time = os::elapsed_counter();
+    int number_of_threads_completed = 0;
     do {
       // Check if handshake operation has timed out
       if (handshake_has_timed_out(start_time)) {
@@ -184,13 +197,19 @@
       // Observing a blocked state may of course be transient but the processing is guarded
       // by semaphores and we optimistically begin by working on the blocked threads
       {
+          // We need to re-think this with SMR ThreadsList.
+          // There is an assumption in the code that the Threads_lock should
+          // be locked during certain phases.
           MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
-          ALL_JAVA_THREADS(thr) {
+          for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
+            // A new thread on the ThreadsList will not have an operation,
+            // hence it is skipped in handshake_process_by_vmthread.
             thr->handshake_process_by_vmthread();
           }
       }
 
       while (poll_for_completed_thread()) {
+        // Includes canceled operations by exiting threads.
         number_of_threads_completed++;
       }
 
@@ -212,7 +231,7 @@
       _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
 
   void doit() {
-    ALL_JAVA_THREADS(t) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
       if (_all_threads || t == _target_thread) {
         if (t == _target_thread) {
           _thread_alive = true;
@@ -298,8 +317,8 @@
   assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
 #ifdef DEBUG
   {
-    MutexLockerEx ml(Threads_lock,  Mutex::_no_safepoint_check_flag);
-    assert(!Threads::includes(thread), "java thread must not be on threads list");
+    ThreadsListHandle tlh;
+    assert(!tlh.includes(_target), "java thread must not be on threads list");
   }
 #endif
   HandshakeOperation* op = _operation;
--- a/src/hotspot/share/runtime/java.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/java.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -356,6 +356,8 @@
   if (PrintNMTStatistics) {
     MemTracker::final_report(tty);
   }
+
+  Threads::log_smr_statistics();
 }
 
 #else // PRODUCT MODE STATISTICS
@@ -396,6 +398,8 @@
   if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
     Method::print_touched_methods(tty);
   }
+
+  Threads::log_smr_statistics();
 }
 
 #endif
--- a/src/hotspot/share/runtime/memprofiler.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/memprofiler.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -36,6 +36,7 @@
 #include "runtime/os.hpp"
 #include "runtime/task.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
 
 #ifndef PRODUCT
@@ -51,8 +52,6 @@
 
 
 void MemProfilerTask::task() {
-  // Get thread lock to provide mutual exclusion, and so we can iterate safely over the thread list.
-  MutexLocker mu(Threads_lock);
   MemProfiler::do_trace();
 }
 
@@ -109,21 +108,22 @@
   // Calculate thread local sizes
   size_t handles_memory_usage    = VMThread::vm_thread()->handle_area()->size_in_bytes();
   size_t resource_memory_usage   = VMThread::vm_thread()->resource_area()->size_in_bytes();
-  JavaThread *cur = Threads::first();
-  while (cur != NULL) {
-    handles_memory_usage  += cur->handle_area()->size_in_bytes();
-    resource_memory_usage += cur->resource_area()->size_in_bytes();
-    cur = cur->next();
+  {
+    JavaThreadIteratorWithHandle jtiwh;
+    for (; JavaThread *cur = jtiwh.next(); ) {
+      handles_memory_usage  += cur->handle_area()->size_in_bytes();
+      resource_memory_usage += cur->resource_area()->size_in_bytes();
+    }
+
+    // Print trace line in log
+    fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
+            os::elapsedTime(),
+            jtiwh.length(),
+            InstanceKlass::number_of_instance_classes(),
+            Universe::heap()->used() / K,
+            Universe::heap()->capacity() / K);
   }
 
-  // Print trace line in log
-  fprintf(_log_fp, "%6.1f,%5d,%5d," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",",
-          os::elapsedTime(),
-          Threads::number_of_threads(),
-          InstanceKlass::number_of_instance_classes(),
-          Universe::heap()->used() / K,
-          Universe::heap()->capacity() / K);
-
   fprintf(_log_fp, UINTX_FORMAT_W(6) ",", CodeCache::capacity() / K);
 
   fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",%6ld\n",
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
 #define SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
 
+#include "memory/allocation.inline.hpp"
 #include "memory/padded.hpp"
 #include "runtime/os.hpp"
 #include "runtime/park.hpp"
--- a/src/hotspot/share/runtime/os.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/os.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -54,6 +54,7 @@
 #include "runtime/os.inline.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/attachListener.hpp"
 #include "services/mallocTracker.hpp"
@@ -197,15 +198,7 @@
 }
 
 OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
-#ifdef ASSERT
-  if (!(!thread->is_Java_thread() ||
-         Thread::current() == thread  ||
-         Threads_lock->owned_by_self()
-         || thread->is_Compiler_thread()
-        )) {
-    assert(false, "possibility of dangling Thread pointer");
-  }
-#endif
+  debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
   if (p >= MinPriority && p <= MaxPriority) {
     int priority = java_to_os_priority[p];
@@ -1100,7 +1093,7 @@
   }
 #endif
 
-  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
     // Check for privilege stack
     if (thread->privileged_stack_top() != NULL &&
         thread->privileged_stack_top()->contains(addr)) {
@@ -1126,7 +1119,6 @@
       if (verbose) thread->print_on(st);
       return;
     }
-
   }
 
   // Check if in metaspace and print types that have vptrs (only method now)
@@ -1665,7 +1657,6 @@
 }
 
 void os::SuspendedThreadTask::run() {
-  assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
   internal_do_task();
   _done = true;
 }
--- a/src/hotspot/share/runtime/perfData.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/perfData.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -32,7 +32,7 @@
 #include "runtime/mutex.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
-#include "runtime/perfData.hpp"
+#include "runtime/perfData.inline.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -611,3 +611,10 @@
 
   return copy;
 }
+
+PerfTraceTime::~PerfTraceTime() {
+  if (!UsePerfData || (_recursion_counter != NULL &&
+      --(*_recursion_counter) > 0)) return;
+  _t.stop();
+  _timerp->inc(_t.ticks());
+}
--- a/src/hotspot/share/runtime/perfData.hpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/perfData.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -25,10 +25,11 @@
 #ifndef SHARE_VM_RUNTIME_PERFDATA_HPP
 #define SHARE_VM_RUNTIME_PERFDATA_HPP
 
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
 #include "runtime/perfMemory.hpp"
 #include "runtime/timer.hpp"
-#include "utilities/growableArray.hpp"
+
+template <typename T> class GrowableArray;
 
 /* jvmstat global and subsystem counter name space - enumeration value
  * serve as an index into the PerfDataManager::_name_space[] array
@@ -629,10 +630,10 @@
     bool contains(const char* name) { return find_by_name(name) != NULL; }
 
     // return the number of PerfData items in this list
-    int length() { return _set->length(); }
+    inline int length();
 
     // add a PerfData item to this list
-    void append(PerfData *p) { _set->append(p); }
+    inline void append(PerfData *p);
 
     // remove the given PerfData item from this list. When called
     // while iterating over the list, this method will result in a
@@ -640,7 +641,7 @@
     // method is also impacted by this method as elements with an
     // index greater than the index of the element removed by this
     // method will be shifted down by one.
-    void remove(PerfData *p) { _set->remove(p); }
+    inline void remove(PerfData *p);
 
     // create a new PerfDataList from this list. The new list is
     // a shallow copy of the original list and care should be taken
@@ -651,7 +652,7 @@
     // for backward compatibility with GrowableArray - need to implement
     // some form of iterator to provide a cleaner abstraction for
     // iteration over the container.
-    PerfData* at(int index) { return _set->at(index); }
+    inline PerfData* at(int index);
 };
 
 
@@ -677,23 +678,23 @@
   protected:
     // return the list of all known PerfData items
     static PerfDataList* all();
-    static int count() { return _all->length(); }
+    static inline int count();
 
     // return the list of all known PerfData items that are to be
     // sampled by the StatSampler.
     static PerfDataList* sampled();
-    static int sampled_count() { return _sampled->length(); }
+    static inline int sampled_count();
 
     // return the list of all known PerfData items that have a
     // variability classification of type Constant
     static PerfDataList* constants();
-    static int constants_count() { return _constants->length(); }
+    static inline int constants_count();
 
   public:
 
     // method to check for the existence of a PerfData item with
     // the given name.
-    static bool exists(const char* name) { return _all->contains(name); }
+    static inline bool exists(const char* name);
 
     // method to search for a instrumentation object by name
     static PerfData* find_by_name(const char* name);
@@ -929,12 +930,7 @@
     inline void suspend() { if (!UsePerfData) return; _t.stop(); }
     inline void resume() { if (!UsePerfData) return; _t.start(); }
 
-    inline ~PerfTraceTime() {
-      if (!UsePerfData || (_recursion_counter != NULL &&
-                           --(*_recursion_counter) > 0)) return;
-      _t.stop();
-      _timerp->inc(_t.ticks());
-    }
+    ~PerfTraceTime();
 };
 
 /* The PerfTraceTimedEvent class is responsible for counting the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/perfData.inline.hpp	Mon Nov 27 17:04:45 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2002, 2017, 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_RUNTIME_PERFDATA_INLINE_HPP
+#define SHARE_VM_RUNTIME_PERFDATA_INLINE_HPP
+
+#include "runtime/perfData.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
+
+inline int PerfDataList::length() {
+  return _set->length();
+}
+
+inline void PerfDataList::append(PerfData *p) {
+  _set->append(p);
+}
+
+inline void PerfDataList::remove(PerfData *p) {
+  _set->remove(p);
+}
+
+inline PerfData* PerfDataList::at(int index) {
+  return _set->at(index);
+}
+
+inline int PerfDataManager::count() {
+  return _all->length();
+}
+
+inline int PerfDataManager::sampled_count() {
+  return _sampled->length();
+}
+
+inline int PerfDataManager::constants_count() {
+  return _constants->length();
+}
+
+inline bool PerfDataManager::exists(const char* name) {
+  return _all->contains(name);
+}
+
+#endif // SHARE_VM_RUNTIME_PERFDATA_INLINE_HPP
--- a/src/hotspot/share/runtime/safepoint.cpp	Fri Nov 24 17:19:47 2017 +0000
+++ b/src/hotspot/share/runtime/safepoint.cpp	Mon Nov 27 17:04:45 2017 +0000
@@ -59,6 +59,7 @@
 #include "runtime/sweeper.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timerTrace.hpp"
 #include "services/runtimeService.hpp"
 #include "trace/tracing.hpp"
@@ -174,7 +175,7 @@
     if (SafepointMechanism::uses_thread_local_poll()) {
       // Arming the per thread poll while having _state != _not_synchronized means safepointing
       log_trace(safepoint)("Setting thread local yield flag for threads");
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+      for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
         // Make sure the threads start polling, it is time to yield.
         SafepointMechanism::arm_local_poll(cur); // release store, global state -> local state
       }
@@ -200,133 +201,137 @@
 
     // Consider using active_processor_count() ... but that call is expensive.
     int ncpus = os::processor_count() ;
+    unsigned int iterations = 0;
 
+    {
+      JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
-    for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-      assert(cur->safepoint_state()->is_running(), "Illegal initial state");
-      // Clear the visited flag to ensure that the critical counts are collected properly.
-      cur->set_visited_for_critical_count(false);
-    }
+      for (; JavaThread *cur = jtiwh.next(); ) {
+        assert(cur->safepoint_state()->is_running(), "Illegal initial state");
+        // Clear the visited flag to ensure that the critical counts are collected properly.
+        cur->set_visited_for_critical_count(false);
+      }
 #endif // ASSERT
 
-    if (SafepointTimeout)
-      safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
+      if (SafepointTimeout)
+        safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
 
-    // Iterate through all threads until it have been determined how to stop them all at a safepoint
-    unsigned int iterations = 0;
-    int steps = 0 ;
-    while(still_running > 0) {
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-        assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
-        ThreadSafepointState *cur_state = cur->safepoint_state();
-        if (cur_state->is_running()) {
-          cur_state->examine_state_of_thread();
-          if (!cur_state->is_running()) {
-            still_running--;
-            // consider adjusting steps downward:
-            //   steps = 0
-            //   steps -= NNN
-            //   steps >>= 1
-            //   steps = MIN(steps, 2000-100)
-            //   if (iterations != 0) steps -= NNN
-          }
-          LogTarget(Trace, safepoint) lt;
-          if (lt.is_enabled()) {
-            ResourceMark rm;
-            LogStream ls(lt);
-            cur_state->print_on(&ls);
+      // Iterate through all threads until it have been determined how to stop them all at a safepoint
+      int steps = 0 ;
+      while(still_running > 0) {
+        jtiwh.rewind();
+        for (; JavaThread *cur = jtiwh.next(); ) {
+          assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
+          ThreadSafepointState *cur_state = cur->safepoint_state();
+          if (cur_state->is_running()) {
+            cur_state->examine_state_of_thread();
+            if (!cur_state->is_running()) {
+              still_running--;
+              // consider adjusting steps downward:
+              //   steps = 0
+              //   steps -= NNN
+              //   steps >>= 1
+              //   steps = MIN(steps, 2000-100)
+              //   if (iterations != 0) steps -= NNN
+            }
+            LogTarget(Trace, safepoint) lt;
+            if (lt.is_enabled()) {
+              ResourceMark rm;
+              LogStream ls(lt);
+              cur_state->print_on(&ls);
+            }
           }
         }
-      }
 
-      if (iterations == 0) {
-        initial_running = still_running;
-        if (PrintSafepointStatistics) {
-          begin_statistics(nof_threads, still_running);
-        }
-      }
-
-      if (still_running > 0) {
-        // Check for if it takes to long
-        if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
-          print_safepoint_timeout(_spinning_timeout);
+        if (iterations == 0) {
+          initial_running = still_running;
+          if (PrintSafepointStatistics) {
+            begin_statistics(nof_threads, still_running);
+          }
         }
 
-        // Spin to avoid context switching.
-        // There's a tension between allowing the mutators to run (and rendezvous)
-        // vs spinning.  As the VM thread spins, wasting cycles, it consumes CPU that
-        // a mutator might otherwise use profitably to reach a safepoint.  Excessive
-        // spinning by the VM thread on a saturated system can increase rendezvous latency.
-        // Blocking or yielding incur their own penalties in the form of context switching
-        // and the resultant loss of $ residency.
-        //
-        // Further complicating matters is that yield() does not work as naively expected
-        // on many platforms -- yield() does not guarantee that any other ready threads
-        // will run.   As such we revert to naked_short_sleep() after some number of iterations.
-        // nakes_short_sleep() is implemented as a short unconditional sleep.
-        // Typical operating systems round a "short" sleep period up to 10 msecs, so sleeping
-        // can actually increase the time it takes the VM thread to detect that a system-wide
-        // stop-the-world safepoint has been reached.  In a pathological scenario such as that
-        // described in CR6415670 the VMthread may sleep just before the mutator(s) become safe.
-        // In that case the mutators will be stalled waiting for the safepoint to complete and the
-        // the VMthread will be sleeping, waiting for the mutators to rendezvous.  The VMthread
-        // will eventually wake up and detect that all mutators are safe, at which point
-        // we'll again make progress.
-        //
-        // Beware too that that the VMThread typically runs at elevated priority.
-        // Its default priority is higher than the default mutator priority.
-        // Obviously, this complicates spinning.
-        //
-        // Note too that on Windows XP SwitchThreadTo() has quite different behavior than Sleep(0).
-        // Sleep(0) will _not yield to lower priority threads, while SwitchThreadTo() will.
-        //
-        // See the comments in synchronizer.cpp for additional remarks on spinning.
-        //
-        // In the future we might:
-        // 1. Modify the safepoint scheme to avoid potentially unbounded spinning.
-        //    This is tricky as the path used by a thread exiting the JVM (say on
-        //    on JNI call-out) simply stores into its state field.  The burden
-        //    is placed on the VM thread, which must poll (spin).
-        // 2. Find something useful to do while spinning.  If the safepoint is GC-related
-        //    we might aggressively scan the stacks of threads that are already safe.
-        // 3. Use Solaris schedctl to examine the state of the still-running mutators.
-        //    If all the mutators are ONPROC there's no reason to sleep or yield.
-        // 4. YieldTo() any still-running mutators that are ready but OFFPROC.
-        // 5. Check system saturation.  If the system is not fully saturated then
-        //    simply spin and avoid sleep/yield.
-        // 6. As still-running mutators rendezvous they could unpark the sleeping
-        //    VMthread.  This works well for still-running mutators that become
-        //    safe.  The VMthread must still poll for mutators that call-out.
-        // 7. Drive the policy on time-since-begin instead of iterations.
-        // 8. Consider making the spin duration a function of the # of CPUs:
-        //    Spin = (((ncpus-1) * M) + K) + F(still_running)
-        //    Alternately, instead of counting iterations of the outer loop
-        //    we could count the # of threads visited in the inner loop, above.
-        // 9. On windows consider using the return value from SwitchThreadTo()
-        //    to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
-
-        if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) {
-          guarantee (PageArmed == 0, "invariant") ;
-          PageArmed = 1 ;
-          os::make_polling_page_unreadable();
-        }
-
-        // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
-        // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
-        ++steps ;
-        if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
-          SpinPause() ;     // MP-Polite spin
-        } else
-          if (steps < DeferThrSuspendLoopCount) {
-            os::naked_yield() ;
-          } else {
-            os::naked_short_sleep(1);
+        if (still_running > 0) {
+          // Check fo