changeset 53708:0c339d151cdc

Merge
author psadhukhan
date Mon, 04 Feb 2019 11:01:04 +0530
parents ec5e5bc74f17 d997c227e968
children fa0d9fc371bb 9bb638b282bc
files src/java.xml/share/classes/com/sun/org/apache/xpath/internal/SourceTreeManager.java test/hotspot/jtreg/gc/g1/TestStringTableStats.java test/jdk/ProblemList.txt test/langtools/jdk/javadoc/doclet/testHtmlWarning/TestHtmlWarning.java
diffstat 463 files changed, 6194 insertions(+), 8855 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sat Feb 02 10:00:05 2019 -0800
+++ b/.hgtags	Mon Feb 04 11:01:04 2019 +0530
@@ -538,3 +538,5 @@
 659b004b6a1bd8c31e766cbdf328d8f8473fd4d7 jdk-12+28
 e3ed960609927b5fdfd0a797159835cd83a81a31 jdk-13+5
 44f41693631f9b5ac78ff4d2bfabd6734fe46df2 jdk-12+29
+b5f05fe4a6f8b3996a000c20078b356d991ca8ec jdk-13+6
+6c377af36a5c4203f16aed8a5e4c2ecc08fcd8bd jdk-12+30
--- a/make/GenerateLinkOptData.gmk	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/GenerateLinkOptData.gmk	Mon Feb 04 11:01:04 2019 +0530
@@ -59,6 +59,8 @@
   INTERIM_IMAGE_DIR := $(BUILD_JDK)
 endif
 
+# Save the stderr output of the command and print it along with stdout in case
+# something goes wrong.
 $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
 	$(call MakeDir, $(LINK_OPT_DIR))
 	$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $@))
@@ -67,7 +69,14 @@
 	    -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
 	    -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
 	    build.tools.classlist.HelloClasslist \
-	    $(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
+	    2> $(LINK_OPT_DIR)/stderr > $(JLI_TRACE_FILE) \
+	    || ( \
+	        exitcode=$$? ; \
+	        $(ECHO) "ERROR: Failed to generate link optimization data." \
+	            "This is likely a problem with the newly built JVM/JDK." ; \
+	        $(CAT) $(LINK_OPT_DIR)/stderr $(JLI_TRACE_FILE) ; \
+	        exit $$exitcode \
+	    )
 	$(GREP) -v HelloClasslist $@.raw > $@
 
 # The jli trace is created by the same recipe as classlist. By declaring these
--- a/make/autoconf/build-performance.m4	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/autoconf/build-performance.m4	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -42,8 +42,11 @@
     NUM_CORES=`/usr/sbin/sysctl -n hw.ncpu`
     FOUND_CORES=yes
   elif test "x$OPENJDK_BUILD_OS" = xaix ; then
-    NUM_CORES=`/usr/sbin/prtconf | grep "^Number Of Processors" | awk '{ print [$]4 }'`
-    FOUND_CORES=yes
+    NUM_LCPU=`lparstat -m 2> /dev/null | $GREP -o "lcpu=[[0-9]]*" | $CUT -d "=" -f 2`
+    if test -n "$NUM_LCPU"; then
+      NUM_CORES=$NUM_LCPU
+      FOUND_CORES=yes
+    fi
   elif test -n "$NUMBER_OF_PROCESSORS"; then
     # On windows, look in the env
     NUM_CORES=$NUMBER_OF_PROCESSORS
--- a/make/autoconf/compare.sh.in	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/autoconf/compare.sh.in	Mon Feb 04 11:01:04 2019 +0530
@@ -76,12 +76,15 @@
 if [ "@COMPILE_TYPE@" != "cross" ]; then
   export JAVAP="@FIXPATH@ $OUTPUTDIR/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
   export JIMAGE="@FIXPATH@ $OUTPUTDIR/jdk/bin/jimage"
+  export JMOD="@FIXPATH@ $OUTPUTDIR/jdk/bin/jmod"
 elif [ "@CREATE_BUILDJDK@" = "true" ]; then
   export JAVAP="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
   export JIMAGE="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/jimage"
+  export JMOD="@FIXPATH@ $OUTPUTDIR/buildjdk/jdk/bin/jmod"
 else
   export JAVAP="@FIXPATH@ @BUILD_JDK@/bin/javap @JAVA_TOOL_FLAGS_SMALL@"
   export JIMAGE="@FIXPATH@ @BUILD_JDK@/bin/jimage"
+  export JMOD="@FIXPATH@ @BUILD_JDK@/bin/jmod"
 fi
 
 if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
--- a/make/autoconf/lib-freetype.m4	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/autoconf/lib-freetype.m4	Mon Feb 04 11:01:04 2019 +0530
@@ -92,7 +92,7 @@
 
   # This setup is to verify access to system installed freetype header and libraries.
   # On Windows and MacOS this does not apply and using these options will report an error.
-  # On other platforms (Linux, Solaris, and perhaps AIX), they will default to using
+  # On other platforms (Linux, Solaris), they will default to using
   # the system libraries. If they are found automatically, nothing need be done.
   # If they are not found, the configure "--with-freetype-*" options may be used to fix that.
   # If the preference is to bundle on these platforms then use --with-freetype=bundled
@@ -102,11 +102,12 @@
 
   if (test "x$with_freetype_include" = "x"  && test "x$with_freetype_lib" != "x") || \
      (test "x$with_freetype_include" != "x"  && test "x$with_freetype_lib" = "x"); then
-       AC_MSG_ERROR(['must specify both or neither of --with_freetype_include and --with_freetype_lib])
+       AC_MSG_ERROR(['must specify both or neither of --with-freetype-include and --with-freetype-lib])
   fi
 
   FREETYPE_TO_USE=bundled
-  if (test "x$OPENJDK_TARGET_OS" != "xwindows" && test "x$OPENJDK_TARGET_OS" != "xmacosx"); then
+  if (test "x$OPENJDK_TARGET_OS" != "xwindows" && test "x$OPENJDK_TARGET_OS" != "xmacosx" \
+      && test "x$OPENJDK_TARGET_OS" != "xaix"); then
     FREETYPE_TO_USE=system
   fi
   if (test "x$with_freetype" != "x"); then
@@ -115,7 +116,7 @@
     elif (test "x$with_freetype" = "xbundled"); then
       FREETYPE_TO_USE=bundled
       if (test "x$with_freetype_include" != "x"  || test "x$with_freetype_lib" != "x"); then
-        AC_MSG_ERROR(['bundled' cannot be specified with --with_freetype_include and --with_freetype_lib])
+        AC_MSG_ERROR(['bundled' cannot be specified with --with-freetype-include and --with-freetype-lib])
       fi
     else
        AC_MSG_ERROR(['valid values for --with-freetype are 'system' and 'bundled'])
--- a/make/conf/jib-profiles.js	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/conf/jib-profiles.js	Mon Feb 04 11:01:04 2019 +0530
@@ -866,8 +866,8 @@
         solaris_x64: "SS12u4-Solaris11u1+1.0",
         solaris_sparcv9: "SS12u6-Solaris11u3+1.0",
         windows_x64: "VS2017-15.5.5+1.0",
-        linux_aarch64: "gcc7.3.0-Fedora27+1.1",
-        linux_arm: "gcc7.3.0-Fedora27+1.1"
+        linux_aarch64: "gcc7.3.0-Fedora27+1.2",
+        linux_arm: "gcc7.3.0-Fedora27+1.2"
     };
 
     var devkit_platform = (input.target_cpu == "x86"
--- a/make/data/charsetmapping/stdcs-aix	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/data/charsetmapping/stdcs-aix	Mon Feb 04 11:01:04 2019 +0530
@@ -5,7 +5,6 @@
 Big5_Solaris
 Big5_HKSCS
 EUC_CN
-EUC_JP
 EUC_KR
 GBK
 GB18030
--- a/make/data/lsrdata/language-subtag-registry.txt	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/data/lsrdata/language-subtag-registry.txt	Mon Feb 04 11:01:04 2019 +0530
@@ -1,4 +1,4 @@
-File-Date: 2018-10-31
+File-Date: 2018-11-30
 %%
 Type: language
 Subtag: aa
@@ -593,6 +593,7 @@
 Type: language
 Subtag: lg
 Description: Ganda
+Description: Luganda
 Added: 2005-10-16
 %%
 Type: language
--- a/make/devkit/Tools.gmk	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/devkit/Tools.gmk	Mon Feb 04 11:01:04 2019 +0530
@@ -103,7 +103,7 @@
 GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.xz
 BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.xz
 CCACHE := https://samba.org/ftp/ccache/$(ccache_ver).tar.xz
-MPFR := http://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
+MPFR := https://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
 GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
 MPC := http://ftp.gnu.org/pub/gnu/mpc/${mpc_ver}.tar.gz
 GDB := http://ftp.gnu.org/gnu/gdb/${gdb_ver}.tar.xz
@@ -355,6 +355,7 @@
 $(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
 
 # Makefile creation. Simply run configure in build dir.
+# Setting CFLAGS to -O2 generates a much faster ld.
 $(bfdmakes) \
 $(BUILDDIR)/$(binutils_ver)/Makefile \
     : $(BINUTILS_CFG)
@@ -362,7 +363,7 @@
 	@mkdir -p $(@D)
 	( \
 	  cd $(@D) ; \
-	  $(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
+	  $(PATHPRE) $(ENVS) CFLAGS="-O2 $(CFLAGS)" \
 	      $(BINUTILS_CFG) \
 	      $(CONFIG) \
 	      --with-sysroot=$(SYSROOT) \
@@ -370,6 +371,7 @@
 	      --program-prefix=$(TARGET)- \
 	      --enable-multilib \
 	      --enable-gold \
+	      --enable-threads \
 	      --enable-plugins \
 	) > $(@D)/log.config 2>&1
 	@echo 'done'
--- a/make/hotspot/gensrc/GensrcAdlc.gmk	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/hotspot/gensrc/GensrcAdlc.gmk	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2019, 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
@@ -142,6 +142,12 @@
       )))
   endif
 
+  ifeq ($(call check-jvm-feature, zgc), true)
+    AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
+        $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/gc/z/z_$(HOTSPOT_TARGET_CPU).ad \
+      )))
+  endif
+
   SINGLE_AD_SRCFILE := $(ADLC_SUPPORT_DIR)/all-ad-src.ad
 
   INSERT_FILENAME_AWK_SCRIPT := \
--- a/make/jdk/src/classes/build/tools/cldrconverter/CalendarType.java	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CalendarType.java	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -40,7 +40,7 @@
         {0,   2},   // generic
         {0,   2},   // gregorian
         {0,   1},   // buddhist
-        {232, 4},   // japanese (eras from Meiji)
+        {232, 5},   // japanese (eras from Meiji)
         {0,   2},   // roc (Minguo)
         {0,   1},   // islamic (Hijrah)
         {0,   1},   // islamic-civil (same as islamic)
--- a/make/scripts/compare.sh	Sat Feb 02 10:00:05 2019 -0800
+++ b/make/scripts/compare.sh	Mon Feb 04 11:01:04 2019 +0530
@@ -340,7 +340,9 @@
 
     echo -n File types...
     found=""
-    for f in `cd $OTHER_DIR && $FIND . ! -type d`
+    # The file command does not know about jmod files and this sometimes results
+    # in different types being detected more or less randomly.
+    for f in $(cd $OTHER_DIR && $FIND . ! -type d -a ! -name "*.jmod")
     do
         if [ ! -f ${OTHER_DIR}/$f ]; then continue; fi
         if [ ! -f ${THIS_DIR}/$f ]; then continue; fi
@@ -494,7 +496,7 @@
     $RM -rf $THIS_UNZIPDIR $OTHER_UNZIPDIR
     $MKDIR -p $THIS_UNZIPDIR
     $MKDIR -p $OTHER_UNZIPDIR
-    if [ "$TYPE" = "jar" -o "$TYPE" = "war" -o "$TYPE" = "zip" -o "$TYPE" = "jmod" ]
+    if [ "$TYPE" = "jar" -o "$TYPE" = "war" -o "$TYPE" = "zip" ]
     then
         (cd $THIS_UNZIPDIR && $UNARCHIVE $THIS_ZIP)
         (cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP)
@@ -502,6 +504,10 @@
     then
         (cd $THIS_UNZIPDIR && $GUNZIP -c $THIS_ZIP | $TAR xf -)
         (cd $OTHER_UNZIPDIR && $GUNZIP -c $OTHER_ZIP | $TAR xf -)
+    elif [ "$TYPE" = "jmod" ]
+    then
+        (cd $THIS_UNZIPDIR && $JMOD extract $THIS_ZIP)
+        (cd $OTHER_UNZIPDIR && $JMOD extract $OTHER_ZIP)
     else
         (cd $THIS_UNZIPDIR && $JIMAGE extract $THIS_ZIP)
         (cd $OTHER_UNZIPDIR && $JIMAGE extract $OTHER_ZIP)
@@ -559,16 +565,16 @@
         return_value=1
     fi
 
-    if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
-        DIFFING_FILES=$($GREP -e 'differ$' -e '^diff ' $CONTENTS_DIFF_FILE \
-            | $SED -e 's/^Files //g' -e 's/diff -r //g' | $CUT -f 1 -d ' ' \
-            | $SED "s|$OTHER_UNZIPDIR/||g")
-    else
-        DIFFING_FILES=$($GREP -e "differ$" $CONTENTS_DIFF_FILE \
-            | $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g")
-    fi
+    if [ "$CMP_ZIPS_CONTENTS" = "true" ]; then
+        if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
+            DIFFING_FILES=$($GREP -e 'differ$' -e '^diff ' $CONTENTS_DIFF_FILE \
+                | $SED -e 's/^Files //g' -e 's/diff -r //g' | $CUT -f 1 -d ' ' \
+                | $SED "s|$OTHER_UNZIPDIR/||g")
+        else
+            DIFFING_FILES=$($GREP -e "differ$" $CONTENTS_DIFF_FILE \
+                | $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g")
+        fi
 
-    if [ "$CMP_ZIPS_CONTENTS" = "true" ]; then
         $RM -f $WORK_DIR/$ZIP_FILE.diffs
         for file in $DIFFING_FILES; do
             if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then
@@ -600,6 +606,48 @@
     return $return_value
 }
 
+################################################################################
+# Compare jmod file
+
+compare_jmod_file() {
+    THIS_DIR=$1
+    OTHER_DIR=$2
+    WORK_DIR=$3
+    JMOD_FILE=$4
+
+    THIS_JMOD=$THIS_DIR/$JMOD_FILE
+    OTHER_JMOD=$OTHER_DIR/$JMOD_FILE
+
+    if $CMP $OTHER_JMOD $THIS_JMOD > /dev/null; then
+        return 0
+    fi
+
+    THIS_JMOD_LIST=$WORK_DIR/$JMOD_FILE.list.this
+    OTHER_JMOD_LIST=$WORK_DIR/$JMOD_FILE.list.other
+    mkdir -p $(dirname $THIS_JMOD_LIST) $(dirname $OTHER_JMOD_LIST)
+
+    $JMOD list $THIS_JMOD | sort > $THIS_JMOD_LIST
+    $JMOD list $OTHER_JMOD | sort > $OTHER_JMOD_LIST
+    JMOD_LIST_DIFF_FILE=$WORK_DIR/$JMOD_FILE.list.diff
+    LC_ALL=C $DIFF $THIS_JMOD_LIST $OTHER_JMOD_LIST > $JMOD_LIST_DIFF_FILE
+
+    ONLY_THIS=$($GREP "^<" $JMOD_LIST_DIFF_FILE)
+    ONLY_OTHER=$($GREP "^>" $JMOD_LIST_DIFF_FILE)
+
+    if [ -n "$ONLY_OTHER" ]; then
+        echo "        Only OTHER $JMOD_FILE contains:"
+        echo "$ONLY_OTHER" | sed "s|^>|            |"g | sed 's|: |/|g'
+        return_value=1
+    fi
+
+    if [ -n "$ONLY_THIS" ]; then
+        echo "        Only THIS $JMOD_FILE contains:"
+        echo "$ONLY_THIS" | sed "s|^<|            |"g | sed 's|: |/|g'
+        return_value=1
+    fi
+
+    return $return_value
+}
 
 ################################################################################
 # Compare all zip files
@@ -631,6 +679,34 @@
 }
 
 ################################################################################
+# Compare all jmod files
+
+compare_all_jmod_files() {
+    THIS_DIR=$1
+    OTHER_DIR=$2
+    WORK_DIR=$3
+
+    JMODS=$(cd $THIS_DIR && $FIND . -type f -name "*.jmod" | $SORT | $FILTER )
+
+    if [ -n "$JMODS" ]; then
+        echo Jmod files...
+
+        return_value=0
+        for f in $JMODS; do
+            if [ -f "$OTHER_DIR/$f" ]; then
+                compare_jmod_file $THIS_DIR $OTHER_DIR $WORK_DIR $f
+                if [ "$?" != "0" ]; then
+                    return_value=1
+                    REGRESSIONS=true
+                fi
+            fi
+        done
+    fi
+
+    return $return_value
+}
+
+################################################################################
 # Compare all jar files
 
 compare_all_jar_files() {
@@ -1141,6 +1217,7 @@
     echo "-zips               Compare the contents of all zip files and files in them"
     echo "-zips-names         Compare the file names inside all zip files"
     echo "-jars               Compare the contents of all jar files"
+    echo "-jmods              Compare the listings of all jmod files"
     echo "-libs               Compare all native libraries"
     echo "-execs              Compare all executables"
     echo "-v                  Verbose output, does not hide known differences"
@@ -1169,6 +1246,7 @@
 CMP_ZIPS=false
 CMP_ZIPS_CONTENTS=true
 CMP_JARS=false
+CMP_JMODS=false
 CMP_LIBS=false
 CMP_EXECS=false
 
@@ -1194,6 +1272,7 @@
             CMP_GENERAL=true
             CMP_ZIPS=true
             CMP_JARS=true
+            CMP_JMODS=true
             CMP_LIBS=true
             CMP_EXECS=true
             ;;
@@ -1220,6 +1299,9 @@
         -jars)
             CMP_JARS=true
             ;;
+        -jmods)
+            CMP_JMODS=true
+            ;;
         -libs)
             CMP_LIBS=true
             ;;
@@ -1264,6 +1346,7 @@
             CMP_TYPES=false
             CMP_ZIPS=true
             CMP_JARS=true
+            CMP_JMODS=true
             CMP_LIBS=true
             CMP_EXECS=true
 
@@ -1317,13 +1400,22 @@
     exit
 fi
 
-if [ "$CMP_NAMES" = "false" ] && [ "$CMP_TYPES" = "false" ] && [ "$CMP_PERMS" = "false" ] && [ "$CMP_GENERAL" = "false" ] && [ "$CMP_ZIPS" = "false" ] && [ "$CMP_JARS" = "false" ] && [ "$CMP_LIBS" = "false" ] && [ "$CMP_EXECS" = "false" ]; then
+if [ "$CMP_NAMES" = "false" ] \
+       && [ "$CMP_TYPES" = "false" ] \
+       && [ "$CMP_PERMS" = "false" ] \
+       && [ "$CMP_GENERAL" = "false" ] \
+       && [ "$CMP_ZIPS" = "false" ] \
+       && [ "$CMP_JARS" = "false" ] \
+       && [ "$CMP_JMODS" = "false" ] \
+       && [ "$CMP_LIBS" = "false" ] \
+       && [ "$CMP_EXECS" = "false" ]; then
     CMP_NAMES=true
     CMP_PERMS=true
     CMP_TYPES=true
     CMP_GENERAL=true
     CMP_ZIPS=true
     CMP_JARS=true
+    CMP_JMODS=true
     CMP_LIBS=true
     CMP_EXECS=true
 fi
@@ -1373,6 +1465,7 @@
         OTHER_JDK="$OTHER/images/jdk"
         # Rewrite the path to tools that are used from the build
         JIMAGE="$(echo "$JIMAGE" | $SED "s|$OLD_THIS|$THIS|g")"
+        JMOD="$(echo "$JMOD" | $SED "s|$OLD_THIS|$THIS|g")"
         JAVAP="$(echo "$JAVAP" | $SED "s|$OLD_THIS|$THIS|g")"
     else
         echo "No common images found."
@@ -1613,6 +1706,15 @@
     fi
 fi
 
+if [ "$CMP_JMODS" = "true" ]; then
+    if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
+        compare_all_jmod_files $THIS_JDK $OTHER_JDK $COMPARE_ROOT/jdk
+    fi
+    if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then
+        compare_all_jmod_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir
+    fi
+fi
+
 if [ "$CMP_PERMS" = "true" ]; then
     if [ -n "$THIS_JDK" ] && [ -n "$OTHER_JDK" ]; then
         echo -n "JDK "
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -34,7 +34,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/monitorChunk.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -137,11 +137,6 @@
 // frame.
 inline intptr_t* frame::id(void) const { return unextended_sp(); }
 
-// Relationals on frames based
-// Return true if the frame is younger (more recent activation) than the frame represented by id
-inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
-                                                    return this->id() < id ; }
-
 // Return true if the frame is older (less recent activation) than the frame represented by id
 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
                                                     return this->id() > id ; }
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -2720,7 +2720,7 @@
   {
     Label notVolatile;
     __ tbz(r5, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
-    __ membar(MacroAssembler::StoreStore);
+    __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore);
     __ bind(notVolatile);
   }
 
--- a/src/hotspot/cpu/arm/frame_arm.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/arm/frame_arm.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -32,6 +32,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/arm/frame_arm.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/arm/frame_arm.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -120,17 +120,11 @@
 // frame.
 inline intptr_t* frame::id(void) const { return unextended_sp(); }
 
-// Relationals on frames based
-// Return true if the frame is younger (more recent activation) than the frame represented by id
-inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
-                                                    return this->id() < id ; }
-
 // Return true if the frame is older (less recent activation) than the frame represented by id
 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
                                                     return this->id() > id ; }
 
 
-
 inline intptr_t* frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
 
 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
--- a/src/hotspot/cpu/ppc/frame_ppc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/ppc/frame_ppc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -34,6 +34,7 @@
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/s390/frame_s390.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/s390/frame_s390.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -32,6 +32,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/s390/frame_s390.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/s390/frame_s390.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -111,14 +111,6 @@
   return _fp;
 }
 
-// Return true if this frame is younger (more recent activation) than
-// the frame represented by id.
-inline bool frame::is_younger(intptr_t* id) const {
-  assert(this->id() != NULL && id != NULL, "NULL frame id");
-  // Stack grows towards smaller addresses on z/Architecture.
-  return this->id() < id;
-}
-
 // Return true if this frame is older (less recent activation) than
 // the frame represented by id.
 inline bool frame::is_older(intptr_t* id) const {
--- a/src/hotspot/cpu/sparc/frame_sparc.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/sparc/frame_sparc.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -57,11 +57,6 @@
 // frame.
 inline intptr_t* frame::id(void) const { return unextended_sp(); }
 
-// Relationals on frames based
-// Return true if the frame is younger (more recent activation) than the frame represented by id
-inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
-                                                    return this->id() < id ; }
-
 // Return true if the frame is older (less recent activation) than the frame represented by id
 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
                                                     return this->id() > id ; }
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -4219,7 +4219,7 @@
     // save F48:F54 in temp registers
     __ movdtox(F54,G2);
     __ movdtox(F52,G3);
-    __ movdtox(F50,G6);
+    __ movdtox(F50,L6);
     __ movdtox(F48,G1);
     for ( int i = 46;  i >= 14; i -= 8 ) {
       __ aes_dround23(as_FloatRegister(i), F0, F2, F4);
@@ -4247,7 +4247,7 @@
     // re-init F48:F54 with their original values
     __ movxtod(G2,F54);
     __ movxtod(G3,F52);
-    __ movxtod(G6,F50);
+    __ movxtod(L6,F50);
     __ movxtod(G1,F48);
 
     __ movxtod(L0,F6);
--- a/src/hotspot/cpu/x86/frame_x86.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -133,11 +133,6 @@
 // frame.
 inline intptr_t* frame::id(void) const { return unextended_sp(); }
 
-// Relationals on frames based
-// Return true if the frame is younger (more recent activation) than the frame represented by id
-inline bool frame::is_younger(intptr_t* id) const { assert(this->id() != NULL && id != NULL, "NULL frame id");
-                                                    return this->id() < id ; }
-
 // Return true if the frame is older (less recent activation) than the frame represented by id
 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
                                                     return this->id() > id ; }
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -278,20 +278,21 @@
 
   Register ref = stub->ref()->as_register();
   Register ref_addr = noreg;
+  Register tmp = noreg;
 
-  if (stub->ref_addr()->is_register()) {
-    // Address already in register
-    ref_addr = stub->ref_addr()->as_pointer_register();
-  } else {
+  if (stub->tmp()->is_valid()) {
     // Load address into tmp register
     ce->leal(stub->ref_addr(), stub->tmp());
-    ref_addr = stub->tmp()->as_pointer_register();
+    ref_addr = tmp = stub->tmp()->as_pointer_register();
+  } else {
+    // Address already in register
+    ref_addr = stub->ref_addr()->as_address_ptr()->base()->as_pointer_register();
   }
 
   assert_different_registers(ref, ref_addr, noreg);
 
-  // Save rax unless it is the result register
-  if (ref != rax) {
+  // Save rax unless it is the result or tmp register
+  if (ref != rax && tmp != rax) {
     __ push(rax);
   }
 
@@ -305,9 +306,13 @@
   // Verify result
   __ verify_oop(rax, "Bad oop");
 
-  // Restore rax unless it is the result register
+  // Move result into place
   if (ref != rax) {
     __ movptr(ref, rax);
+  }
+
+  // Restore rax unless it is the result or tmp register
+  if (ref != rax && tmp != rax) {
     __ pop(rax);
   }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad	Mon Feb 04 11:01:04 2019 +0530
@@ -0,0 +1,155 @@
+//
+// Copyright (c) 2015, 2019, 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.
+//
+
+source %{
+
+#include "gc/z/zBarrierSetAssembler.hpp"
+
+static void z_load_barrier_slow_reg(MacroAssembler& _masm, Register dst, Address src, bool weak) {
+  assert(dst != r12, "Invalid register");
+  assert(dst != r15, "Invalid register");
+  assert(dst != rsp, "Invalid register");
+
+  const address stub = weak ? ZBarrierSet::assembler()->load_barrier_weak_slow_stub(dst)
+                            : ZBarrierSet::assembler()->load_barrier_slow_stub(dst);
+  __ lea(dst, src);
+  __ call(RuntimeAddress(stub));
+}
+
+%}
+
+// For XMM and YMM enabled processors
+instruct zLoadBarrierSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
+                                      rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+                                      rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+                                      rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+                                      rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+
+  match(Set dst (LoadBarrierSlowReg src));
+  predicate(UseAVX <= 2);
+
+  effect(DEF dst, KILL cr,
+         KILL x0, KILL x1, KILL x2, KILL x3,
+         KILL x4, KILL x5, KILL x6, KILL x7,
+         KILL x8, KILL x9, KILL x10, KILL x11,
+         KILL x12, KILL x13, KILL x14, KILL x15);
+
+  format %{ "zLoadBarrierSlowRegXmmAndYmm $dst, $src" %}
+
+  ins_encode %{
+    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+// For ZMM enabled processors
+instruct zLoadBarrierSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
+                                rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+                                rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+                                rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+                                rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
+                                rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
+                                rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
+                                rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
+                                rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+
+  match(Set dst (LoadBarrierSlowReg src));
+  predicate(UseAVX == 3);
+
+  effect(DEF dst, KILL cr,
+         KILL x0, KILL x1, KILL x2, KILL x3,
+         KILL x4, KILL x5, KILL x6, KILL x7,
+         KILL x8, KILL x9, KILL x10, KILL x11,
+         KILL x12, KILL x13, KILL x14, KILL x15,
+         KILL x16, KILL x17, KILL x18, KILL x19,
+         KILL x20, KILL x21, KILL x22, KILL x23,
+         KILL x24, KILL x25, KILL x26, KILL x27,
+         KILL x28, KILL x29, KILL x30, KILL x31);
+
+  format %{ "zLoadBarrierSlowRegZmm $dst, $src" %}
+
+  ins_encode %{
+    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+// For XMM and YMM enabled processors
+instruct zLoadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
+                                          rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+                                          rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+                                          rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+                                          rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
+
+  match(Set dst (LoadBarrierWeakSlowReg src));
+  predicate(UseAVX <= 2);
+
+  effect(DEF dst, KILL cr,
+         KILL x0, KILL x1, KILL x2, KILL x3,
+         KILL x4, KILL x5, KILL x6, KILL x7,
+         KILL x8, KILL x9, KILL x10, KILL x11,
+         KILL x12, KILL x13, KILL x14, KILL x15);
+
+  format %{ "zLoadBarrierWeakSlowRegXmmAndYmm $dst, $src" %}
+
+  ins_encode %{
+    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+// For ZMM enabled processors
+instruct zLoadBarrierWeakSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
+                                    rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
+                                    rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
+                                    rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
+                                    rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
+                                    rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
+                                    rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
+                                    rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
+                                    rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+
+  match(Set dst (LoadBarrierWeakSlowReg src));
+  predicate(UseAVX == 3);
+
+  effect(DEF dst, KILL cr,
+         KILL x0, KILL x1, KILL x2, KILL x3,
+         KILL x4, KILL x5, KILL x6, KILL x7,
+         KILL x8, KILL x9, KILL x10, KILL x11,
+         KILL x12, KILL x13, KILL x14, KILL x15,
+         KILL x16, KILL x17, KILL x18, KILL x19,
+         KILL x20, KILL x21, KILL x22, KILL x23,
+         KILL x24, KILL x25, KILL x26, KILL x27,
+         KILL x28, KILL x29, KILL x30, KILL x31);
+
+  format %{ "zLoadBarrierWeakSlowRegZmm $dst, $src" %}
+
+  ins_encode %{
+    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
+  %}
+
+  ins_pipe(pipe_slow);
+%}
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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
@@ -3709,8 +3709,6 @@
     // Round to nearest, 24-bit mode, exceptions masked
     StubRoutines::_fpu_cntrl_wrd_24    = 0x007F;
     // Round to nearest, 64-bit mode, exceptions masked
-    StubRoutines::_fpu_cntrl_wrd_64    = 0x037F;
-    // Round to nearest, 64-bit mode, exceptions masked
     StubRoutines::_mxcsr_std           = 0x1F80;
     // Note: the following two constants are 80-bit values
     //       layout is critical for correct loading by FPU.
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -5721,8 +5721,6 @@
     // Round to nearest, 24-bit mode, exceptions masked
     StubRoutines::_fpu_cntrl_wrd_24    = 0x007F;
     // Round to nearest, 64-bit mode, exceptions masked
-    StubRoutines::_fpu_cntrl_wrd_64    = 0x037F;
-    // Round to nearest, 64-bit mode, exceptions masked
     StubRoutines::_mxcsr_std           = 0x1F80;
     // Note: the following two constants are 80-bit values
     //       layout is critical for correct loading by FPU.
--- a/src/hotspot/cpu/x86/x86.ad	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/x86.ad	Mon Feb 04 11:01:04 2019 +0530
@@ -1685,26 +1685,24 @@
     case Op_VecS: // copy whole register
     case Op_VecD:
     case Op_VecX:
-#ifndef LP64
+#ifndef _LP64
       __ movdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
 #else
       if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
         __ movdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
       } else {
-        __ vpxor(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[dst_lo]), 2);
-        __ vinserti32x4(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 0x0);
+        __ vextractf32x4(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 0x0);
      }
 #endif
       break;
     case Op_VecY:
-#ifndef LP64
+#ifndef _LP64
       __ vmovdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
 #else
       if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
         __ vmovdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
       } else {
-        __ vpxor(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[dst_lo]), 2);
-        __ vinserti64x4(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 0x0);
+        __ vextractf64x4(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]), 0x0);
      }
 #endif
       break;
@@ -1758,26 +1756,26 @@
         __ movq(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
         break;
       case Op_VecX:
-#ifndef LP64
+#ifndef _LP64
         __ movdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
 #else
         if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
           __ movdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
         } else {
-          __ vpxor(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 2);
-          __ vinserti32x4(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset),0x0);
+          __ vpxor(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 2);
+          __ vinsertf32x4(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset),0x0);
         }
 #endif
         break;
       case Op_VecY:
-#ifndef LP64
+#ifndef _LP64
         __ vmovdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
 #else
         if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
           __ vmovdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
         } else {
-          __ vpxor(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 2);
-          __ vinserti64x4(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset),0x0);
+          __ vpxor(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 2);
+          __ vinsertf64x4(as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset),0x0);
         }
 #endif
         break;
@@ -1796,26 +1794,26 @@
         __ movq(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
         break;
       case Op_VecX:
-#ifndef LP64
+#ifndef _LP64
         __ movdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
 #else
         if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
           __ movdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
         }
         else {
-          __ vextracti32x4(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 0x0);
+          __ vextractf32x4(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), 0x0);
         }
 #endif
         break;
       case Op_VecY:
-#ifndef LP64
+#ifndef _LP64
         __ vmovdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
 #else
         if ((UseAVX < 3) || VM_Version::supports_avx512vl()) {
           __ vmovdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
         }
         else {
-          __ vextracti64x4(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), as_XMMRegister(Matcher::_regEncode[reg]), 0x0);
+          __ vextractf64x4(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]), 0x0);
         }
 #endif
         break;
--- a/src/hotspot/cpu/x86/x86_64.ad	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/x86/x86_64.ad	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2019, 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
@@ -526,12 +526,6 @@
 
 %}
 
-source_hpp %{
-#if INCLUDE_ZGC
-#include "gc/z/zBarrierSetAssembler.hpp"
-#endif
-%}
-
 //----------SOURCE BLOCK-------------------------------------------------------
 // This is a block of C++ code which provides values, functions, and
 // definitions necessary in the rest of the architecture description
@@ -12711,170 +12705,6 @@
   ins_pipe(pipe_jmp);
 %}
 
-//
-// Execute ZGC load barrier (strong) slow path
-//
-
-// For XMM and YMM enabled processors
-instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr,
-                                     rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
-                                     rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                     rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                     rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
-
-  match(Set dst (LoadBarrierSlowReg mem));
-  predicate(UseAVX <= 2);
-
-  effect(DEF dst, KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15);
-
-  format %{"LoadBarrierSlowRegXmmAndYmm $dst, $mem" %}
-  ins_encode %{
-#if INCLUDE_ZGC
-    Register d = $dst$$Register;
-    ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
-
-    assert(d != r12, "Can't be R12!");
-    assert(d != r15, "Can't be R15!");
-    assert(d != rsp, "Can't be RSP!");
-
-    __ lea(d, $mem$$Address);
-    __ call(RuntimeAddress(bs->load_barrier_slow_stub(d)));
-#else
-    ShouldNotReachHere();
-#endif
-  %}
-  ins_pipe(pipe_slow);
-%}
-
-// For ZMM enabled processors
-instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr,
-                               rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
-                               rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                               rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                               rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
-                               rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
-                               rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
-                               rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
-                               rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
-
-  match(Set dst (LoadBarrierSlowReg mem));
-  predicate(UseAVX == 3);
-
-  effect(DEF dst, KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15,
-         KILL x16, KILL x17, KILL x18, KILL x19,
-         KILL x20, KILL x21, KILL x22, KILL x23,
-         KILL x24, KILL x25, KILL x26, KILL x27,
-         KILL x28, KILL x29, KILL x30, KILL x31);
-
-  format %{"LoadBarrierSlowRegZmm $dst, $mem" %}
-  ins_encode %{
-#if INCLUDE_ZGC
-    Register d = $dst$$Register;
-    ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
-
-    assert(d != r12, "Can't be R12!");
-    assert(d != r15, "Can't be R15!");
-    assert(d != rsp, "Can't be RSP!");
-
-    __ lea(d, $mem$$Address);
-    __ call(RuntimeAddress(bs->load_barrier_slow_stub(d)));
-#else
-    ShouldNotReachHere();
-#endif
-  %}
-  ins_pipe(pipe_slow);
-%}
-
-//
-// Execute ZGC load barrier (weak) slow path
-//
-
-// For XMM and YMM enabled processors
-instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr,
-                                         rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
-                                         rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                         rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                         rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
-
-  match(Set dst (LoadBarrierWeakSlowReg mem));
-  predicate(UseAVX <= 2);
-
-  effect(DEF dst, KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15);
-
-  format %{"LoadBarrierWeakSlowRegXmmAndYmm $dst, $mem" %}
-  ins_encode %{
-#if INCLUDE_ZGC
-    Register d = $dst$$Register;
-    ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
-
-    assert(d != r12, "Can't be R12!");
-    assert(d != r15, "Can't be R15!");
-    assert(d != rsp, "Can't be RSP!");
-
-    __ lea(d,$mem$$Address);
-    __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d)));
-#else
-    ShouldNotReachHere();
-#endif
-  %}
-  ins_pipe(pipe_slow);
-%}
-
-// For ZMM enabled processors
-instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr,
-                                   rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3,
-                                   rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                   rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                   rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
-                                   rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
-                                   rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
-                                   rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
-                                   rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
-
-  match(Set dst (LoadBarrierWeakSlowReg mem));
-  predicate(UseAVX == 3);
-
-  effect(DEF dst, KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15,
-         KILL x16, KILL x17, KILL x18, KILL x19,
-         KILL x20, KILL x21, KILL x22, KILL x23,
-         KILL x24, KILL x25, KILL x26, KILL x27,
-         KILL x28, KILL x29, KILL x30, KILL x31);
-
-  format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %}
-  ins_encode %{
-#if INCLUDE_ZGC
-    Register d = $dst$$Register;
-    ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
-
-    assert(d != r12, "Can't be R12!");
-    assert(d != r15, "Can't be R15!");
-    assert(d != rsp, "Can't be RSP!");
-
-    __ lea(d,$mem$$Address);
-    __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d)));
-#else
-    ShouldNotReachHere();
-#endif
-  %}
-  ins_pipe(pipe_slow);
-%}
-
 // ============================================================================
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -41,6 +41,7 @@
 #include "runtime/atomic.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/orderAccess.hpp"
--- a/src/hotspot/os/linux/os_linux.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os/linux/os_linux.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1856,6 +1856,36 @@
   return true;
 }
 
+#if defined(S390)
+// keywords_to_match - NULL terminated array of keywords
+static bool print_matching_lines_from_sysinfo_file(outputStream* st, const char* keywords_to_match[]) {
+  const char* filename = "/proc/sysinfo";
+  char* line = NULL;
+  size_t length = 0;
+  FILE* fp = fopen(filename, "r");
+  if (fp == NULL) {
+    return false;
+  }
+
+  st->print_cr("Virtualization information:");
+  while (getline(&line, &length, fp) != -1) {
+    int i = 0;
+    while (keywords_to_match[i] != NULL) {
+      if (strncmp(line, keywords_to_match[i], strlen(keywords_to_match[i])) == 0) {
+        st->print("%s", line);
+        break;
+      }
+      i++;
+    }
+  }
+
+  free(line);
+  fclose(fp);
+
+  return true;
+}
+#endif
+
 void os::print_dll_info(outputStream *st) {
   st->print_cr("Dynamic libraries:");
 
@@ -1939,6 +1969,8 @@
   os::Linux::print_ld_preload_file(st);
 
   os::Linux::print_container_info(st);
+
+  os::Linux::print_virtualization_info(st);
 }
 
 // Try to identify popular distros.
@@ -2152,6 +2184,20 @@
   st->cr();
 }
 
+void os::Linux::print_virtualization_info(outputStream* st) {
+#if defined(S390)
+  // /proc/sysinfo contains interesting information about
+  // - LPAR
+  // - whole "Box" (CPUs )
+  // - z/VM / KVM (VM<nn>); this is not available in an LPAR-only setup
+  const char* kw[] = { "LPAR", "CPUs", "VM", NULL };
+
+  if (! print_matching_lines_from_sysinfo_file(st, kw)) {
+    st->print_cr("  </proc/sysinfo Not Available>");
+  }
+#endif
+}
+
 void os::print_memory_info(outputStream* st) {
 
   st->print("Memory:");
--- a/src/hotspot/os/linux/os_linux.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os/linux/os_linux.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -110,6 +110,7 @@
 
   static void print_full_memory_info(outputStream* st);
   static void print_container_info(outputStream* st);
+  static void print_virtualization_info(outputStream* st);
   static void print_distro_info(outputStream* st);
   static void print_libversion_info(outputStream* st);
   static void print_proc_sys_info(outputStream* st);
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -561,8 +561,7 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Aix::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4);
+  print_instructions(st, pc, /*instrsize=*/4);
   st->cr();
 
   // Try to decode the instructions.
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1021,8 +1021,8 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Bsd::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", (intptr_t)pc);
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -606,8 +606,8 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -543,8 +543,8 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc - 32, pc + 32, Assembler::InstructionSize);
+  print_instructions(st, pc, Assembler::InstructionSize);
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -574,8 +574,7 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4);
+  print_instructions(st, pc, /*instrsize=*/4);
   st->cr();
 }
 
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -605,9 +605,7 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  if (Verbose) { st->print_cr("pc at " PTR_FORMAT, p2i(pc)); }
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc-64, pc+64, /*intrsize=*/4);
+  print_instructions(st, pc, /*intrsize=*/4);
   st->cr();
 }
 
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -232,8 +232,8 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -755,8 +755,8 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = os::Linux::ucontext_get_pc(uc);
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -655,8 +655,8 @@
   // this at the end, and hope for the best.
   ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   address pc = epc.pc();
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -779,8 +779,8 @@
   // this at the end, and hope for the best.
   ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   address pc = epc.pc();
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
+  st->cr();
 }
 
 void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -585,8 +585,7 @@
   // point to garbage if entry point in an nmethod is corrupted. Leave
   // this at the end, and hope for the best.
   address pc = (address)uc->REG_PC;
-  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
-  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  print_instructions(st, pc, sizeof(char));
   st->cr();
 }
 
--- a/src/hotspot/share/aot/aotLoader.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/aot/aotLoader.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 #include "memory/allocation.inline.hpp"
 #include "oops/method.hpp"
 #include "runtime/handles.inline.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
 #include "runtime/timerTrace.hpp"
 
 GrowableArray<AOTCodeHeap*>* AOTLoader::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTCodeHeap*> (2, true);
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1942,7 +1942,8 @@
       // Use CHA on the receiver to select a more precise method.
       cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
     } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
-      // if there is only one implementor of this interface then we
+      assert(callee_holder->is_interface(), "invokeinterface to non interface?");
+      // If there is only one implementor of this interface then we
       // may be able bind this invoke directly to the implementing
       // klass but we need both a dependence on the single interface
       // and on the method we bind to.  Additionally since all we know
@@ -1950,53 +1951,44 @@
       // interface we have to insert a check that it's the class we
       // expect.  Interface types are not checked by the verifier so
       // they are roughly equivalent to Object.
+      // The number of implementors for declared_interface is less or
+      // equal to the number of implementors for target->holder() so
+      // if number of implementors of target->holder() == 1 then
+      // number of implementors for decl_interface is 0 or 1. If
+      // it's 0 then no class implements decl_interface and there's
+      // no point in inlining.
       ciInstanceKlass* singleton = NULL;
-      if (target->holder()->nof_implementors() == 1) {
-        singleton = target->holder()->implementor();
-        assert(singleton != NULL && singleton != target->holder(),
-               "just checking");
-
-        assert(holder->is_interface(), "invokeinterface to non interface?");
-        ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder;
-        // the number of implementors for decl_interface is less or
-        // equal to the number of implementors for target->holder() so
-        // if number of implementors of target->holder() == 1 then
-        // number of implementors for decl_interface is 0 or 1. If
-        // it's 0 then no class implements decl_interface and there's
-        // no point in inlining.
-        if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_nonstatic_concrete_methods()) {
-          singleton = NULL;
-        }
-      }
-      if (singleton) {
-        cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
+      ciInstanceKlass* declared_interface = callee_holder;
+      if (declared_interface->nof_implementors() == 1 &&
+          (!target->is_default_method() || target->is_overpass()) /* CHA doesn't support default methods yet. */) {
+        singleton = declared_interface->implementor();
+        assert(singleton != NULL && singleton != declared_interface, "");
+        cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
         if (cha_monomorphic_target != NULL) {
-          // If CHA is able to bind this invoke then update the class
-          // to match that class, otherwise klass will refer to the
-          // interface.
-          klass = cha_monomorphic_target->holder();
-          actual_recv = target->holder();
-
-          // insert a check it's really the expected class.
-          CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
-          c->set_incompatible_class_change_check();
-          c->set_direct_compare(klass->is_final());
-          // pass the result of the checkcast so that the compiler has
-          // more accurate type info in the inlinee
-          better_receiver = append_split(c);
+          if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
+            // If CHA is able to bind this invoke then update the class
+            // to match that class, otherwise klass will refer to the
+            // interface.
+            klass = cha_monomorphic_target->holder();
+            actual_recv = declared_interface;
+
+            // insert a check it's really the expected class.
+            CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
+            c->set_incompatible_class_change_check();
+            c->set_direct_compare(klass->is_final());
+            // pass the result of the checkcast so that the compiler has
+            // more accurate type info in the inlinee
+            better_receiver = append_split(c);
+          } else {
+            cha_monomorphic_target = NULL; // subtype check against Object is useless
+          }
         }
       }
     }
   }
 
   if (cha_monomorphic_target != NULL) {
-    if (cha_monomorphic_target->is_abstract()) {
-      // Do not optimize for abstract methods
-      cha_monomorphic_target = NULL;
-    }
-  }
-
-  if (cha_monomorphic_target != NULL) {
+    assert(!cha_monomorphic_target->is_abstract(), "");
     if (!(target->is_final_method())) {
       // If we inlined because CHA revealed only a single target method,
       // then we are dependent on that target method not getting overridden
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/sharedRuntime.hpp"
--- a/src/hotspot/share/ci/ciArray.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciArray.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -73,7 +73,6 @@
 
   // What kind of ciObject is this?
   bool is_array()        { return true; }
-  bool is_java_object()  { return true; }
 };
 
 #endif // SHARE_CI_CIARRAY_HPP
--- a/src/hotspot/share/ci/ciCallProfile.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciCallProfile.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -79,17 +79,6 @@
     assert(i < _limit, "out of Call Profile MorphismLimit");
     return _receiver[i];
   }
-
-  // Rescale the current profile based on the incoming scale
-  ciCallProfile rescale(double scale) {
-    assert(scale >= 0 && scale <= 1.0, "out of range");
-    ciCallProfile call = *this;
-    call._count = (int)(call._count * scale);
-    for (int i = 0; i < _morphism; i++) {
-      call._receiver_count[i] = (int)(call._receiver_count[i] * scale);
-    }
-    return call;
-  }
 };
 
 #endif // SHARE_CI_CICALLPROFILE_HPP
--- a/src/hotspot/share/ci/ciCallSite.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciCallSite.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,12 +32,6 @@
 bool ciCallSite::is_constant_call_site() {
   return klass()->is_subclass_of(CURRENT_ENV->ConstantCallSite_klass());
 }
-bool ciCallSite::is_mutable_call_site() {
-  return klass()->is_subclass_of(CURRENT_ENV->MutableCallSite_klass());
-}
-bool ciCallSite::is_volatile_call_site() {
-  return klass()->is_subclass_of(CURRENT_ENV->VolatileCallSite_klass());
-}
 
 // ------------------------------------------------------------------
 // ciCallSite::get_target
--- a/src/hotspot/share/ci/ciCallSite.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciCallSite.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -38,8 +38,6 @@
   bool is_call_site() const { return true; }
 
   bool is_constant_call_site();
-  bool is_mutable_call_site();
-  bool is_volatile_call_site();
 
   // Return the target MethodHandle of this CallSite.
   ciMethodHandle* get_target() const;
--- a/src/hotspot/share/ci/ciEnv.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciEnv.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -55,6 +55,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/ci/ciInstanceKlass.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciInstanceKlass.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -72,7 +72,7 @@
   // The possible values of the _implementor fall into following three cases:
   //   NULL: no implementor.
   //   A ciInstanceKlass that's not itself: one implementor.
-  //   Itsef: more than one implementors.
+  //   Itself: more than one implementor.
   ciInstanceKlass*       _implementor;
 
   void compute_injected_fields();
--- a/src/hotspot/share/ci/ciMethod.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciMethod.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -46,6 +46,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/deoptimization.hpp"
+#include "runtime/handles.inline.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/xmlstream.hpp"
 #ifdef COMPILER2
@@ -89,6 +90,7 @@
   _is_c2_compilable   = !h_m()->is_not_c2_compilable();
   _can_be_parsed      = true;
   _has_reserved_stack_access = h_m()->has_reserved_stack_access();
+  _is_overpass        = h_m()->is_overpass();
   // Lazy fields, filled in on demand.  Require allocation.
   _code               = NULL;
   _exception_handlers = NULL;
@@ -718,7 +720,7 @@
   VM_ENTRY_MARK;
 
   // Disable CHA for default methods for now
-  if (root_m->get_Method()->is_default_method()) {
+  if (root_m->is_default_method()) {
     return NULL;
   }
 
@@ -758,6 +760,7 @@
     // with the same name but different vtable indexes.
     return NULL;
   }
+  assert(!target()->is_abstract(), "not allowed");
   return CURRENT_THREAD_ENV->get_method(target());
 }
 
@@ -874,6 +877,14 @@
 }
 
 // ------------------------------------------------------------------
+ciKlass* ciMethod::get_declared_method_holder_at_bci(int bci) {
+  ciBytecodeStream iter(this);
+  iter.reset_to_bci(bci);
+  iter.next();
+  return iter.get_declared_method_holder();
+}
+
+// ------------------------------------------------------------------
 // Adjust a CounterData count to be commensurate with
 // interpreter_invocation_count.  If the MDO exists for
 // only 25% of the time the method exists, then the
--- a/src/hotspot/share/ci/ciMethod.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciMethod.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -89,6 +89,7 @@
   bool _can_be_parsed;
   bool _can_be_statically_bound;
   bool _has_reserved_stack_access;
+  bool _is_overpass;
 
   // Lazy fields, filled in on demand
   address              _code;
@@ -265,6 +266,8 @@
     return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature);
   }
 
+  ciKlass*      get_declared_method_holder_at_bci(int bci);
+
   ciSignature*  get_declared_signature_at_bci(int bci) {
     bool ignored_will_link;
     ciSignature* declared_signature;
@@ -333,6 +336,9 @@
   bool is_empty_method() const;
   bool is_vanilla_constructor() const;
   bool is_final_method() const                   { return is_final() || holder()->is_final(); }
+  bool is_default_method() const                 { return !is_abstract() && !is_private() &&
+                                                          holder()->is_interface(); }
+  bool is_overpass    () const                   { check_is_loaded(); return _is_overpass; }
   bool has_loops      () const;
   bool has_jsrs       () const;
   bool is_getter      () const;
--- a/src/hotspot/share/ci/ciMethodData.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciMethodData.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -208,15 +208,17 @@
   // Snapshot the data -- actually, take an approximate snapshot of
   // the data.  Any concurrently executing threads may be changing the
   // data as we copy it.
-  Copy::disjoint_words((HeapWord*) mdo,
-                       (HeapWord*) &_orig,
-                       sizeof(_orig) / HeapWordSize);
+  Copy::disjoint_words_atomic((HeapWord*) mdo,
+                              (HeapWord*) &_orig,
+                              sizeof(_orig) / HeapWordSize);
   Arena* arena = CURRENT_ENV->arena();
   _data_size = mdo->data_size();
   _extra_data_size = mdo->extra_data_size();
   int total_size = _data_size + _extra_data_size;
   _data = (intptr_t *) arena->Amalloc(total_size);
-  Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
+  Copy::disjoint_words_atomic((HeapWord*) mdo->data_base(),
+                              (HeapWord*) _data,
+                              total_size / HeapWordSize);
 
   // Traverse the profile data, translating any oops into their
   // ci equivalents.
@@ -535,10 +537,6 @@
   set_bits(_eflags, f);
 }
 
-void ciMethodData::clear_eflag(MethodData::EscapeFlag f) {
-  clear_bits(_eflags, f);
-}
-
 bool ciMethodData::eflag_set(MethodData::EscapeFlag f) const {
   return mask_bits(_eflags, f) != 0;
 }
--- a/src/hotspot/share/ci/ciMethodData.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciMethodData.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -271,11 +271,6 @@
     }
   }
 
-  intptr_t argument_type(int i) const {
-    assert(has_arguments(), "no arg type profiling data");
-    return args()->type(i);
-  }
-
   ciKlass* valid_argument_type(int i) const {
     assert(has_arguments(), "no arg type profiling data");
     return args()->valid_type(i);
@@ -315,11 +310,6 @@
   ciBranchData(DataLayout* layout) : BranchData(layout) {};
 };
 
-class ciArrayData : public ArrayData {
-public:
-  ciArrayData(DataLayout* layout) : ArrayData(layout) {};
-};
-
 class ciMultiBranchData : public MultiBranchData {
 public:
   ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {};
@@ -471,10 +461,6 @@
 
   ciArgInfoData *arg_info() const;
 
-  address data_base() const {
-    return (address) _data;
-  }
-
   void prepare_metadata();
   void load_extra_data();
   ciProfileData* bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots);
@@ -574,7 +560,6 @@
   void update_escape_info();
 
   void set_eflag(MethodData::EscapeFlag f);
-  void clear_eflag(MethodData::EscapeFlag f);
   bool eflag_set(MethodData::EscapeFlag f) const;
 
   void set_arg_local(int i);
--- a/src/hotspot/share/ci/ciNullObject.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciNullObject.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -42,9 +42,6 @@
   void print_impl(outputStream* st);
 
 public:
-  // Is this ciObject a Java Language Object?  That is,
-  // is the ciObject an instance or an array
-  bool is_java_object() { return true; }
 
   // What kind of ciObject is this?
   bool is_null_object() const { return true; }
--- a/src/hotspot/share/ci/ciObject.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciObject.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -115,7 +115,6 @@
   // What kind of ciObject is this?
   virtual bool is_null_object()       const { return false; }
   virtual bool is_call_site()         const { return false; }
-  virtual bool is_cpcache()           const { return false; }
   virtual bool is_instance()                { return false; }
   virtual bool is_member_name()       const { return false; }
   virtual bool is_method_handle()     const { return false; }
--- a/src/hotspot/share/ci/ciReplay.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciReplay.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
 #include "oops/method.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
 
--- a/src/hotspot/share/ci/ciStreams.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciStreams.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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
@@ -224,14 +224,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciBytecodeStream::get_constant_cache_index
-// Return the CP cache index, or -1 if there isn't any.
-int ciBytecodeStream::get_constant_cache_index() const {
-  // work-alike for Bytecode_loadconstant::cache_index()
-  return has_cache_index() ? get_constant_raw_index() : -1;
-}
-
-// ------------------------------------------------------------------
 // ciBytecodeStream::get_constant
 //
 // If this bytecode is one of the ldc variants, get the referenced
@@ -318,36 +310,12 @@
 }
 
 // ------------------------------------------------------------------
-// ciBytecodeStream::get_field_signature_index
-//
-// Get the constant pool index of the signature of the field
-// referenced by the current bytecode.  Used for generating
-// deoptimization information.
-int ciBytecodeStream::get_field_signature_index() {
-  VM_ENTRY_MARK;
-  ConstantPool* cpool = _holder->get_instanceKlass()->constants();
-  int nt_index = cpool->name_and_type_ref_index_at(get_field_index());
-  return cpool->signature_ref_index_at(nt_index);
-}
-
-// ------------------------------------------------------------------
 // ciBytecodeStream::get_method_index
 //
 // If this is a method invocation bytecode, get the constant pool
 // index of the invoked method.
 int ciBytecodeStream::get_method_index() {
-#ifdef ASSERT
-  switch (cur_bc()) {
-  case Bytecodes::_invokeinterface:
-  case Bytecodes::_invokevirtual:
-  case Bytecodes::_invokespecial:
-  case Bytecodes::_invokestatic:
-  case Bytecodes::_invokedynamic:
-    break;
-  default:
-    ShouldNotReachHere();
-  }
-#endif
+  assert(Bytecodes::is_invoke(cur_bc()), "invalid bytecode: %s", Bytecodes::name(cur_bc()));
   if (has_index_u4())
     return get_index_u4();  // invokedynamic
   return get_index_u2_cpcache();
@@ -474,13 +442,3 @@
   )
 }
 
-// ------------------------------------------------------------------
-// ciBytecodeStream::get_resolved_references
-ciObjArray* ciBytecodeStream::get_resolved_references() {
-    VM_ENTRY_MARK;
-    // Get the constant pool.
-  ConstantPool*        cpool   = _holder->get_instanceKlass()->constants();
-
-  // Create a resolved references array and return it.
-  return CURRENT_ENV->get_object(cpool->resolved_references())->as_obj_array();
-  }
--- a/src/hotspot/share/ci/ciStreams.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciStreams.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -70,12 +70,6 @@
     _start = _pc = base; _end = base + size;
   }
 
-  void assert_wide(bool require_wide) const {
-    if (require_wide)
-         { assert(is_wide(),  "must be a wide instruction"); }
-    else { assert(!is_wide(), "must not be a wide instruction"); }
-  }
-
   Bytecode bytecode() const { return Bytecode(this, _bc_start); }
   Bytecode next_bytecode() const { return Bytecode(this, _pc); }
 
@@ -155,10 +149,6 @@
     return bytecode().get_index_u1(cur_bc_raw());
   }
 
-  int get_index_u1_cpcache() const {
-    return bytecode().get_index_u1_cpcache(cur_bc_raw());
-  }
-
   // Get a byte index following this bytecode.
   // If prefixed with a wide bytecode, get a wide index.
   int get_index() const {
@@ -218,16 +208,12 @@
   int get_int_table( int index ) const {
     return Bytes::get_Java_u4((address)&_table_base[index]); }
 
-  // For tableswitch - get length of offset part
-  int get_tableswitch_length()  { return get_int_table(2)-get_int_table(1)+1; }
-
   int get_dest_table( int index ) const {
     return cur_bci() + get_int_table(index); }
 
   // --- Constant pool access ---
   int get_constant_raw_index() const;
   int get_constant_pool_index() const;
-  int get_constant_cache_index() const;
   int get_field_index();
   int get_method_index();
 
@@ -255,7 +241,6 @@
 
   ciInstanceKlass* get_declared_field_holder();
   int      get_field_holder_index();
-  int      get_field_signature_index();
 
   ciMethod*     get_method(bool& will_link, ciSignature* *declared_signature_result);
   bool          has_appendix();
@@ -266,8 +251,6 @@
   int           get_method_holder_index();
   int           get_method_signature_index(const constantPoolHandle& cpool);
 
-  // Get the resolved references arrays from the constant pool
-  ciObjArray* get_resolved_references();
 };
 
 
--- a/src/hotspot/share/ci/ciTypeFlow.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciTypeFlow.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -2427,22 +2427,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciTypeFlow::PostOrderLoops::next
-//
-// Advance to next loop tree using a postorder, left-to-right traversal.
-void ciTypeFlow::PostorderLoops::next() {
-  assert(!done(), "must not be done.");
-  if (_current->sibling() != NULL) {
-    _current = _current->sibling();
-    while (_current->child() != NULL) {
-      _current = _current->child();
-    }
-  } else {
-    _current = _current->parent();
-  }
-}
-
-// ------------------------------------------------------------------
 // ciTypeFlow::PreOrderLoops::next
 //
 // Advance to next loop tree using a preorder, left-to-right traversal.
--- a/src/hotspot/share/ci/ciTypeFlow.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciTypeFlow.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -765,22 +765,6 @@
     void print(outputStream* st = tty, int indent = 0) const PRODUCT_RETURN;
   };
 
-  // Postorder iteration over the loop tree.
-  class PostorderLoops : public StackObj {
-  private:
-    Loop* _root;
-    Loop* _current;
-  public:
-    PostorderLoops(Loop* root) : _root(root), _current(root) {
-      while (_current->child() != NULL) {
-        _current = _current->child();
-      }
-    }
-    bool done() { return _current == NULL; }  // Finished iterating?
-    void next();                            // Advance to next loop
-    Loop* current() { return _current; }      // Return current loop.
-  };
-
   // Preorder iteration over the loop tree.
   class PreorderLoops : public StackObj {
   private:
@@ -857,7 +841,6 @@
   int start_block_num() const       { return 0; }
   Block* rpo_at(int rpo) const      { assert(0 <= rpo && rpo < block_count(), "out of bounds");
                                       return _block_map[rpo]; }
-  int next_pre_order()              { return _next_pre_order; }
   int inc_next_pre_order()          { return _next_pre_order++; }
 
 private:
--- a/src/hotspot/share/ci/ciUtilities.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciUtilities.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,13 +42,6 @@
 }
 
 // ------------------------------------------------------------------
-// basictype_to_char
-const char basictype_to_char(BasicType t) {
-  char c = type2char(t);
-  return c ? c : 'X';
-}
-
-// ------------------------------------------------------------------
 // card_table_base
 jbyte *ci_card_table_address() {
   BarrierSet* bs = BarrierSet::barrier_set();
--- a/src/hotspot/share/ci/ciUtilities.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/ci/ciUtilities.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -49,7 +49,6 @@
 }
 
 const char* basictype_to_str(BasicType t);
-const char  basictype_to_char(BasicType t);
 
 jbyte *ci_card_table_address();
 template <typename T> T ci_card_table_address_as() {
--- a/src/hotspot/share/classfile/classLoader.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/classLoader.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -56,7 +56,6 @@
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
-#include "runtime/handles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
--- a/src/hotspot/share/classfile/dictionary.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/dictionary.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -198,41 +198,6 @@
   }
 }
 
-// During class loading we may have cached a protection domain that has
-// since been unreferenced, so this entry should be cleared.
-void Dictionary::clean_cached_protection_domains(DictionaryEntry* probe) {
-  assert_locked_or_safepoint(SystemDictionary_lock);
-
-  ProtectionDomainEntry* current = probe->pd_set();
-  ProtectionDomainEntry* prev = NULL;
-  while (current != NULL) {
-    if (current->object_no_keepalive() == NULL) {
-      LogTarget(Debug, protectiondomain) lt;
-      if (lt.is_enabled()) {
-        ResourceMark rm;
-        // Print out trace information
-        LogStream ls(lt);
-        ls.print_cr("PD in set is not alive:");
-        ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls);
-        ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls);
-        ls.cr();
-      }
-      if (probe->pd_set() == current) {
-        probe->set_pd_set(current->next());
-      } else {
-        assert(prev != NULL, "should be set by alive entry");
-        prev->set_next(current->next());
-      }
-      ProtectionDomainEntry* to_delete = current;
-      current = current->next();
-      delete to_delete;
-    } else {
-      prev = current;
-      current = current->next();
-    }
-  }
-}
-
 //   Just the classes from defining class loaders
 void Dictionary::classes_do(void f(InstanceKlass*)) {
   for (int index = 0; index < table_size(); index++) {
--- a/src/hotspot/share/classfile/dictionary.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/dictionary.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -51,8 +51,6 @@
 
   DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);
 
-  void clean_cached_protection_domains(DictionaryEntry* probe);
-
 public:
   Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false);
   Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries, bool resizable = false);
--- a/src/hotspot/share/classfile/stringTable.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/stringTable.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -376,68 +376,11 @@
   } while(true);
 }
 
-// GC support
-class StringTableIsAliveCounter : public BoolObjectClosure {
-  BoolObjectClosure* _real_boc;
- public:
-  size_t _count;
-  size_t _count_total;
-  StringTableIsAliveCounter(BoolObjectClosure* boc) : _real_boc(boc), _count(0),
-                                                      _count_total(0) {}
-  bool do_object_b(oop obj) {
-    bool ret = _real_boc->do_object_b(obj);
-    if (!ret) {
-      ++_count;
-    }
-    ++_count_total;
-    return ret;
-  }
-};
-
-void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f,
-                                    size_t* processed, size_t* removed) {
-  DoNothingClosure dnc;
-  assert(is_alive != NULL, "No closure");
-  StringTableIsAliveCounter stiac(is_alive);
-  OopClosure* tmp = f != NULL ? f : &dnc;
-
-  StringTable::the_table()->_weak_handles->weak_oops_do(&stiac, tmp);
-
-  // This is the serial case without ParState.
-  // Just set the correct number and check for a cleaning phase.
-  the_table()->_uncleaned_items_count = stiac._count;
-  StringTable::the_table()->check_concurrent_work();
-
-  if (processed != NULL) {
-    *processed = stiac._count_total;
-  }
-  if (removed != NULL) {
-    *removed = stiac._count;
-  }
-}
-
 void StringTable::oops_do(OopClosure* f) {
   assert(f != NULL, "No closure");
   StringTable::the_table()->_weak_handles->oops_do(f);
 }
 
-void StringTable::possibly_parallel_unlink(
-   OopStorage::ParState<false, false>* _par_state_string, BoolObjectClosure* cl,
-   size_t* processed, size_t* removed)
-{
-  DoNothingClosure dnc;
-  assert(cl != NULL, "No closure");
-  StringTableIsAliveCounter stiac(cl);
-
-  _par_state_string->weak_oops_do(&stiac, &dnc);
-
-  // Accumulate the dead strings.
-  the_table()->add_items_to_clean(stiac._count);
-
-  *processed = stiac._count_total;
-  *removed = stiac._count;
-}
-
 void StringTable::possibly_parallel_oops_do(
    OopStorage::ParState<false /* concurrent */, false /* const */>*
    _par_state_string, OopClosure* f)
@@ -525,7 +468,7 @@
   if ((dead_factor > load_factor) ||
       (load_factor > PREF_AVG_LIST_LEN) ||
       (dead_factor > CLEAN_DEAD_HIGH_WATER_MARK)) {
-    log_debug(stringtable)("Concurrent work triggered, live factor:%g dead factor:%g",
+    log_debug(stringtable)("Concurrent work triggered, live factor: %g dead factor: %g",
                            load_factor, dead_factor);
     trigger_concurrent_work();
   }
--- a/src/hotspot/share/classfile/stringTable.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/stringTable.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -128,20 +128,10 @@
     the_table()->add_items_to_clean(ndead);
   }
 
-  //   Delete pointers to otherwise-unreachable objects.
-  static void unlink(BoolObjectClosure* cl) {
-    unlink_or_oops_do(cl);
-  }
-  static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f = NULL,
-                                size_t* processed = NULL, size_t* removed = NULL);
-
   // Serially invoke "f->do_oop" on the locations of all oops in the table.
   static void oops_do(OopClosure* f);
 
   // Possibly parallel versions of the above
-  static void possibly_parallel_unlink(
-     OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
-     BoolObjectClosure* cl, size_t* processed, size_t* removed);
   static void possibly_parallel_oops_do(
      OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
      OopClosure* f);
--- a/src/hotspot/share/classfile/symbolTable.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -49,10 +49,6 @@
 const size_t END_SIZE = 17;
 // If a chain gets to 100 something might be wrong
 const size_t REHASH_LEN = 100;
-// We only get a chance to check whether we need
-// to clean infrequently (on class unloading),
-// so if we have even one dead entry then mark table for cleaning
-const double CLEAN_DEAD_HIGH_WATER_MARK = 0.0;
 
 const size_t ON_STACK_BUFFER_LENGTH = 128;
 
@@ -142,7 +138,7 @@
 SymbolTable::SymbolTable() :
   _symbols_removed(0), _symbols_counted(0), _local_table(NULL),
   _current_size(0), _has_work(0), _needs_rehashing(false),
-  _items_count(0), _uncleaned_items_count(0) {
+  _items_count(0), _has_items_to_clean(false) {
 
   size_t start_size_log_2 = ceil_log2(SymbolTableSize);
   _current_size = ((size_t)1) << start_size_log_2;
@@ -171,22 +167,14 @@
   }
 }
 
+void SymbolTable::reset_has_items_to_clean() { Atomic::store(false, &_has_items_to_clean); }
+void SymbolTable::mark_has_items_to_clean()  { Atomic::store(true, &_has_items_to_clean); }
+bool SymbolTable::has_items_to_clean() const { return Atomic::load(&_has_items_to_clean); }
+
 void SymbolTable::item_added() {
   Atomic::inc(&(SymbolTable::the_table()->_items_count));
 }
 
-void SymbolTable::set_item_clean_count(size_t ncl) {
-  Atomic::store(ncl, &(SymbolTable::the_table()->_uncleaned_items_count));
-  log_trace(symboltable)("Set uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
-}
-
-// Mark one item as needing to be cleaned, but only if no other items are marked yet
-void SymbolTable::mark_item_clean_count() {
-  if (Atomic::cmpxchg((size_t)1, &(SymbolTable::the_table()->_uncleaned_items_count), (size_t)0) == 0) {
-    log_trace(symboltable)("Marked uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
-  }
-}
-
 void SymbolTable::item_removed() {
   Atomic::inc(&(SymbolTable::the_table()->_symbols_removed));
   Atomic::dec(&(SymbolTable::the_table()->_items_count));
@@ -196,15 +184,11 @@
   return (double)_items_count/_current_size;
 }
 
-double SymbolTable::get_dead_factor() const {
-  return (double)_uncleaned_items_count/_current_size;
-}
-
 size_t SymbolTable::table_size() {
   return ((size_t)1) << _local_table->get_size_log2(Thread::current());
 }
 
-void SymbolTable::trigger_concurrent_work() {
+void SymbolTable::trigger_cleanup() {
   MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
   SymbolTable::the_table()->_has_work = true;
   Service_lock->notify_all();
@@ -490,12 +474,7 @@
   update_needs_rehash(rehash_warning);
 
   if (clean_hint) {
-    // we just found out that there is a dead item,
-    // which we were unable to clean right now,
-    // but we have no way of telling whether it's
-    // been previously counted or not, so mark
-    // it only if no other items were found yet
-    mark_item_clean_count();
+    mark_has_items_to_clean();
     check_concurrent_work();
   }
 
@@ -697,7 +676,7 @@
       }
       bdt.cont(jt);
     }
-    SymbolTable::the_table()->set_item_clean_count(0);
+    SymbolTable::the_table()->reset_has_items_to_clean();
     bdt.done(jt);
   }
 
@@ -711,17 +690,13 @@
   if (_has_work) {
     return;
   }
-  double load_factor = SymbolTable::get_load_factor();
-  double dead_factor = SymbolTable::get_dead_factor();
-  // We should clean/resize if we have more dead than alive,
+  // We should clean/resize if we have
   // more items than preferred load factor or
   // more dead items than water mark.
-  if ((dead_factor > load_factor) ||
-      (load_factor > PREF_AVG_LIST_LEN) ||
-      (dead_factor > CLEAN_DEAD_HIGH_WATER_MARK)) {
-    log_debug(symboltable)("Concurrent work triggered, live factor:%f dead factor:%f",
-                           load_factor, dead_factor);
-    trigger_concurrent_work();
+  if (has_items_to_clean() || (get_load_factor() > PREF_AVG_LIST_LEN)) {
+    log_debug(symboltable)("Concurrent work triggered, load factor: %f, items to clean: %s",
+                           get_load_factor(), has_items_to_clean() ? "true" : "false");
+    trigger_cleanup();
   }
 }
 
@@ -737,34 +712,6 @@
   _has_work = false;
 }
 
-class CountDead : StackObj {
-  size_t _count;
-public:
-  CountDead() : _count(0) {}
-  bool operator()(Symbol** value) {
-    assert(value != NULL, "expected valid value");
-    assert(*value != NULL, "value should point to a symbol");
-    Symbol* sym = *value;
-    if (sym->refcount() == 0) {
-      _count++;
-    }
-    return true;
-  };
-  size_t get_dead_count() const {
-    return _count;
-  }
-};
-
-void SymbolTable::do_check_concurrent_work() {
-  CountDead counter;
-  if (!SymbolTable::the_table()->_local_table->try_scan(Thread::current(), counter)) {
-    log_info(symboltable)("count dead unavailable at this moment");
-  } else {
-    SymbolTable::the_table()->set_item_clean_count(counter.get_dead_count());
-    SymbolTable::the_table()->check_concurrent_work();
-  }
-}
-
 void SymbolTable::do_concurrent_work(JavaThread* jt) {
   SymbolTable::the_table()->concurrent_work(jt);
 }
@@ -800,7 +747,7 @@
   if (get_load_factor() > PREF_AVG_LIST_LEN &&
       !_local_table->is_max_size_reached()) {
     log_debug(symboltable)("Choosing growing over rehashing.");
-    trigger_concurrent_work();
+    trigger_cleanup();
     _needs_rehashing = false;
     return;
   }
@@ -808,7 +755,7 @@
   // Already rehashed.
   if (rehashed) {
     log_warning(symboltable)("Rehashing already done, still long lists.");
-    trigger_concurrent_work();
+    trigger_cleanup();
     _needs_rehashing = false;
     return;
   }
--- a/src/hotspot/share/classfile/symbolTable.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -123,18 +123,19 @@
   volatile bool _needs_rehashing;
 
   volatile size_t _items_count;
-  volatile size_t _uncleaned_items_count;
+  volatile bool   _has_items_to_clean;
 
   double get_load_factor() const;
-  double get_dead_factor() const;
 
   void check_concurrent_work();
-  void trigger_concurrent_work();
 
   static void item_added();
   static void item_removed();
-  static void set_item_clean_count(size_t ncl);
-  static void mark_item_clean_count();
+
+  // For cleaning
+  void reset_has_items_to_clean();
+  void mark_has_items_to_clean();
+  bool has_items_to_clean() const;
 
   SymbolTable();
 
@@ -190,12 +191,9 @@
     initialize_symbols(symbol_alloc_arena_size);
   }
 
-  static void unlink() {
-    do_check_concurrent_work();
-  }
-  static void do_check_concurrent_work();
   static void do_concurrent_work(JavaThread* jt);
   static bool has_work() { return the_table()->_has_work; }
+  static void trigger_cleanup();
 
   // Probing
   static Symbol* lookup(const char* name, int len, TRAPS);
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1825,40 +1825,27 @@
     if (unloading_occurred) {
       MutexLockerEx ml2(is_concurrent ? Module_lock : NULL);
       JFR_ONLY(Jfr::on_unloading_classes();)
+
       MutexLockerEx ml1(is_concurrent ? SystemDictionary_lock : NULL);
       ClassLoaderDataGraph::clean_module_and_package_info();
-    }
-  }
-
-  // Cleanup ResolvedMethodTable even if no unloading occurred.
-  {
-    GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
-    ResolvedMethodTable::trigger_cleanup();
-  }
-
-  if (unloading_occurred) {
-    {
-      GCTraceTime(Debug, gc, phases) t("SymbolTable", gc_timer);
-      // Check if there's work to do in the SymbolTable
-      SymbolTable::do_check_concurrent_work();
-    }
-
-    {
-      MutexLockerEx ml(is_concurrent ? SystemDictionary_lock : NULL);
-      GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer);
       constraints()->purge_loader_constraints();
       resolution_errors()->purge_resolution_errors();
     }
-
-    {
-      GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
-      // Oops referenced by the protection domain cache table may get unreachable independently
-      // of the class loader (eg. cached protection domain oops). So we need to
-      // explicitly unlink them here.
-      // All protection domain oops are linked to the caller class, so if nothing
-      // unloads, this is not needed.
-      _pd_cache_table->trigger_cleanup();
-    }
+  }
+
+  GCTraceTime(Debug, gc, phases) t("Trigger cleanups", gc_timer);
+  // Trigger cleaning the ResolvedMethodTable even if no unloading occurred.
+  ResolvedMethodTable::trigger_cleanup();
+
+  if (unloading_occurred) {
+    SymbolTable::trigger_cleanup();
+
+    // Oops referenced by the protection domain cache table may get unreachable independently
+    // of the class loader (eg. cached protection domain oops). So we need to
+    // explicitly unlink them here.
+    // All protection domain oops are linked to the caller class, so if nothing
+    // unloads, this is not needed.
+    _pd_cache_table->trigger_cleanup();
   }
 
   return unloading_occurred;
--- a/src/hotspot/share/code/codeHeapState.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/code/codeHeapState.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -78,43 +78,134 @@
 //  - direct output into an argument-passed outputStream and
 //  - buffered output into a bufferedStream with subsequent flush
 //    of the filled buffer to the outputStream.
-#define USE_STRINGSTREAM
-#define HEX32_FORMAT  "0x%x"  // just a helper format string used below multiple times
+#define USE_BUFFEREDSTREAM
+
+// There are instances when composing an output line or a small set of
+// output lines out of many tty->print() calls creates significant overhead.
+// Writing to a bufferedStream buffer first has a significant advantage:
+// It uses noticeably less cpu cycles and reduces (when writing to a
+// network file) the required bandwidth by at least a factor of ten. Observed on MacOS.
+// That clearly makes up for the increased code complexity.
 //
-// Writing to a bufferedStream buffer first has a significant advantage:
-// It uses noticeably less cpu cycles and reduces (when wirting to a
-// network file) the required bandwidth by at least a factor of ten.
-// That clearly makes up for the increased code complexity.
-#if defined(USE_STRINGSTREAM)
-#define STRINGSTREAM_DECL(_anyst, _outst)                 \
-    /* _anyst  name of the stream as used in the code */  \
-    /* _outst  stream where final output will go to   */  \
-    ResourceMark rm;                                      \
-    bufferedStream   _sstobj = bufferedStream(4*K);       \
-    bufferedStream*  _sstbuf = &_sstobj;                  \
-    outputStream*    _outbuf = _outst;                    \
-    bufferedStream*  _anyst  = &_sstobj; /* any stream. Use this to just print - no buffer flush.  */
+// Conversion of existing code is easy and straightforward, if the code already
+// uses a parameterized output destination, e.g. "outputStream st".
+//  - rename the formal parameter to any other name, e.g. out_st.
+//  - at a suitable place in your code, insert
+//      BUFFEREDSTEAM_DECL(buf_st, out_st)
+// This will provide all the declarations necessary. After that, all
+// buf_st->print() (and the like) calls will be directed to a bufferedStream object.
+// Once a block of output (a line or a small set of lines) is composed, insert
+//      BUFFEREDSTREAM_FLUSH(termstring)
+// to flush the bufferedStream to the final destination out_st. termstring is just
+// an arbitrary string (e.g. "\n") which is appended to the bufferedStream before
+// being written to out_st. Be aware that the last character written MUST be a '\n'.
+// Otherwise, buf_st->position() does not correspond to out_st->position() any longer.
+//      BUFFEREDSTREAM_FLUSH_LOCKED(termstring)
+// does the same thing, protected by the ttyLocker lock.
+//      BUFFEREDSTREAM_FLUSH_IF(termstring, remSize)
+// does a flush only if the remaining buffer space is less than remSize.
+//
+// To activate, #define USE_BUFFERED_STREAM before including this header.
+// If not activated, output will directly go to the originally used outputStream
+// with no additional overhead.
+//
+#if defined(USE_BUFFEREDSTREAM)
+// All necessary declarations to print via a bufferedStream
+// This macro must be placed before any other BUFFEREDSTREAM*
+// macro in the function.
+#define BUFFEREDSTREAM_DECL_SIZE(_anyst, _outst, _capa)       \
+    ResourceMark         _rm;                                 \
+    /* _anyst  name of the stream as used in the code */      \
+    /* _outst  stream where final output will go to   */      \
+    /* _capa   allocated capacity of stream buffer    */      \
+    size_t           _nflush = 0;                             \
+    size_t     _nforcedflush = 0;                             \
+    size_t      _nsavedflush = 0;                             \
+    size_t     _nlockedflush = 0;                             \
+    size_t     _nflush_bytes = 0;                             \
+    size_t         _capacity = _capa;                         \
+    bufferedStream   _sstobj = bufferedStream(_capa);         \
+    bufferedStream*  _sstbuf = &_sstobj;                      \
+    outputStream*    _outbuf = _outst;                        \
+    bufferedStream*   _anyst = &_sstobj; /* any stream. Use this to just print - no buffer flush.  */
 
-#define STRINGSTREAM_FLUSH(termString)                    \
-    _sstbuf->print("%s", termString);                     \
-    _outbuf->print("%s", _sstbuf->as_string());           \
-    _sstbuf->reset();
+// Same as above, but with fixed buffer size.
+#define BUFFEREDSTREAM_DECL(_anyst, _outst)                   \
+    BUFFEREDSTREAM_DECL_SIZE(_anyst, _outst, 4*K);
 
-#define STRINGSTREAM_FLUSH_LOCKED(termString)             \
-    { ttyLocker ttyl;/* keep this output block together */\
-      STRINGSTREAM_FLUSH(termString)                      \
+// Flush the buffer contents unconditionally.
+// No action if the buffer is empty.
+#define BUFFEREDSTREAM_FLUSH(_termString)                     \
+    if (((_termString) != NULL) && (strlen(_termString) > 0)){\
+      _sstbuf->print("%s", _termString);                      \
+    }                                                         \
+    if (_sstbuf != _outbuf) {                                 \
+      if (_sstbuf->size() != 0) {                             \
+        _nforcedflush++; _nflush_bytes += _sstbuf->size();    \
+        _outbuf->print("%s", _sstbuf->as_string());           \
+        _sstbuf->reset();                                     \
+      }                                                       \
     }
+
+// Flush the buffer contents if the remaining capacity is
+// less than the given threshold.
+#define BUFFEREDSTREAM_FLUSH_IF(_termString, _remSize)        \
+    if (((_termString) != NULL) && (strlen(_termString) > 0)){\
+      _sstbuf->print("%s", _termString);                      \
+    }                                                         \
+    if (_sstbuf != _outbuf) {                                 \
+      if ((_capacity - _sstbuf->size()) < (size_t)(_remSize)){\
+        _nflush++; _nforcedflush--;                           \
+        BUFFEREDSTREAM_FLUSH("")                              \
+      } else {                                                \
+        _nsavedflush++;                                       \
+      }                                                       \
+    }
+
+// Flush the buffer contents if the remaining capacity is less
+// than the calculated threshold (256 bytes + capacity/16)
+// That should suffice for all reasonably sized output lines.
+#define BUFFEREDSTREAM_FLUSH_AUTO(_termString)                \
+    BUFFEREDSTREAM_FLUSH_IF(_termString, 256+(_capacity>>4))
+
+#define BUFFEREDSTREAM_FLUSH_LOCKED(_termString)              \
+    { ttyLocker ttyl;/* keep this output block together */    \
+      _nlockedflush++;                                        \
+      BUFFEREDSTREAM_FLUSH(_termString)                       \
+    }
+
+// #define BUFFEREDSTREAM_FLUSH_STAT()                           \
+//     if (_sstbuf != _outbuf) {                                 \
+//       _outbuf->print_cr("%ld flushes (buffer full), %ld forced, %ld locked, %ld bytes total, %ld flushes saved", _nflush, _nforcedflush, _nlockedflush, _nflush_bytes, _nsavedflush); \
+//    }
+
+#define BUFFEREDSTREAM_FLUSH_STAT()
 #else
-#define STRINGSTREAM_DECL(_anyst, _outst)                 \
-    outputStream*  _outbuf = _outst;                      \
+#define BUFFEREDSTREAM_DECL_SIZE(_anyst, _outst, _capa)       \
+    size_t       _capacity = _capa;                           \
+    outputStream*  _outbuf = _outst;                          \
     outputStream*  _anyst  = _outst;   /* any stream. Use this to just print - no buffer flush.  */
 
-#define STRINGSTREAM_FLUSH(termString)                    \
-    _outbuf->print("%s", termString);
+#define BUFFEREDSTREAM_DECL(_anyst, _outst)                   \
+    BUFFEREDSTREAM_DECL_SIZE(_anyst, _outst, 4*K)
 
-#define STRINGSTREAM_FLUSH_LOCKED(termString)             \
-    _outbuf->print("%s", termString);
+#define BUFFEREDSTREAM_FLUSH(_termString)                     \
+    if (((_termString) != NULL) && (strlen(_termString) > 0)){\
+      _outbuf->print("%s", _termString);                      \
+    }
+
+#define BUFFEREDSTREAM_FLUSH_IF(_termString, _remSize)        \
+    BUFFEREDSTREAM_FLUSH(_termString)
+
+#define BUFFEREDSTREAM_FLUSH_AUTO(_termString)                \
+    BUFFEREDSTREAM_FLUSH(_termString)
+
+#define BUFFEREDSTREAM_FLUSH_LOCKED(_termString)              \
+    BUFFEREDSTREAM_FLUSH(_termString)
+
+#define BUFFEREDSTREAM_FLUSH_STAT()
 #endif
+#define HEX32_FORMAT  "0x%x"  // just a helper format string used below multiple times
 
 const char  blobTypeChar[] = {' ', 'C', 'N', 'I', 'X', 'Z', 'U', 'R', '?', 'D', 'T', 'E', 'S', 'A', 'M', 'B', 'L' };
 const char* blobTypeName[] = {"noType"
@@ -461,7 +552,7 @@
                                   // results in StatArray size of 24M (= max_granules * 48 Bytes per element)
                                   // For a 1GB CodeHeap, the granule size must be at least 2kB to not violate the max_granles limit.
   const char* heapName   = get_heapName(heap);
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   if (!initialization_complete) {
     memset(CodeHeapStatArray, 0, sizeof(CodeHeapStatArray));
@@ -477,7 +568,7 @@
                   "   to help them understand and solve issues in customer systems.\n"
                   "   It is not intended for use and interpretation by other persons.\n"
                   "   \n");
-    STRINGSTREAM_FLUSH("")
+    BUFFEREDSTREAM_FLUSH("")
   }
   get_HeapStatGlobals(out, heapName);
 
@@ -493,13 +584,13 @@
 
   if (seg_size == 0) {
     printBox(ast, '-', "Heap not fully initialized yet, segment size is zero for segment ", heapName);
-    STRINGSTREAM_FLUSH("")
+    BUFFEREDSTREAM_FLUSH("")
     return;
   }
 
   if (!CodeCache_lock->owned_by_self()) {
     printBox(ast, '-', "aggregate function called without holding the CodeCache_lock for ", heapName);
-    STRINGSTREAM_FLUSH("")
+    BUFFEREDSTREAM_FLUSH("")
     return;
   }
 
@@ -555,7 +646,7 @@
   ast->print_cr("   CodeHeap (committed part) is mapped to " SIZE_FORMAT " granules of size " SIZE_FORMAT " bytes.", granules, granularity);
   ast->print_cr("   Each granule takes " SIZE_FORMAT " bytes of C heap, that is " SIZE_FORMAT "K in total for statistics data.", sizeof(StatElement), (sizeof(StatElement)*granules)/(size_t)K);
   ast->print_cr("   The number of granules is limited to %dk, requiring a granules size of at least %d bytes for a 1GB heap.", (unsigned int)(max_granules/K), (unsigned int)(G/max_granules));
-  STRINGSTREAM_FLUSH("\n")
+  BUFFEREDSTREAM_FLUSH("\n")
 
 
   while (!done) {
@@ -644,7 +735,7 @@
         insane = true; ast->print_cr("Sanity check: end index (%d) lower than begin index (%d)", ix_end, ix_beg);
       }
       if (insane) {
-        STRINGSTREAM_FLUSH("")
+        BUFFEREDSTREAM_FLUSH("")
         continue;
       }
 
@@ -1033,7 +1124,7 @@
         avgTemp = 0;
         ast->print_cr("No hotness data available");
       }
-      STRINGSTREAM_FLUSH("\n")
+      BUFFEREDSTREAM_FLUSH("\n")
 
       // This loop is intentionally printing directly to "out".
       // It should not print anything, anyway.
@@ -1115,7 +1206,7 @@
                   "   Subsequent print functions create their output based on this snapshot.\n");
     ast->print_cr("   Free space in %s is distributed over %d free blocks.", heapName, nBlocks_free);
     ast->print_cr("   Each free block takes " SIZE_FORMAT " bytes of C heap for statistics data, that is " SIZE_FORMAT "K in total.", sizeof(FreeBlk), (sizeof(FreeBlk)*nBlocks_free)/K);
-    STRINGSTREAM_FLUSH("\n")
+    BUFFEREDSTREAM_FLUSH("\n")
 
     //----------------------------------------
     //--  Prepare the FreeArray of FreeBlks --
@@ -1151,7 +1242,7 @@
     if (ix != alloc_freeBlocks) {
       ast->print_cr("Free block count mismatch. Expected %d free blocks, but found %d.", alloc_freeBlocks, ix);
       ast->print_cr("I will update the counter and retry data collection");
-      STRINGSTREAM_FLUSH("\n")
+      BUFFEREDSTREAM_FLUSH("\n")
       nBlocks_free = ix;
       continue;
     }
@@ -1165,7 +1256,7 @@
       ast->print_cr("Free block count mismatch could not be resolved.");
       ast->print_cr("Try to run \"aggregate\" function to update counters");
     }
-    STRINGSTREAM_FLUSH("")
+    BUFFEREDSTREAM_FLUSH("")
 
     //---< discard old array and update global values  >---
     discard_FreeArray(out);
@@ -1199,7 +1290,7 @@
   set_HeapStatGlobals(out, heapName);
 
   printBox(ast, '=', "C O D E   H E A P   A N A L Y S I S   C O M P L E T E   for segment ", heapName);
-  STRINGSTREAM_FLUSH("\n")
+  BUFFEREDSTREAM_FLUSH("\n")
 }
 
 
@@ -1214,7 +1305,7 @@
   if ((StatArray == NULL) || (TopSizeArray == NULL) || (used_topSizeBlocks == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   {
     printBox(ast, '=', "U S E D   S P A C E   S T A T I S T I C S   for ", heapName);
@@ -1226,7 +1317,7 @@
                   "      is not continuously held, the displayed name might be wrong or no name\n"
                   "      might be found at all. The likelihood for that to happen increases\n"
                   "      over time passed between analysis and print step.\n", used_topSizeBlocks);
-    STRINGSTREAM_FLUSH_LOCKED("\n")
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n")
   }
 
   //----------------------------
@@ -1246,7 +1337,7 @@
     ast->fill_to(66);
     ast->print_cr("%6s", "method");
     ast->print_cr("%18s %13s %17s %4s %9s  %5s %s",      "Addr(module)      ", "offset", "size", "type", " type lvl", " temp", "Name");
-    STRINGSTREAM_FLUSH_LOCKED("")
+    BUFFEREDSTREAM_FLUSH_LOCKED("")
 
     //---<  print Top Ten Used Blocks  >---
     if (used_topSizeBlocks > 0) {
@@ -1324,17 +1415,17 @@
           ast->fill_to(67+6);
           ast->print("%s", blob_name);
         }
-        STRINGSTREAM_FLUSH_LOCKED("\n")
+        ast->cr();
+        BUFFEREDSTREAM_FLUSH_AUTO("")
       }
       if (used_topSizeBlocks != printed_topSizeBlocks) {
         ast->print_cr("used blocks: %d, printed blocks: %d", used_topSizeBlocks, printed_topSizeBlocks);
-        STRINGSTREAM_FLUSH("")
         for (unsigned int i = 0; i < alloc_topSizeBlocks; i++) {
           ast->print_cr("  TopSizeArray[%d].index = %d, len = %d", i, TopSizeArray[i].index, TopSizeArray[i].len);
-          STRINGSTREAM_FLUSH("")
+          BUFFEREDSTREAM_FLUSH_AUTO("")
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("\n\n")
+      BUFFEREDSTREAM_FLUSH("\n\n")
     }
   }
 
@@ -1359,7 +1450,7 @@
                     "      %ld characters are printed per percentage point.\n", pctFactor/100);
       ast->print_cr("total size   of all blocks: %7ldM", (total_size<<log2_seg_size)/M);
       ast->print_cr("total number of all blocks: %7ld\n", total_count);
-      STRINGSTREAM_FLUSH_LOCKED("")
+      BUFFEREDSTREAM_FLUSH_LOCKED("")
 
       ast->print_cr("[Size Range)------avg.-size-+----count-+");
       for (unsigned int i = 0; i < nSizeDistElements; i++) {
@@ -1388,9 +1479,10 @@
           ast->print("%c", (j%((pctFactor/100)*10) == 0) ? ('0'+j/(((unsigned int)pctFactor/100)*10)) : '*');
         }
         ast->cr();
+        BUFFEREDSTREAM_FLUSH_AUTO("")
       }
-      ast->print_cr("----------------------------+----------+\n\n");
-      STRINGSTREAM_FLUSH_LOCKED("\n")
+      ast->print_cr("----------------------------+----------+");
+      BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
 
       printBox(ast, '-', "Contribution per size range to total size for ", heapName);
       ast->print_cr("Note: The histogram indicates how much space (as a percentage of all\n"
@@ -1398,7 +1490,7 @@
                     "      %ld characters are printed per percentage point.\n", pctFactor/100);
       ast->print_cr("total size   of all blocks: %7ldM", (total_size<<log2_seg_size)/M);
       ast->print_cr("total number of all blocks: %7ld\n", total_count);
-      STRINGSTREAM_FLUSH_LOCKED("")
+      BUFFEREDSTREAM_FLUSH_LOCKED("")
 
       ast->print_cr("[Size Range)------avg.-size-+----count-+");
       for (unsigned int i = 0; i < nSizeDistElements; i++) {
@@ -1427,9 +1519,10 @@
           ast->print("%c", (j%((pctFactor/100)*10) == 0) ? ('0'+j/(((unsigned int)pctFactor/100)*10)) : '*');
         }
         ast->cr();
+        BUFFEREDSTREAM_FLUSH_AUTO("")
       }
       ast->print_cr("----------------------------+----------+");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
+      BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
     }
   }
 }
@@ -1446,7 +1539,7 @@
   if ((StatArray == NULL) || (FreeArray == NULL) || (alloc_granules == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   {
     printBox(ast, '=', "F R E E   S P A C E   S T A T I S T I C S   for ", heapName);
@@ -1455,12 +1548,11 @@
                   "      unoccupied, e.g. by class unloading. Then, the two adjacent free\n"
                   "      blocks, together with the now unoccupied space, form a new, large\n"
                   "      free block.");
-    STRINGSTREAM_FLUSH_LOCKED("\n")
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n")
   }
 
   {
     printBox(ast, '-', "List of all Free Blocks in ", heapName);
-    STRINGSTREAM_FLUSH_LOCKED("")
 
     unsigned int ix = 0;
     for (ix = 0; ix < alloc_freeBlocks-1; ix++) {
@@ -1472,10 +1564,11 @@
       if (FreeArray[ix].stubs_in_gap) {
         ast->print(" !! permanent gap, contains stubs and/or blobs !!");
       }
-      STRINGSTREAM_FLUSH_LOCKED("\n")
+      ast->cr();
+      BUFFEREDSTREAM_FLUSH_AUTO("")
     }
     ast->print_cr(INTPTR_FORMAT ": Len[%4d] = " HEX32_FORMAT, p2i(FreeArray[ix].start), ix, FreeArray[ix].len);
-    STRINGSTREAM_FLUSH_LOCKED("\n\n")
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n")
   }
 
 
@@ -1519,7 +1612,7 @@
       }
     }
   }
-  STRINGSTREAM_FLUSH_LOCKED("")
+  BUFFEREDSTREAM_FLUSH_AUTO("")
 
   {
     printBox(ast, '-', "Top Ten Free Blocks in ", heapName);
@@ -1536,9 +1629,10 @@
         ast->print("#blocks (in gap) %d", FreeTopTen[iy]->n_gapBlocks);
       }
       ast->cr();
+      BUFFEREDSTREAM_FLUSH_AUTO("")
     }
-    STRINGSTREAM_FLUSH_LOCKED("\n\n")
   }
+  BUFFEREDSTREAM_FLUSH_LOCKED("\n\n")
 
 
   //--------------------------------------------------------
@@ -1583,7 +1677,7 @@
       }
     }
   }
-  STRINGSTREAM_FLUSH_LOCKED("")
+  BUFFEREDSTREAM_FLUSH_AUTO("")
 
   {
     printBox(ast, '-', "Top Ten Free-Occupied-Free Triples in ", heapName);
@@ -1601,9 +1695,10 @@
       ast->fill_to(63);
       ast->print("#blocks (in gap) %d", FreeTopTenTriple[iy]->n_gapBlocks);
       ast->cr();
+      BUFFEREDSTREAM_FLUSH_AUTO("")
     }
-    STRINGSTREAM_FLUSH_LOCKED("\n\n")
   }
+  BUFFEREDSTREAM_FLUSH_LOCKED("\n\n")
 }
 
 
@@ -1618,7 +1713,7 @@
   if ((StatArray == NULL) || (alloc_granules == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   unsigned int granules_per_line = 32;
   char*        low_bound         = heap->low_boundary();
@@ -1634,13 +1729,12 @@
                     "  Occupied granules show their BlobType character, see legend.\n");
       print_blobType_legend(ast);
     }
-    STRINGSTREAM_FLUSH_LOCKED("")
+    BUFFEREDSTREAM_FLUSH_LOCKED("")
   }
 
   {
     if (segment_granules) {
       printBox(ast, '-', "Total (all types) count for granule size == segment size", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1649,7 +1743,6 @@
       }
     } else {
       printBox(ast, '-', "Total (all tiers) count, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1659,13 +1752,12 @@
         print_count_single(ast, count);
       }
     }
-    STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+    BUFFEREDSTREAM_FLUSH_LOCKED("|\n\n\n")
   }
 
   {
     if (nBlocks_t1 > 0) {
       printBox(ast, '-', "Tier1 nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1676,17 +1768,16 @@
           print_count_single(ast, StatArray[ix].t1_count);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier1 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_t2 > 0) {
       printBox(ast, '-', "Tier2 nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1697,17 +1788,16 @@
           print_count_single(ast, StatArray[ix].t2_count);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier2 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_alive > 0) {
       printBox(ast, '-', "not_used/not_entrant/not_installed nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1718,17 +1808,16 @@
           print_count_single(ast, StatArray[ix].tx_count);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No not_used/not_entrant nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_stub > 0) {
       printBox(ast, '-', "Stub & Blob count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1739,17 +1828,16 @@
           print_count_single(ast, StatArray[ix].stub_count);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Stubs and Blobs found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_dead > 0) {
       printBox(ast, '-', "Dead nMethod count only, 0x1..0xf. '*' indicates >= 16 blocks, ' ' indicates empty", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1760,17 +1848,16 @@
           print_count_single(ast, StatArray[ix].dead_count);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No dead nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (!segment_granules) { // Prevent totally redundant printouts
       printBox(ast, '-', "Count by tier (combined, no dead blocks): <#t1>:<#t2>:<#s>, 0x0..0xf. '*' indicates >= 16 blocks", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 24;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1787,7 +1874,7 @@
         }
         ast->print(" ");
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      BUFFEREDSTREAM_FLUSH_LOCKED("|\n\n\n")
     }
   }
 }
@@ -1804,7 +1891,7 @@
   if ((StatArray == NULL) || (alloc_granules == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   unsigned int granules_per_line = 32;
   char*        low_bound         = heap->low_boundary();
@@ -1823,13 +1910,12 @@
       ast->print_cr("  These digits represent a fill percentage range (see legend).\n");
       print_space_legend(ast);
     }
-    STRINGSTREAM_FLUSH_LOCKED("")
+    BUFFEREDSTREAM_FLUSH_LOCKED("")
   }
 
   {
     if (segment_granules) {
       printBox(ast, '-', "Total (all types) space consumption for granule size == segment size", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1838,7 +1924,6 @@
       }
     } else {
       printBox(ast, '-', "Total (all types) space consumption. ' ' indicates empty, '*' indicates full.", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1848,13 +1933,12 @@
         print_space_single(ast, space);
       }
     }
-    STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+    BUFFEREDSTREAM_FLUSH_LOCKED("|\n\n\n")
   }
 
   {
     if (nBlocks_t1 > 0) {
       printBox(ast, '-', "Tier1 space consumption. ' ' indicates empty, '*' indicates full", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1865,17 +1949,16 @@
           print_space_single(ast, StatArray[ix].t1_space);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier1 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_t2 > 0) {
       printBox(ast, '-', "Tier2 space consumption. ' ' indicates empty, '*' indicates full", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1886,11 +1969,11 @@
           print_space_single(ast, StatArray[ix].t2_space);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier2 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
@@ -1906,17 +1989,16 @@
           print_space_single(ast, StatArray[ix].tx_space);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier2 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_stub > 0) {
       printBox(ast, '-', "Stub and Blob space consumption. ' ' indicates empty, '*' indicates full", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1927,34 +2009,32 @@
           print_space_single(ast, StatArray[ix].stub_space);
         }
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Stubs and Blobs found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_dead > 0) {
       printBox(ast, '-', "Dead space consumption. ' ' indicates empty, '*' indicates full", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
         print_line_delim(out, ast, low_bound, ix, granules_per_line);
         print_space_single(ast, StatArray[ix].dead_space);
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No dead nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (!segment_granules) { // Prevent totally redundant printouts
       printBox(ast, '-', "Space consumption by tier (combined): <t1%>:<t2%>:<s%>. ' ' indicates empty, '*' indicates full", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 24;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -1979,7 +2059,8 @@
         }
         ast->print(" ");
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
+      BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
     }
   }
 }
@@ -1995,7 +2076,7 @@
   if ((StatArray == NULL) || (alloc_granules == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   unsigned int granules_per_line = 32;
   char*        low_bound         = heap->low_boundary();
@@ -2009,12 +2090,11 @@
                   "  Information for the youngest method (highest ID) in the granule is printed.\n"
                   "  Refer to the legend to learn how method age is mapped to the displayed digit.");
     print_age_legend(ast);
-    STRINGSTREAM_FLUSH_LOCKED("")
+    BUFFEREDSTREAM_FLUSH_LOCKED("")
   }
 
   {
     printBox(ast, '-', "Age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
-    STRINGSTREAM_FLUSH_LOCKED("")
 
     granules_per_line = 128;
     for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -2026,64 +2106,61 @@
       age       = age > agex ? age : agex;
       print_age_single(ast, age);
     }
-    STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+    ast->print("|");
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_t1 > 0) {
       printBox(ast, '-', "Tier1 age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
         print_line_delim(out, ast, low_bound, ix, granules_per_line);
         print_age_single(ast, StatArray[ix].t1_age);
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier1 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_t2 > 0) {
       printBox(ast, '-', "Tier2 age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
         print_line_delim(out, ast, low_bound, ix, granules_per_line);
         print_age_single(ast, StatArray[ix].t2_age);
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier2 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (nBlocks_alive > 0) {
       printBox(ast, '-', "not_used/not_entrant/not_installed age distribution. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 128;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
         print_line_delim(out, ast, low_bound, ix, granules_per_line);
         print_age_single(ast, StatArray[ix].tx_age);
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
     } else {
       ast->print("No Tier2 nMethods found in CodeHeap.");
-      STRINGSTREAM_FLUSH_LOCKED("\n\n\n")
     }
+    BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
   }
 
   {
     if (!segment_granules) { // Prevent totally redundant printouts
       printBox(ast, '-', "age distribution by tier <a1>:<a2>. '0' indicates youngest 1/256, '8': oldest half, ' ': no age information", NULL);
-      STRINGSTREAM_FLUSH_LOCKED("")
 
       granules_per_line = 32;
       for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -2093,7 +2170,8 @@
         print_age_single(ast, StatArray[ix].t2_age);
         ast->print(" ");
       }
-      STRINGSTREAM_FLUSH_LOCKED("|\n\n\n")
+      ast->print("|");
+      BUFFEREDSTREAM_FLUSH_LOCKED("\n\n\n")
     }
   }
 }
@@ -2110,7 +2188,7 @@
   if ((StatArray == NULL) || (alloc_granules == 0)) {
     return;
   }
-  STRINGSTREAM_DECL(ast, out)
+  BUFFEREDSTREAM_DECL(ast, out)
 
   unsigned int granules_per_line   = 128;
   char*        low_bound           = heap->low_boundary();
@@ -2129,7 +2207,7 @@
                 "  is not continuously held, the displayed name might be wrong or no name\n"
                 "  might be found at all. The likelihood for that to happen increases\n"
                 "  over time passed between aggregtion and print steps.\n");
-  STRINGSTREAM_FLUSH_LOCKED("")
+  BUFFEREDSTREAM_FLUSH_LOCKED("")
 
   for (unsigned int ix = 0; ix < alloc_granules; ix++) {
     //---<  print a new blob on a new line  >---
@@ -2144,7 +2222,7 @@
       ast->print_cr("--------------------------------------------------------------------");
       ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), " SIZE_FORMAT "k", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K);
       ast->print_cr("--------------------------------------------------------------------");
-      STRINGSTREAM_FLUSH_LOCKED("")
+      BUFFEREDSTREAM_FLUSH_AUTO("")
     }
     // Only check granule if it contains at least one blob.
     unsigned int nBlobs  = StatArray[ix].t1_count   + StatArray[ix].t2_count + StatArray[ix].tx_count +
@@ -2192,7 +2270,7 @@
           ast->fill_to(61);
           ast->print_cr("%6s", "method");
           ast->print_cr("%18s %13s %17s %9s  %5s %18s  %s", "Addr(module)      ", "offset", "size", " type lvl", " temp", "blobType          ", "Name");
-          STRINGSTREAM_FLUSH_LOCKED("")
+          BUFFEREDSTREAM_FLUSH_AUTO("")
         }
 
         //---<  print line prefix (address and offset from CodeHeap start)  >---
@@ -2248,15 +2326,15 @@
           ast->fill_to(62+6);
           ast->print("<stale blob>");
         }
-        STRINGSTREAM_FLUSH_LOCKED("\n")
+        ast->cr();
+        BUFFEREDSTREAM_FLUSH_AUTO("")
       } else if (!blob_is_safe && (this_blob != last_blob) && (this_blob != NULL)) {
         last_blob          = this_blob;
-        STRINGSTREAM_FLUSH_LOCKED("\n")
       }
     }
     } // nBlobs > 0
   }
-  STRINGSTREAM_FLUSH_LOCKED("\n\n")
+  BUFFEREDSTREAM_FLUSH_LOCKED("\n\n")
 }
 
 
@@ -2393,7 +2471,11 @@
     }
     ast->cr();
 
-    { // can't use STRINGSTREAM_FLUSH_LOCKED("") here.
+    // can't use BUFFEREDSTREAM_FLUSH_IF("", 512) here.
+    // can't use this expression. bufferedStream::capacity() does not exist.
+    // if ((ast->capacity() - ast->size()) < 512) {
+    // Assume instead that default bufferedStream capacity (4K) was used.
+    if (ast->size() > 3*K) {
       ttyLocker ttyl;
       out->print("%s", ast->as_string());
       ast->reset();
--- a/src/hotspot/share/compiler/compileBroker.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -48,6 +48,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/compilationPolicy.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -148,7 +148,7 @@
     FLAG_SET_ERGO(uintx, CodeCacheExpansionSize, 32*K);
   }
   if (FLAG_IS_DEFAULT(MetaspaceSize)) {
-    FLAG_SET_ERGO(size_t, MetaspaceSize, 12*M);
+    FLAG_SET_ERGO(size_t, MetaspaceSize, MIN2(12*M, MaxMetaspaceSize));
   }
   if (FLAG_IS_DEFAULT(MaxRAM)) {
     // Do not use FLAG_SET_ERGO to update MaxRAM, as this will impact
@@ -264,7 +264,7 @@
       FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
     }
     if (FLAG_IS_DEFAULT(MetaspaceSize)) {
-      FLAG_SET_DEFAULT(MetaspaceSize, MAX2(12*M, MetaspaceSize));
+      FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
     }
     if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
       FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -225,15 +225,11 @@
                                 ScanningOption so,
                                 bool only_strong_roots,
                                 OopsInGenClosure* root_closure,
-                                CLDClosure* cld_closure,
-                                OopStorage::ParState<false, false>* par_state_string) {
+                                CLDClosure* cld_closure) {
   MarkingCodeBlobClosure mark_code_closure(root_closure, !CodeBlobToOopClosure::FixRelocations);
   CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
 
   process_roots(scope, so, root_closure, cld_closure, weak_cld_closure, &mark_code_closure);
-  if (!only_strong_roots) {
-    process_string_table_roots(scope, root_closure, par_state_string);
-  }
 
   if (young_gen_as_roots &&
       _process_strong_tasks->try_claim_task(GCH_PS_younger_gens)) {
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -91,8 +91,7 @@
                          ScanningOption so,
                          bool only_strong_roots,
                          OopsInGenClosure* root_closure,
-                         CLDClosure* cld_closure,
-                         OopStorage::ParState<false, false>* par_state_string = NULL);
+                         CLDClosure* cld_closure);
 
   GCMemoryManager* old_manager() const { return _old_manager; }
 
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -4333,8 +4333,7 @@
                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                           _collector->should_unload_classes(),
                           &par_mri_cl,
-                          &cld_closure,
-                          &_par_state_string);
+                          &cld_closure);
 
   assert(_collector->should_unload_classes()
          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
@@ -4464,8 +4463,7 @@
                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                           _collector->should_unload_classes(),
                           &par_mrias_cl,
-                          NULL,     // The dirty klasses will be handled below
-                          &_par_state_string);
+                          NULL);     // The dirty klasses will be handled below
 
   assert(_collector->should_unload_classes()
          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
@@ -5271,18 +5269,6 @@
       // Prune dead klasses from subklass/sibling/implementor lists.
       Klass::clean_weak_klass_links(purged_class);
     }
-
-    {
-      GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer_cm);
-      // Clean up unreferenced symbols in symbol table.
-      SymbolTable::unlink();
-    }
-
-    {
-      GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer_cm);
-      // Delete entries for dead interned strings.
-      StringTable::unlink(&_is_alive_closure);
-    }
   }
 
   // Restore any preserved marks as a result of mark stack or
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -59,7 +59,6 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/handles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/thread.inline.hpp"
@@ -606,8 +605,7 @@
   heap->young_process_roots(_strong_roots_scope,
                            &par_scan_state.to_space_root_closure(),
                            &par_scan_state.older_gen_closure(),
-                           &cld_scan_closure,
-                           &_par_state_string);
+                           &cld_scan_closure);
 
   par_scan_state.end_strong_roots();
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -3362,24 +3362,54 @@
 
 void G1CollectedHeap::complete_cleaning(BoolObjectClosure* is_alive,
                                         bool class_unloading_occurred) {
-  uint n_workers = workers()->active_workers();
-
-  G1StringDedupUnlinkOrOopsDoClosure dedup_closure(is_alive, NULL, false);
-  ParallelCleaningTask g1_unlink_task(is_alive, &dedup_closure, n_workers, class_unloading_occurred);
-  workers()->run_task(&g1_unlink_task);
+  uint num_workers = workers()->active_workers();
+  ParallelCleaningTask unlink_task(is_alive, num_workers, class_unloading_occurred, false);
+  workers()->run_task(&unlink_task);
 }
 
-void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive,
-                                       bool process_strings,
-                                       bool process_string_dedup) {
-  if (!process_strings && !process_string_dedup) {
-    // Nothing to clean.
-    return;
+// Clean string dedup data structures.
+// Ideally we would prefer to use a StringDedupCleaningTask here, but we want to
+// record the durations of the phases. Hence the almost-copy.
+class G1StringDedupCleaningTask : public AbstractGangTask {
+  BoolObjectClosure* _is_alive;
+  OopClosure* _keep_alive;
+  G1GCPhaseTimes* _phase_times;
+
+public:
+  G1StringDedupCleaningTask(BoolObjectClosure* is_alive,
+                            OopClosure* keep_alive,
+                            G1GCPhaseTimes* phase_times) :
+    AbstractGangTask("Partial Cleaning Task"),
+    _is_alive(is_alive),
+    _keep_alive(keep_alive),
+    _phase_times(phase_times)
+  {
+    assert(G1StringDedup::is_enabled(), "String deduplication disabled.");
+    StringDedup::gc_prologue(true);
   }
 
-  G1StringDedupUnlinkOrOopsDoClosure dedup_closure(is_alive, NULL, false);
-  StringCleaningTask g1_unlink_task(is_alive, process_string_dedup ? &dedup_closure : NULL, process_strings);
-  workers()->run_task(&g1_unlink_task);
+  ~G1StringDedupCleaningTask() {
+    StringDedup::gc_epilogue();
+  }
+
+  void work(uint worker_id) {
+    StringDedupUnlinkOrOopsDoClosure cl(_is_alive, _keep_alive);
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
+      StringDedupQueue::unlink_or_oops_do(&cl);
+    }
+    {
+      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
+      StringDedupTable::unlink_or_oops_do(&cl, worker_id);
+    }
+  }
+};
+
+void G1CollectedHeap::string_dedup_cleaning(BoolObjectClosure* is_alive,
+                                            OopClosure* keep_alive,
+                                            G1GCPhaseTimes* phase_times) {
+  G1StringDedupCleaningTask cl(is_alive, keep_alive, phase_times);
+  workers()->run_task(&cl);
 }
 
 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
@@ -3911,11 +3941,6 @@
   // not copied during the pause.
   process_discovered_references(per_thread_states);
 
-  // FIXME
-  // CM's reference processing also cleans up the string table.
-  // Should we do that here also? We could, but it is a serial operation
-  // and could significantly increase the pause time.
-
   G1STWIsAliveClosure is_alive(this);
   G1KeepAliveClosure keep_alive(this);
 
@@ -3923,12 +3948,12 @@
                               g1_policy()->phase_times()->weak_phase_times());
 
   if (G1StringDedup::is_enabled()) {
-    double fixup_start = os::elapsedTime();
-
-    G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, g1_policy()->phase_times());
-
-    double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
-    g1_policy()->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
+    double string_dedup_time_ms = os::elapsedTime();
+
+    string_dedup_cleaning(&is_alive, &keep_alive, g1_policy()->phase_times());
+
+    double string_cleanup_time_ms = (os::elapsedTime() - string_dedup_time_ms) * 1000.0;
+    g1_policy()->phase_times()->record_string_deduplication_time(string_cleanup_time_ms);
   }
 
   if (evacuation_failed()) {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1332,14 +1332,12 @@
   // after a full GC.
   void rebuild_strong_code_roots();
 
-  // Partial cleaning used when class unloading is disabled.
-  // Let the caller choose what structures to clean out:
-  // - StringTable
-  // - StringDeduplication structures
-  void partial_cleaning(BoolObjectClosure* is_alive, bool unlink_strings, bool unlink_string_dedup);
+  // Partial cleaning of VM internal data structures.
+  void string_dedup_cleaning(BoolObjectClosure* is_alive,
+                             OopClosure* keep_alive,
+                             G1GCPhaseTimes* phase_times = NULL);
 
-  // Complete cleaning used when class unloading is enabled.
-  // Cleans out all structures handled by partial_cleaning and also the CodeCache.
+  // Performs cleaning of data structures after class unloading.
   void complete_cleaning(BoolObjectClosure* is_alive, bool class_unloading_occurred);
 
   // Redirty logged cards in the refinement queue.
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -588,7 +588,7 @@
   _num_active_tasks = active_tasks;
   // Need to update the three data structures below according to the
   // number of active threads for this phase.
-  _terminator = TaskTerminator((int) active_tasks, _task_queues);
+  _terminator.terminator()->reset_for_reuse((int) active_tasks);
   _first_overflow_barrier_sync.set_n_workers((int) active_tasks);
   _second_overflow_barrier_sync.set_n_workers((int) active_tasks);
 }
@@ -1655,11 +1655,9 @@
     GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm);
     bool purged_classes = SystemDictionary::do_unloading(_gc_timer_cm);
     _g1h->complete_cleaning(&g1_is_alive, purged_classes);
-  } else {
-    GCTraceTime(Debug, gc, phases) debug("Cleanup", _gc_timer_cm);
-    // No need to clean string table as it is treated as strong roots when
-    // class unloading is disabled.
-    _g1h->partial_cleaning(&g1_is_alive, false, G1StringDedup::is_enabled());
+  } else if (StringDedup::is_enabled()) {
+    GCTraceTime(Debug, gc, phases) debug("String Deduplication", _gc_timer_cm);
+    _g1h->string_dedup_cleaning(&g1_is_alive, NULL);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -224,10 +224,10 @@
     // Unload classes and purge the SystemDictionary.
     bool purged_class = SystemDictionary::do_unloading(scope()->timer());
     _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.
-    _heap->partial_cleaning(&_is_alive, true, G1StringDedup::is_enabled());
+  } else if (G1StringDedup::is_enabled()) {
+    GCTraceTime(Debug, gc, phases) debug("Phase 1: String Dedup Cleanup", scope()->timer());
+    // If no class unloading just clean out string deduplication data.
+    _heap->string_dedup_cleaning(&_is_alive, NULL);
   }
 
   scope()->tracer()->report_object_count_after_gc(&_is_alive);
--- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
     _weak_proc_task(collector->workers()),
     _hrclaimer(collector->workers()),
     _adjust(),
-    _adjust_string_dedup(NULL, &_adjust, G1StringDedup::is_enabled()) {
+    _string_dedup_cleaning_task(NULL, &_adjust, false) {
   // Need cleared claim bits for the roots processing
   ClassLoaderDataGraph::clear_claimed_marks();
 }
@@ -110,15 +110,10 @@
 
   CLDToOopClosure adjust_cld(&_adjust, ClassLoaderData::_claim_strong);
   CodeBlobToOopClosure adjust_code(&_adjust, CodeBlobToOopClosure::FixRelocations);
-  _root_processor.process_all_roots(
-      &_adjust,
-      &adjust_cld,
-      &adjust_code);
+  _root_processor.process_all_roots(&_adjust, &adjust_cld, &adjust_code);
 
-  // Adjust string dedup if enabled.
-  if (G1StringDedup::is_enabled()) {
-    G1StringDedup::parallel_unlink(&_adjust_string_dedup, worker_id);
-  }
+  // Adjust string dedup data structures.
+  _string_dedup_cleaning_task.work(worker_id);
 
   // Now adjust pointers region by region
   G1AdjustRegionClosure blk(collector()->mark_bitmap(), worker_id);
--- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 #include "gc/g1/g1RootProcessor.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/heapRegionManager.hpp"
+#include "gc/shared/parallelCleaning.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
 #include "gc/shared/weakProcessor.hpp"
 #include "utilities/ticks.hpp"
@@ -42,7 +43,7 @@
   WeakProcessor::Task      _weak_proc_task;
   HeapRegionClaimer        _hrclaimer;
   G1AdjustClosure          _adjust;
-  G1StringDedupUnlinkOrOopsDoClosure _adjust_string_dedup;
+  StringDedupCleaningTask  _string_dedup_cleaning_task;
 
 public:
   G1FullGCAdjustTask(G1FullCollector* collector);
--- a/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -49,15 +49,13 @@
   MarkingCodeBlobClosure code_closure(marker->mark_closure(), !CodeBlobToOopClosure::FixRelocations);
 
   if (ClassUnloading) {
-    _root_processor.process_strong_roots(
-        marker->mark_closure(),
-        marker->cld_closure(),
-        &code_closure);
+    _root_processor.process_strong_roots(marker->mark_closure(),
+                                         marker->cld_closure(),
+                                         &code_closure);
   } else {
-    _root_processor.process_all_roots_no_string_table(
-        marker->mark_closure(),
-        marker->cld_closure(),
-        &code_closure);
+    _root_processor.process_all_roots(marker->mark_closure(),
+                                      marker->cld_closure(),
+                                      &code_closure);
   }
 
   // Mark stack is populated, now process and drain it.
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@
 
   // Root scanning phases
   _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms):");
-  _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms):");
   _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms):");
   _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms):");
   _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms):");
@@ -136,7 +135,7 @@
   _cur_strong_code_root_purge_time_ms = 0.0;
   _cur_evac_fail_recalc_used = 0.0;
   _cur_evac_fail_remove_self_forwards = 0.0;
-  _cur_string_dedup_fixup_time_ms = 0.0;
+  _cur_string_deduplication_time_ms = 0.0;
   _cur_prepare_tlab_time_ms = 0.0;
   _cur_resize_tlab_time_ms = 0.0;
   _cur_derived_pointer_table_update_time_ms = 0.0;
@@ -290,12 +289,12 @@
   }
 }
 
-void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase) const {
+void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase, uint extra_indent) const {
   LogTarget(Debug, gc, phases) lt;
   if (lt.is_enabled()) {
     ResourceMark rm;
     LogStream ls(lt);
-    log_phase(phase, 2, &ls, true);
+    log_phase(phase, 2 + extra_indent, &ls, true);
   }
 }
 
@@ -417,7 +416,7 @@
                         _recorded_total_free_cset_time_ms +
                         _cur_fast_reclaim_humongous_time_ms +
                         _cur_expand_heap_time_ms +
-                        _cur_string_dedup_fixup_time_ms;
+                        _cur_string_deduplication_time_ms;
 
   info_time("Post Evacuate Collection Set", sum_ms);
 
@@ -430,9 +429,9 @@
   _weak_phase_times.log_print(2);
 
   if (G1StringDedup::is_enabled()) {
-    debug_time("String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
-    debug_phase(_gc_par_phases[StringDedupQueueFixup]);
-    debug_phase(_gc_par_phases[StringDedupTableFixup]);
+    debug_time("String Deduplication", _cur_string_deduplication_time_ms);
+    debug_phase(_gc_par_phases[StringDedupQueueFixup], 1);
+    debug_phase(_gc_par_phases[StringDedupTableFixup], 1);
   }
 
   if (G1CollectedHeap::heap()->evacuation_failed()) {
@@ -497,7 +496,6 @@
       "GCWorkerStart",
       "ExtRootScan",
       "ThreadRoots",
-      "StringTableRoots",
       "UniverseRoots",
       "JNIRoots",
       "ObjectSynchronizerRoots",
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -48,7 +48,6 @@
     GCWorkerStart,
     ExtRootScan,
     ThreadRoots,
-    StringTableRoots,
     UniverseRoots,
     JNIRoots,
     ObjectSynchronizerRoots,
@@ -104,8 +103,6 @@
  private:
   // Markers for grouping the phases in the GCPhases enum above
   static const int GCMainParPhasesLast = GCWorkerEnd;
-  static const int StringDedupPhasesFirst = StringDedupQueueFixup;
-  static const int StringDedupPhasesLast = StringDedupTableFixup;
 
   WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
 
@@ -134,7 +131,7 @@
   double _cur_evac_fail_recalc_used;
   double _cur_evac_fail_remove_self_forwards;
 
-  double _cur_string_dedup_fixup_time_ms;
+  double _cur_string_deduplication_time_ms;
 
   double _cur_prepare_tlab_time_ms;
   double _cur_resize_tlab_time_ms;
@@ -187,7 +184,7 @@
   void details(T* phase, const char* indent) const;
 
   void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const;
-  void debug_phase(WorkerDataArray<double>* phase) const;
+  void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
   void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const;
 
   void info_time(const char* name, double value) const;
@@ -272,8 +269,8 @@
     _cur_evac_fail_remove_self_forwards = ms;
   }
 
-  void record_string_dedup_fixup_time(double ms) {
-    _cur_string_dedup_fixup_time_ms = ms;
+  void record_string_deduplication_time(double ms) {
+    _cur_string_deduplication_time_ms = ms;
   }
 
   void record_ref_proc_time(double ms) {
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -490,9 +490,7 @@
 
   {
     G1RootProcessor root_processor(_g1h, 1);
-    root_processor.process_all_roots(&rootsCl,
-                                     &cldCl,
-                                     &blobsCl);
+    root_processor.process_all_roots(&rootsCl, &cldCl, &blobsCl);
   }
 
   bool failures = rootsCl.failures() || codeRootsCl.failures();
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -90,7 +90,6 @@
   }
 
   process_vm_roots(closures, phase_times, worker_i);
-  process_string_table_roots(closures, phase_times, worker_i);
 
   {
     // Now the CM ref_processor roots.
@@ -188,34 +187,17 @@
 
 void G1RootProcessor::process_all_roots(OopClosure* oops,
                                         CLDClosure* clds,
-                                        CodeBlobClosure* blobs,
-                                        bool process_string_table) {
+                                        CodeBlobClosure* blobs) {
   AllRootsClosures closures(oops, clds);
 
   process_java_roots(&closures, NULL, 0);
   process_vm_roots(&closures, NULL, 0);
 
-  if (process_string_table) {
-    process_string_table_roots(&closures, NULL, 0);
-  }
   process_code_cache_roots(blobs, NULL, 0);
 
   _process_strong_tasks.all_tasks_completed(n_workers());
 }
 
-void G1RootProcessor::process_all_roots(OopClosure* oops,
-                                        CLDClosure* clds,
-                                        CodeBlobClosure* blobs) {
-  process_all_roots(oops, clds, blobs, true);
-}
-
-void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops,
-                                                        CLDClosure* clds,
-                                                        CodeBlobClosure* blobs) {
-  assert(!ClassUnloading, "Should only be used when class unloading is disabled");
-  process_all_roots(oops, clds, blobs, false);
-}
-
 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
                                          G1GCPhaseTimes* phase_times,
                                          uint worker_i) {
@@ -295,16 +277,6 @@
   }
 }
 
-void G1RootProcessor::process_string_table_roots(G1RootClosures* closures,
-                                                 G1GCPhaseTimes* phase_times,
-                                                 uint worker_i) {
-  assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed");
-  G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
-  // All threads execute the following. A specific chunk of buckets
-  // from the StringTable are the individual tasks.
-  StringTable::possibly_parallel_oops_do(&_par_state_string, closures->weak_oops());
-}
-
 void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
                                                G1GCPhaseTimes* phase_times,
                                                uint worker_i) {
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -75,11 +75,6 @@
   void worker_has_discovered_all_strong_classes();
   void wait_until_all_strong_classes_discovered();
 
-  void process_all_roots(OopClosure* oops,
-                         CLDClosure* clds,
-                         CodeBlobClosure* blobs,
-                         bool process_string_table);
-
   void process_java_roots(G1RootClosures* closures,
                           G1GCPhaseTimes* phase_times,
                           uint worker_i);
@@ -88,10 +83,6 @@
                         G1GCPhaseTimes* phase_times,
                         uint worker_i);
 
-  void process_string_table_roots(G1RootClosures* closures,
-                                  G1GCPhaseTimes* phase_times,
-                                  uint worker_i);
-
   void process_code_cache_roots(CodeBlobClosure* code_closure,
                                 G1GCPhaseTimes* phase_times,
                                 uint worker_i);
@@ -101,7 +92,7 @@
 
   // Apply correct closures from pss to the strongly and weakly reachable roots in the system
   // in a single pass.
-  // Record and report timing measurements for sub phases using the worker_i
+  // Record and report timing measurements for sub phases using worker_id.
   void evacuate_roots(G1ParScanThreadState* pss, uint worker_id);
 
   // Apply oops, clds and blobs to all strongly reachable roots in the system
@@ -114,13 +105,6 @@
                          CLDClosure* clds,
                          CodeBlobClosure* blobs);
 
-  // Apply oops, clds and blobs to strongly and weakly reachable roots in the system,
-  // the only thing different from process_all_roots is that we skip the string table
-  // to avoid keeping every string live when doing class unloading.
-  void process_all_roots_no_string_table(OopClosure* oops,
-                                         CLDClosure* clds,
-                                         CodeBlobClosure* blobs);
-
   // Number of worker threads used by the root processor.
   uint n_workers() const;
 };
--- a/src/hotspot/share/gc/g1/g1StringDedup.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1StringDedup.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -89,53 +89,3 @@
   }
 }
 
-void G1StringDedup::oops_do(OopClosure* keep_alive) {
-  assert(is_enabled(), "String deduplication not enabled");
-  unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */);
-}
-
-void G1StringDedup::parallel_unlink(G1StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id) {
-  assert(is_enabled(), "String deduplication not enabled");
-  StringDedupQueue::unlink_or_oops_do(unlink);
-  StringDedupTable::unlink_or_oops_do(unlink, worker_id);
-}
-
-//
-// Task for parallel unlink_or_oops_do() operation on the deduplication queue
-// and table.
-//
-class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask {
-private:
-  G1StringDedupUnlinkOrOopsDoClosure _cl;
-  G1GCPhaseTimes* _phase_times;
-
-public:
-  G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive,
-                                  OopClosure* keep_alive,
-                                  bool allow_resize_and_rehash,
-                                  G1GCPhaseTimes* phase_times) :
-    AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"),
-    _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { }
-
-  virtual void work(uint worker_id) {
-    {
-      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id);
-      StringDedupQueue::unlink_or_oops_do(&_cl);
-    }
-    {
-      G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id);
-      StringDedupTable::unlink_or_oops_do(&_cl, worker_id);
-    }
-  }
-};
-
-void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive,
-                                      OopClosure* keep_alive,
-                                      bool allow_resize_and_rehash,
-                                      G1GCPhaseTimes* phase_times) {
-  assert(is_enabled(), "String deduplication not enabled");
-
-  G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times);
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  g1h->workers()->run_task(&task);
-}
--- a/src/hotspot/share/gc/g1/g1StringDedup.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/g1/g1StringDedup.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -78,35 +78,6 @@
   static void enqueue_from_mark(oop java_string, uint worker_id);
   static void enqueue_from_evacuation(bool from_young, bool to_young,
                                       unsigned int queue, oop java_string);
-
-  static void oops_do(OopClosure* keep_alive);
-  static void parallel_unlink(G1StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id);
-  static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive,
-                                bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL);
-};
-
-//
-// This closure encapsulates the state and the closures needed when scanning
-// the deduplication queue and table during the unlink_or_oops_do() operation.
-// A single instance of this closure is created and then shared by all worker
-// threads participating in the scan.
-//
-class G1StringDedupUnlinkOrOopsDoClosure : public StringDedupUnlinkOrOopsDoClosure {
-public:
-  G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
-                                     OopClosure* keep_alive,
-                                     bool allow_resize_and_rehash) :
-    StringDedupUnlinkOrOopsDoClosure(is_alive, keep_alive) {
-      if (G1StringDedup::is_enabled()) {
-        G1StringDedup::gc_prologue(allow_resize_and_rehash);
-      }
-    }
-
-  ~G1StringDedupUnlinkOrOopsDoClosure() {
-    if (G1StringDedup::is_enabled()) {
-      G1StringDedup::gc_epilogue();
-    }
-  }
 };
 
 #endif // SHARE_GC_G1_G1STRINGDEDUP_HPP
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -566,18 +566,6 @@
     Klass::clean_weak_klass_links(purged_class);
   }
 
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub String Table", _gc_timer);
-    // Delete entries for dead interned strings.
-    StringTable::unlink(is_alive_closure());
-  }
-
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer);
-    // Clean up unreferenced symbols in symbol table.
-    SymbolTable::unlink();
-  }
-
   _gc_tracer->report_object_count_after_gc(is_alive_closure());
 }
 
@@ -630,7 +618,6 @@
   CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
   AOTLoader::oops_do(adjust_pointer_closure());
-  StringTable::oops_do(adjust_pointer_closure());
   ref_processor()->weak_oops_do(adjust_pointer_closure());
   PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -2184,18 +2184,6 @@
     Klass::clean_weak_klass_links(purged_class);
   }
 
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub String Table", &_gc_timer);
-    // Delete entries for dead interned strings.
-    StringTable::unlink(is_alive_closure());
-  }
-
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", &_gc_timer);
-    // Clean up unreferenced symbols in symbol table.
-    SymbolTable::unlink();
-  }
-
   _gc_tracer.report_object_count_after_gc(is_alive_closure());
 }
 
@@ -2226,7 +2214,6 @@
   CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
   AOTLoader::oops_do(&oop_closure);
-  StringTable::oops_do(&oop_closure);
   ref_processor()->weak_oops_do(&oop_closure);
   // Roots were visited so references into the young gen in roots
   // may have been scanned.  Process them also.
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -430,12 +430,6 @@
       WeakProcessor::weak_oops_do(&_is_alive_closure, &root_closure);
     }
 
-    {
-      GCTraceTime(Debug, gc, phases) tm("Scrub String Table", &_gc_timer);
-      // Unlink any dead interned Strings and process the remaining live ones.
-      StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
-    }
-
     // Verify that usage of root_closure didn't copy any objects.
     assert(promotion_manager->stacks_empty(),"stacks should be empty at this point");
 
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -239,18 +239,6 @@
     Klass::clean_weak_klass_links(purged_class);
   }
 
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub String Table", gc_timer());
-    // Delete entries for dead interned strings.
-    StringTable::unlink(&is_alive);
-  }
-
-  {
-    GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", gc_timer());
-    // Clean up unreferenced symbols in symbol table.
-    SymbolTable::unlink();
-  }
-
   gc_tracer()->report_object_count_after_gc(&is_alive);
 }
 
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -849,33 +849,14 @@
   }
 }
 
-void GenCollectedHeap::process_string_table_roots(StrongRootsScope* scope,
-                                                  OopClosure* root_closure,
-                                                  OopStorage::ParState<false, false>* par_state_string) {
-  assert(root_closure != NULL, "Must be set");
-  // All threads execute the following. A specific chunk of buckets
-  // from the StringTable are the individual tasks.
-
-  // Either we should be single threaded or have a ParState
-  assert((scope->n_threads() <= 1) || par_state_string != NULL, "Parallel but no ParState");
-
-  if (scope->n_threads() > 1) {
-    StringTable::possibly_parallel_oops_do(par_state_string, root_closure);
-  } else {
-    StringTable::oops_do(root_closure);
-  }
-}
-
 void GenCollectedHeap::young_process_roots(StrongRootsScope* scope,
                                            OopsInGenClosure* root_closure,
                                            OopsInGenClosure* old_gen_closure,
-                                           CLDClosure* cld_closure,
-                                           OopStorage::ParState<false, false>* par_state_string) {
+                                           CLDClosure* cld_closure) {
   MarkingCodeBlobClosure mark_code_closure(root_closure, CodeBlobToOopClosure::FixRelocations);
 
   process_roots(scope, SO_ScavengeCodeCache, root_closure,
                 cld_closure, cld_closure, &mark_code_closure);
-  process_string_table_roots(scope, root_closure, par_state_string);
 
   if (_process_strong_tasks->try_claim_task(GCH_PS_younger_gens)) {
     root_closure->reset_generation();
@@ -895,19 +876,11 @@
                                           ScanningOption so,
                                           bool only_strong_roots,
                                           OopsInGenClosure* root_closure,
-                                          CLDClosure* cld_closure,
-                                          OopStorage::ParState<false, false>* par_state_string) {
+                                          CLDClosure* cld_closure) {
   MarkingCodeBlobClosure mark_code_closure(root_closure, is_adjust_phase);
   CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
 
   process_roots(scope, so, root_closure, cld_closure, weak_cld_closure, &mark_code_closure);
-  if (is_adjust_phase) {
-    // We never treat the string table as roots during marking
-    // for the full gc, so we only need to process it during
-    // the adjust phase.
-    process_string_table_roots(scope, root_closure, par_state_string);
-  }
-
   _process_strong_tasks->all_tasks_completed(scope->n_threads());
 }
 
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -400,10 +400,6 @@
                      CLDClosure* weak_cld_closure,
                      CodeBlobToOopClosure* code_roots);
 
-  void process_string_table_roots(StrongRootsScope* scope,
-                                  OopClosure* root_closure,
-                                  OopStorage::ParState<false, false>* par_state_string);
-
   // Accessor for memory state verification support
   NOT_PRODUCT(
     virtual size_t skip_header_HeapWords() { return 0; }
@@ -416,16 +412,14 @@
   void young_process_roots(StrongRootsScope* scope,
                            OopsInGenClosure* root_closure,
                            OopsInGenClosure* old_gen_closure,
-                           CLDClosure* cld_closure,
-                           OopStorage::ParState<false, false>* par_state_string = NULL);
+                           CLDClosure* cld_closure);
 
   void full_process_roots(StrongRootsScope* scope,
                           bool is_adjust_phase,
                           ScanningOption so,
                           bool only_strong_roots,
                           OopsInGenClosure* root_closure,
-                          CLDClosure* cld_closure,
-                          OopStorage::ParState<false, false>* par_state_string = NULL);
+                          CLDClosure* cld_closure);
 
   // Apply "root_closure" to all the weak roots of the system.
   // These include JNI weak roots, string table,
--- a/src/hotspot/share/gc/shared/owstTaskTerminator.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/owstTaskTerminator.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -38,15 +38,17 @@
   // Single worker, done
   if (_n_threads == 1) {
     _offered_termination = 1;
+    assert(!peek_in_queue_set(), "Precondition");
     return true;
   }
 
   _blocker->lock_without_safepoint_check();
+  _offered_termination++;
   // All arrived, done
-  _offered_termination++;
   if (_offered_termination == _n_threads) {
     _blocker->notify_all();
     _blocker->unlock();
+    assert(!peek_in_queue_set(), "Precondition");
     return true;
   }
 
@@ -59,21 +61,31 @@
 
       if (do_spin_master_work(terminator)) {
         assert(_offered_termination == _n_threads, "termination condition");
+        assert(!peek_in_queue_set(), "Precondition");
         return true;
       } else {
         _blocker->lock_without_safepoint_check();
+        // There is possibility that termination is reached between dropping the lock
+        // before returning from do_spin_master_work() and acquiring lock above.
+        if (_offered_termination == _n_threads) {
+          _blocker->unlock();
+          assert(!peek_in_queue_set(), "Precondition");
+          return true;
+        }
       }
     } else {
       _blocker->wait(true, WorkStealingSleepMillis);
 
       if (_offered_termination == _n_threads) {
         _blocker->unlock();
+        assert(!peek_in_queue_set(), "Precondition");
         return true;
       }
     }
 
     size_t tasks = tasks_in_queue_set();
     if (exit_termination(tasks, terminator)) {
+      assert_lock_strong(_blocker);
       _offered_termination--;
       _blocker->unlock();
       return false;
@@ -153,19 +165,24 @@
       _total_peeks++;
 #endif
     size_t tasks = tasks_in_queue_set();
-    if (exit_termination(tasks, terminator)) {
+    bool exit = exit_termination(tasks, terminator);
+    {
       MonitorLockerEx locker(_blocker, Mutex::_no_safepoint_check_flag);
-      if (tasks >= _offered_termination - 1) {
-        locker.notify_all();
-      } else {
-        for (; tasks > 1; tasks--) {
-          locker.notify();
+      // Termination condition reached
+      if (_offered_termination == _n_threads) {
+        _spin_master = NULL;
+        return true;
+      } else if (exit) {
+        if (tasks >= _offered_termination - 1) {
+          locker.notify_all();
+        } else {
+          for (; tasks > 1; tasks--) {
+            locker.notify();
+          }
         }
+        _spin_master = NULL;
+        return false;
       }
-      _spin_master = NULL;
-      return false;
-    } else if (_offered_termination == _n_threads) {
-      return true;
     }
   }
 }
--- a/src/hotspot/share/gc/shared/owstTaskTerminator.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/owstTaskTerminator.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -55,6 +55,7 @@
   }
 
   virtual ~OWSTTaskTerminator() {
+    assert(_spin_master == NULL, "Should have been reset");
     assert(_blocker != NULL, "Can not be NULL");
     delete _blocker;
   }
--- a/src/hotspot/share/gc/shared/parallelCleaning.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/parallelCleaning.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,48 +31,35 @@
 #include "memory/resourceArea.hpp"
 #include "logging/log.hpp"
 
-StringCleaningTask::StringCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure, bool process_strings) :
-  AbstractGangTask("String Unlinking"),
-  _is_alive(is_alive),
-  _dedup_closure(dedup_closure),
-  _par_state_string(StringTable::weak_storage()),
-  _initial_string_table_size((int) StringTable::the_table()->table_size()),
-  _process_strings(process_strings), _strings_processed(0), _strings_removed(0) {
+StringDedupCleaningTask::StringDedupCleaningTask(BoolObjectClosure* is_alive,
+                                                 OopClosure* keep_alive,
+                                                 bool resize_table) :
+  AbstractGangTask("String Dedup Cleaning"),
+  _dedup_closure(is_alive, keep_alive) {
 
-  if (process_strings) {
-    StringTable::reset_dead_counter();
+  if (StringDedup::is_enabled()) {
+    StringDedup::gc_prologue(resize_table);
   }
 }
 
-StringCleaningTask::~StringCleaningTask() {
-  log_info(gc, stringtable)(
-      "Cleaned string table, "
-      "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
-      strings_processed(), strings_removed());
-  if (_process_strings) {
-    StringTable::finish_dead_counter();
+StringDedupCleaningTask::~StringDedupCleaningTask() {
+  if (StringDedup::is_enabled()) {
+    StringDedup::gc_epilogue();
   }
 }
 
-void StringCleaningTask::work(uint worker_id) {
-  size_t strings_processed = 0;
-  size_t strings_removed = 0;
-  if (_process_strings) {
-    StringTable::possibly_parallel_unlink(&_par_state_string, _is_alive, &strings_processed, &strings_removed);
-    Atomic::add(strings_processed, &_strings_processed);
-    Atomic::add(strings_removed, &_strings_removed);
-  }
-  if (_dedup_closure != NULL) {
-    StringDedup::parallel_unlink(_dedup_closure, worker_id);
+void StringDedupCleaningTask::work(uint worker_id) {
+  if (StringDedup::is_enabled()) {
+    StringDedup::parallel_unlink(&_dedup_closure, worker_id);
   }
 }
 
 CodeCacheUnloadingTask::CodeCacheUnloadingTask(uint num_workers, BoolObjectClosure* is_alive, bool unloading_occurred) :
-      _unloading_scope(is_alive),
-      _unloading_occurred(unloading_occurred),
-      _num_workers(num_workers),
-      _first_nmethod(NULL),
-      _claimed_nmethod(NULL) {
+  _unloading_scope(is_alive),
+  _unloading_occurred(unloading_occurred),
+  _num_workers(num_workers),
+  _first_nmethod(NULL),
+  _claimed_nmethod(NULL) {
   // Get first alive nmethod
   CompiledMethodIterator iter(CompiledMethodIterator::only_alive);
   if(iter.next()) {
@@ -175,10 +162,12 @@
 }
 
 ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive,
-  StringDedupUnlinkOrOopsDoClosure* dedup_closure, uint num_workers, bool unloading_occurred) :
+                                           uint num_workers,
+                                           bool unloading_occurred,
+                                           bool resize_dedup_table) :
   AbstractGangTask("Parallel Cleaning"),
   _unloading_occurred(unloading_occurred),
-  _string_task(is_alive, StringDedup::is_enabled() ? dedup_closure : NULL, true),
+  _string_dedup_task(is_alive, NULL, resize_dedup_table),
   _code_cache_task(num_workers, is_alive, unloading_occurred),
   _klass_cleaning_task() {
 }
@@ -188,8 +177,8 @@
   // Do first pass of code cache cleaning.
   _code_cache_task.work(worker_id);
 
-  // Clean the Strings and Symbols.
-  _string_task.work(worker_id);
+  // Clean the string dedup data structures.
+  _string_dedup_task.work(worker_id);
 
   // Clean all klasses that were not unloaded.
   // The weak metadata in klass doesn't need to be
--- a/src/hotspot/share/gc/shared/parallelCleaning.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/parallelCleaning.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -33,27 +33,14 @@
 
 class ParallelCleaningTask;
 
-class StringCleaningTask : public AbstractGangTask {
-private:
-  BoolObjectClosure* _is_alive;
-  StringDedupUnlinkOrOopsDoClosure * const _dedup_closure;
-
-  OopStorage::ParState<false /* concurrent */, false /* const */> _par_state_string;
-
-  int _initial_string_table_size;
-
-  bool            _process_strings;
-  volatile size_t _strings_processed;
-  volatile size_t _strings_removed;
+class StringDedupCleaningTask : public AbstractGangTask {
+  StringDedupUnlinkOrOopsDoClosure _dedup_closure;
 
 public:
-  StringCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure, bool process_strings);
-  ~StringCleaningTask();
+  StringDedupCleaningTask(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool resize_table);
+  ~StringDedupCleaningTask();
 
   void work(uint worker_id);
-
-  size_t strings_processed() const { return _strings_processed; }
-  size_t strings_removed()   const { return _strings_removed; }
 };
 
 class CodeCacheUnloadingTask {
@@ -100,18 +87,21 @@
   void work();
 };
 
-// To minimize the remark pause times, the tasks below are done in parallel.
+// Do cleanup of some weakly held data in the same parallel task.
+// Assumes a non-moving context.
 class ParallelCleaningTask : public AbstractGangTask {
 private:
-  bool                        _unloading_occurred;
-  StringCleaningTask          _string_task;
-  CodeCacheUnloadingTask      _code_cache_task;
-  KlassCleaningTask           _klass_cleaning_task;
+  bool                    _unloading_occurred;
+  StringDedupCleaningTask _string_dedup_task;
+  CodeCacheUnloadingTask  _code_cache_task;
+  KlassCleaningTask       _klass_cleaning_task;
 
 public:
   // The constructor is run in the VMThread.
-  ParallelCleaningTask(BoolObjectClosure* is_alive, StringDedupUnlinkOrOopsDoClosure* dedup_closure,
-    uint num_workers, bool unloading_occurred);
+  ParallelCleaningTask(BoolObjectClosure* is_alive,
+                       uint num_workers,
+                       bool unloading_occurred,
+                       bool resize_dedup_table);
 
   void work(uint worker_id);
 };
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedup.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@
   StringDedupTable::deduplicate(java_string, &dummy);
 }
 
-
 void StringDedup::parallel_unlink(StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id) {
   assert(is_enabled(), "String deduplication not enabled");
   StringDedupQueue::unlink_or_oops_do(unlink);
@@ -80,5 +79,8 @@
 
 StringDedupUnlinkOrOopsDoClosure::StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
                                                                    OopClosure* keep_alive) :
-  _is_alive(is_alive), _keep_alive(keep_alive) {
+  _always_true(),
+  _do_nothing(),
+  _is_alive(is_alive != NULL ? is_alive : &_always_true),
+  _keep_alive(keep_alive != NULL ? keep_alive : &_do_nothing) {
 }
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -113,30 +113,18 @@
 // the deduplication queue and table during the unlink_or_oops_do() operation.
 //
 class StringDedupUnlinkOrOopsDoClosure : public StackObj {
-private:
+  AlwaysTrueClosure   _always_true;
+  DoNothingClosure    _do_nothing;
   BoolObjectClosure*  _is_alive;
   OopClosure*         _keep_alive;
 
 public:
   StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
-                                     OopClosure* keep_alive);
+                                   OopClosure* keep_alive);
 
-  // Applies and returns the result from the is_alive closure, or
-  // returns true if no such closure was provided.
-  bool is_alive(oop o) {
-    if (_is_alive != NULL) {
-      return _is_alive->do_object_b(o);
-    }
-    return true;
-  }
+  bool is_alive(oop o) { return _is_alive->do_object_b(o); }
 
-  // Applies the keep_alive closure, or does nothing if no such
-  // closure was provided.
-  void keep_alive(oop* p) {
-    if (_keep_alive != NULL) {
-      _keep_alive->do_oop(p);
-    }
-  }
+  void keep_alive(oop* p) { _keep_alive->do_oop(p); }
 };
 
 #endif // SHARE_GC_SHARED_STRINGDEDUP_STRINGDEDUP_HPP
--- a/src/hotspot/share/gc/shared/taskqueue.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/taskqueue.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -118,6 +118,11 @@
   _queue_set(queue_set),
   _offered_termination(0) {}
 
+ParallelTaskTerminator::~ParallelTaskTerminator() {
+  assert(_offered_termination == 0 || !peek_in_queue_set(), "Precondition");
+  assert(_offered_termination == 0 || _offered_termination == _n_threads, "Terminated or aborted" );
+}
+
 bool ParallelTaskTerminator::peek_in_queue_set() {
   return _queue_set->peek();
 }
@@ -162,6 +167,7 @@
     assert(_offered_termination <= _n_threads, "Invariant");
     // Are all threads offering termination?
     if (_offered_termination == _n_threads) {
+      assert(!peek_in_queue_set(), "Precondition");
       return true;
     } else {
       // Look for more work.
@@ -211,9 +217,7 @@
 #endif
       if (peek_in_queue_set() ||
           (terminator != NULL && terminator->should_exit_termination())) {
-        Atomic::dec(&_offered_termination);
-        assert(_offered_termination < _n_threads, "Invariant");
-        return false;
+        return complete_or_exit_termination();
       }
     }
   }
@@ -229,6 +233,23 @@
 }
 #endif
 
+bool ParallelTaskTerminator::complete_or_exit_termination() {
+  // If termination is ever reached, terminator should stay in such state,
+  // so that all threads see the same state
+  uint current_offered = _offered_termination;
+  uint expected_value;
+  do {
+    if (current_offered == _n_threads) {
+      assert(!peek_in_queue_set(), "Precondition");
+      return true;
+    }
+    expected_value = current_offered;
+  } while ((current_offered = Atomic::cmpxchg(current_offered - 1, &_offered_termination, current_offered)) != expected_value);
+
+  assert(_offered_termination < _n_threads, "Invariant");
+  return false;
+}
+
 void ParallelTaskTerminator::reset_for_reuse() {
   if (_offered_termination != 0) {
     assert(_offered_termination == _n_threads,
@@ -260,13 +281,3 @@
   }
 }
 
-// Move assignment
-TaskTerminator& TaskTerminator::operator=(const TaskTerminator& o) {
-  if (_terminator != NULL) {
-    delete _terminator;
-  }
-  _terminator = o.terminator();
-  const_cast<TaskTerminator&>(o)._terminator = NULL;
-  return *this;
-}
-
--- a/src/hotspot/share/gc/shared/taskqueue.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -451,7 +451,10 @@
 protected:
   uint _n_threads;
   TaskQueueSetSuper* _queue_set;
+
+  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
   volatile uint _offered_termination;
+  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
 
 #ifdef TRACESPINNING
   static uint _total_yields;
@@ -464,11 +467,18 @@
   virtual void yield();
   void sleep(uint millis);
 
+  // Called when exiting termination is requested.
+  // When the request is made, terminator may have already terminated
+  // (e.g. all threads are arrived and offered termination). In this case,
+  // it should ignore the request and complete the termination.
+  // Return true if termination is completed. Otherwise, return false.
+  bool complete_or_exit_termination();
 public:
 
   // "n_threads" is the number of threads to be terminated.  "queue_set" is a
   // queue sets of work queues of other threads.
   ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
+  virtual ~ParallelTaskTerminator();
 
   // The current thread has no work, and is ready to terminate if everyone
   // else is.  If returns "true", all threads are terminated.  If returns
@@ -500,37 +510,21 @@
 #endif
 };
 
-#ifdef _MSC_VER
-#pragma warning(push)
-// warning C4521: multiple copy constructors specified
-#pragma warning(disable:4521)
-// warning C4522: multiple assignment operators specified
-#pragma warning(disable:4522)
-#endif
-
 class TaskTerminator : public StackObj {
 private:
   ParallelTaskTerminator*  _terminator;
 
-  // Disable following copy constructors and assignment operator
-  TaskTerminator(TaskTerminator& o) { }
-  TaskTerminator(const TaskTerminator& o) { }
-  TaskTerminator& operator=(TaskTerminator& o) { return *this; }
+  // Noncopyable.
+  TaskTerminator(const TaskTerminator&);
+  TaskTerminator& operator=(const TaskTerminator&);
 public:
   TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
   ~TaskTerminator();
 
-  // Move assignment
-  TaskTerminator& operator=(const TaskTerminator& o);
-
   ParallelTaskTerminator* terminator() const {
     return _terminator;
   }
 };
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
 
 typedef GenericTaskQueue<oop, mtGC>             OopTaskQueue;
 typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessor.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
-#include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
@@ -35,13 +35,19 @@
 #include "utilities/macros.hpp"
 
 void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
+  StringTable::reset_dead_counter();
+  CountingIsAliveClosure<BoolObjectClosure> cl(is_alive);
   FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
     if (WeakProcessorPhases::is_serial(phase)) {
-      WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+      WeakProcessorPhases::processor(phase)(&cl, keep_alive);
     } else {
-      WeakProcessorPhases::oop_storage(phase)->weak_oops_do(is_alive, keep_alive);
+      WeakProcessorPhases::oop_storage(phase)->weak_oops_do(&cl, keep_alive);
+    }
+    if (WeakProcessorPhases::is_stringtable(phase)) {
+      StringTable::inc_dead_counter(cl.num_dead());
     }
   }
+  StringTable::finish_dead_counter();
 }
 
 void WeakProcessor::oops_do(OopClosure* closure) {
@@ -93,6 +99,7 @@
     OopStorage* storage = WeakProcessorPhases::oop_storage(phase);
     new (states++) StorageState(storage, _nworkers);
   }
+  StringTable::reset_dead_counter();
 }
 
 WeakProcessor::Task::Task(uint nworkers) :
@@ -122,6 +129,7 @@
     }
     FREE_C_HEAP_ARRAY(StorageState, _storage_states);
   }
+  StringTable::finish_dead_counter();
 }
 
 void WeakProcessor::GangTask::work(uint worker_id) {
--- a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -25,6 +25,7 @@
 #ifndef SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
 #define SHARE_GC_SHARED_WEAKPROCESSOR_INLINE_HPP
 
+#include "classfile/stringTable.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
@@ -36,6 +37,27 @@
 class BoolObjectClosure;
 class OopClosure;
 
+template<typename T>
+class CountingIsAliveClosure : public BoolObjectClosure {
+  T* _inner;
+
+  size_t _num_dead;
+  size_t _num_total;
+
+public:
+  CountingIsAliveClosure(T* cl) : _inner(cl), _num_dead(0), _num_total(0) { }
+
+  virtual bool do_object_b(oop obj) {
+    bool result = _inner->do_object_b(obj);
+    _num_dead += !result;
+    _num_total++;
+    return result;
+  }
+
+  size_t num_dead() const { return _num_dead; }
+  size_t num_total() const { return _num_total; }
+};
+
 template<typename IsAlive, typename KeepAlive>
 void WeakProcessor::Task::work(uint worker_id,
                                IsAlive* is_alive,
@@ -45,16 +67,26 @@
          worker_id, _nworkers);
 
   FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
+    CountingIsAliveClosure<IsAlive> cl(is_alive);
     if (WeakProcessorPhases::is_serial(phase)) {
       uint serial_index = WeakProcessorPhases::serial_index(phase);
       if (_serial_phases_done.try_claim_task(serial_index)) {
         WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
-        WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+        WeakProcessorPhases::processor(phase)(&cl, keep_alive);
+        if (_phase_times != NULL) {
+          _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
+        }
       }
     } else {
       WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
       uint storage_index = WeakProcessorPhases::oop_storage_index(phase);
-      _storage_states[storage_index].weak_oops_do(is_alive, keep_alive);
+      _storage_states[storage_index].weak_oops_do(&cl, keep_alive);
+      if (_phase_times != NULL) {
+        _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
+      }
+    }
+    if (WeakProcessorPhases::is_stringtable(phase)) {
+      StringTable::inc_dead_counter(cl.num_dead());
     }
   }
 
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -49,6 +49,7 @@
 
 #ifdef ASSERT
 static bool is_initialized_time(double t) { return t >= 0.0; }
+static bool is_initialized_items(size_t i) { return i != 0; }
 #endif // ASSERT
 
 static void reset_times(double* times, size_t ntimes) {
@@ -57,28 +58,43 @@
   }
 }
 
+static void reset_items(size_t* items, size_t nitems) {
+  for (size_t i = 0; i < nitems; ++i) {
+    items[i] = 0;
+  }
+}
+
 WeakProcessorPhaseTimes::WeakProcessorPhaseTimes(uint max_threads) :
   _max_threads(max_threads),
   _active_workers(0),
   _total_time_sec(uninitialized_time),
-  _worker_phase_times_sec()
+  _worker_data(),
+  _worker_dead_items(),
+  _worker_total_items()
 {
   assert(_max_threads > 0, "max_threads must not be zero");
 
   reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
+  reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
+  reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
 
   if (_max_threads > 1) {
-    WorkerDataArray<double>** wpt = _worker_phase_times_sec;
+    WorkerDataArray<double>** wpt = _worker_data;
     FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
       const char* description = WeakProcessorPhases::description(phase);
-      *wpt++ = new WorkerDataArray<double>(_max_threads, description);
+      *wpt = new WorkerDataArray<double>(_max_threads, description);
+      (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Dead"), DeadItems);
+      (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Total"), TotalItems);
+      wpt++;
     }
   }
 }
 
 WeakProcessorPhaseTimes::~WeakProcessorPhaseTimes() {
-  for (size_t i = 0; i < ARRAY_SIZE(_worker_phase_times_sec); ++i) {
-    delete _worker_phase_times_sec[i];
+  for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
+    delete _worker_data[i];
+    delete _worker_dead_items[i];
+    delete _worker_total_items[i];
   }
 }
 
@@ -100,9 +116,11 @@
   _active_workers = 0;
   _total_time_sec = uninitialized_time;
   reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
+  reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
+  reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
   if (_max_threads > 1) {
-    for (size_t i = 0; i < ARRAY_SIZE(_worker_phase_times_sec); ++i) {
-      _worker_phase_times_sec[i]->reset();
+    for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
+      _worker_data[i]->reset();
     }
   }
 }
@@ -129,10 +147,20 @@
   _phase_times_sec[phase_index(phase)] = time_sec;
 }
 
+void WeakProcessorPhaseTimes::record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total) {
+  uint p = phase_index(phase);
+  assert(!is_initialized_items(_phase_dead_items[p]),
+         "Already set dead items for phase %u", p);
+  assert(!is_initialized_items(_phase_total_items[p]),
+         "Already set total items for phase %u", p);
+  _phase_dead_items[p] = num_dead;
+  _phase_total_items[p] = num_total;
+}
+
 WorkerDataArray<double>* WeakProcessorPhaseTimes::worker_data(WeakProcessorPhase phase) const {
   assert_oop_storage_phase(phase);
   assert(active_workers() > 1, "No worker data when single-threaded");
-  return _worker_phase_times_sec[WeakProcessorPhases::oop_storage_index(phase)];
+  return _worker_data[WeakProcessorPhases::oop_storage_index(phase)];
 }
 
 double WeakProcessorPhaseTimes::worker_time_sec(uint worker_id, WeakProcessorPhase phase) const {
@@ -155,6 +183,18 @@
   }
 }
 
+void WeakProcessorPhaseTimes::record_worker_items(uint worker_id,
+                                                  WeakProcessorPhase phase,
+                                                  size_t num_dead,
+                                                  size_t num_total) {
+  if (active_workers() == 1) {
+    record_phase_items(phase, num_dead, num_total);
+  } else {
+    worker_data(phase)->set_or_add_thread_work_item(worker_id, num_dead, DeadItems);
+    worker_data(phase)->set_or_add_thread_work_item(worker_id, num_total, TotalItems);
+  }
+}
+
 static double elapsed_time_sec(Ticks start_time, Ticks end_time) {
   return (end_time - start_time).seconds();
 }
@@ -223,6 +263,16 @@
                         indent_str(indent),
                         WeakProcessorPhases::description(phase),
                         phase_time_sec(phase) * MILLIUNITS);
+
+  log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
+                        indent_str(indent + 1),
+                        "Dead",
+                        _phase_dead_items[phase_index(phase)]);
+
+  log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
+                        indent_str(indent + 1),
+                        "Total",
+                        _phase_total_items[phase_index(phase)]);
 }
 
 void WeakProcessorPhaseTimes::log_mt_phase_summary(WeakProcessorPhase phase,
@@ -231,27 +281,36 @@
   LogStream ls(lt);
   ls.print("%s", indents[indent]);
   worker_data(phase)->print_summary_on(&ls, true);
+  log_mt_phase_details(worker_data(phase), indent + 1);
+
+  for (uint i = 0; i < worker_data(phase)->MaxThreadWorkItems; i++) {
+    WorkerDataArray<size_t>* work_items = worker_data(phase)->thread_work_items(i);
+    if (work_items != NULL) {
+      ls.print("%s", indents[indent + 1]);
+      work_items->print_summary_on(&ls, true);
+      log_mt_phase_details(work_items, indent + 1);
+    }
+  }
 }
 
-void WeakProcessorPhaseTimes::log_mt_phase_details(WeakProcessorPhase phase,
+template <typename T>
+void WeakProcessorPhaseTimes::log_mt_phase_details(WorkerDataArray<T>* data,
                                                    uint indent) const {
   LogTarget(Trace, gc, phases) lt;
-  LogStream ls(lt);
-  ls.print("%s", indents[indent]);
-  worker_data(phase)->print_details_on(&ls);
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print("%s", indents[indent]);
+    data->print_details_on(&ls);
+  }
 }
 
 void WeakProcessorPhaseTimes::log_print_phases(uint indent) const {
   if (log_is_enabled(Debug, gc, phases)) {
-    bool details_enabled = log_is_enabled(Trace, gc, phases);
     FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
       if (is_serial_phase(phase) || (active_workers() == 1)) {
         log_st_phase(phase, indent);
       } else {
         log_mt_phase_summary(phase, indent);
-        if (details_enabled) {
-          log_mt_phase_details(phase, indent + 1);
-        }
       }
     }
   }
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,10 @@
 template<typename T> class WorkerDataArray;
 
 class WeakProcessorPhaseTimes : public CHeapObj<mtGC> {
+  enum {
+    DeadItems,
+    TotalItems
+  };
   uint _max_threads;
   uint _active_workers;
 
@@ -43,15 +47,20 @@
   // processed by multiple threads are unused, as are entries for
   // unexecuted phases.
   double _phase_times_sec[WeakProcessorPhases::phase_count];
+  size_t _phase_dead_items[WeakProcessorPhases::phase_count];
+  size_t _phase_total_items[WeakProcessorPhases::phase_count];
 
-  // Per-worker times, if multiple threads used and the phase was executed.
-  WorkerDataArray<double>* _worker_phase_times_sec[WeakProcessorPhases::oop_storage_phase_count];
+  // Per-worker times and linked items, if multiple threads used and the phase was executed.
+  WorkerDataArray<double>* _worker_data[WeakProcessorPhases::oop_storage_phase_count];
+  WorkerDataArray<size_t>* _worker_dead_items[WeakProcessorPhases::oop_storage_phase_count];
+  WorkerDataArray<size_t>* _worker_total_items[WeakProcessorPhases::oop_storage_phase_count];
 
   WorkerDataArray<double>* worker_data(WeakProcessorPhase phase) const;
 
   void log_st_phase(WeakProcessorPhase phase, uint indent) const;
   void log_mt_phase_summary(WeakProcessorPhase phase, uint indent) const;
-  void log_mt_phase_details(WeakProcessorPhase phase, uint indent) const;
+  template <typename T>
+  void log_mt_phase_details(WorkerDataArray<T>* data, uint indent) const;
 
 public:
   WeakProcessorPhaseTimes(uint max_threads);
@@ -67,7 +76,9 @@
 
   void record_total_time_sec(double time_sec);
   void record_phase_time_sec(WeakProcessorPhase phase, double time_sec);
+  void record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total);
   void record_worker_time_sec(uint worker_id, WeakProcessorPhase phase, double time_sec);
+  void record_worker_items(uint worker_id, WeakProcessorPhase phase, size_t num_dead, size_t num_total);
 
   void reset();
 
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "runtime/jniHandles.hpp"
@@ -78,6 +79,7 @@
   JVMTI_ONLY(case jvmti: return "JVMTI weak processing";)
   JFR_ONLY(case jfr: return "JFR weak processing";)
   case jni: return "JNI weak processing";
+  case stringtable: return "StringTable weak processing";
   case vm: return "VM weak processing";
   default:
     ShouldNotReachHere();
@@ -98,9 +100,14 @@
 OopStorage* WeakProcessorPhases::oop_storage(Phase phase) {
   switch (phase) {
   case jni: return JNIHandles::weak_global_handles();
+  case stringtable: return StringTable::weak_storage();
   case vm: return SystemDictionary::vm_weak_oop_storage();
   default:
     ShouldNotReachHere();
     return NULL;
   }
 }
+
+bool WeakProcessorPhases::is_stringtable(Phase phase) {
+  return phase == stringtable;
+}
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -44,6 +44,7 @@
 
     // OopStorage phases.
     jni,
+    stringtable,
     vm
   };
 
@@ -65,6 +66,8 @@
   static const char* description(Phase phase);
   static Processor processor(Phase phase); // Precondition: is_serial(phase)
   static OopStorage* oop_storage(Phase phase); // Precondition: is_oop_storage(phase)
+
+  static bool is_stringtable(Phase phase);
 };
 
 typedef WeakProcessorPhases::Phase WeakProcessorPhase;
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -46,6 +46,7 @@
 #include "memory/metaspace.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
 
 template<UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
 class ShenandoahInitMarkRootsClosure : public OopClosure {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -65,6 +65,8 @@
 #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
 
 #include "memory/metaspace.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/mallocTracker.hpp"
 
@@ -1863,6 +1865,22 @@
   return _free_set->used();
 }
 
+bool ShenandoahHeap::try_cancel_gc() {
+  while (true) {
+    jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE);
+    if (prev == CANCELLABLE) return true;
+    else if (prev == CANCELLED) return false;
+    assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
+    assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
+    {
+      // We need to provide a safepoint here, otherwise we might
+      // spin forever if a SP is pending.
+      ThreadBlockInVM sp(JavaThread::current());
+      SpinPause();
+    }
+  }
+}
+
 void ShenandoahHeap::cancel_gc(GCCause::Cause cause) {
   if (try_cancel_gc()) {
     FormatBuffer<> msg("Cancelling GC: %s", GCCause::to_string(cause));
@@ -1923,8 +1941,7 @@
                             ShenandoahPhaseTimings::full_gc_purge_par :
                             ShenandoahPhaseTimings::purge_par);
     uint active = _workers->active_workers();
-    StringDedupUnlinkOrOopsDoClosure dedup_cl(is_alive, NULL);
-    ParallelCleaningTask unlink_task(is_alive, &dedup_cl, active, purged_class);
+    ParallelCleaningTask unlink_task(is_alive, active, purged_class, true);
     _workers->run_task(&unlink_task);
   }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -380,7 +380,7 @@
   };
 
   ShenandoahSharedEnumFlag<CancelState> _cancelled_gc;
-  inline bool try_cancel_gc();
+  bool try_cancel_gc();
 
 public:
   static address cancelled_gc_addr();
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -31,7 +31,6 @@
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
 #include "gc/shenandoah/shenandoahBrooksPointer.inline.hpp"
-#include "gc/shenandoah/shenandoahCollectionSet.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
 #include "gc/shenandoah/shenandoahWorkGroup.hpp"
 #include "gc/shenandoah/shenandoahHeap.hpp"
@@ -42,8 +41,6 @@
 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/interfaceSupport.inline.hpp"
-#include "runtime/prefetch.hpp"
 #include "runtime/prefetch.inline.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/copy.hpp"
@@ -216,22 +213,6 @@
   }
 }
 
-inline bool ShenandoahHeap::try_cancel_gc() {
-  while (true) {
-    jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE);
-    if (prev == CANCELLABLE) return true;
-    else if (prev == CANCELLED) return false;
-    assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
-    assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
-    {
-      // We need to provide a safepoint here, otherwise we might
-      // spin forever if a SP is pending.
-      ThreadBlockInVM sp(JavaThread::current());
-      SpinPause();
-    }
-  }
-}
-
 inline void ShenandoahHeap::clear_cancelled_gc() {
   _cancelled_gc.set(CANCELLABLE);
   _oom_evac_handler.clear();
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -45,7 +45,6 @@
   f(scan_roots,                                     "  Scan Roots")                     \
   f(scan_thread_roots,                              "    S: Thread Roots")              \
   f(scan_code_roots,                                "    S: Code Cache Roots")          \
-  f(scan_string_table_roots,                        "    S: String Table Roots")        \
   f(scan_universe_roots,                            "    S: Universe Roots")            \
   f(scan_jni_roots,                                 "    S: JNI Roots")                 \
   f(scan_jni_weak_roots,                            "    S: JNI Weak Roots")            \
@@ -67,7 +66,6 @@
   f(update_roots,                                   "  Update Roots")                   \
   f(update_thread_roots,                            "    U: Thread Roots")              \
   f(update_code_roots,                              "    U: Code Cache Roots")          \
-  f(update_string_table_roots,                      "    U: String Table Roots")        \
   f(update_universe_roots,                          "    U: Universe Roots")            \
   f(update_jni_roots,                               "    U: JNI Roots")                 \
   f(update_jni_weak_roots,                          "    U: JNI Weak Roots")            \
@@ -97,7 +95,6 @@
   f(init_evac,                                      "  Initial Evacuation")             \
   f(evac_thread_roots,                              "    E: Thread Roots")              \
   f(evac_code_roots,                                "    E: Code Cache Roots")          \
-  f(evac_string_table_roots,                        "    E: String Table Roots")        \
   f(evac_universe_roots,                            "    E: Universe Roots")            \
   f(evac_jni_roots,                                 "    E: JNI Roots")                 \
   f(evac_jni_weak_roots,                            "    E: JNI Weak Roots")            \
@@ -124,7 +121,6 @@
   f(final_update_refs_roots,                         "  Update Roots")                  \
   f(final_update_refs_thread_roots,                  "    UR: Thread Roots")            \
   f(final_update_refs_code_roots,                    "    UR: Code Cache Roots")        \
-  f(final_update_refs_string_table_roots,            "    UR: String Table Roots")      \
   f(final_update_refs_universe_roots,                "    UR: Universe Roots")          \
   f(final_update_refs_jni_roots,                     "    UR: JNI Roots")               \
   f(final_update_refs_jni_weak_roots,                "    UR: JNI Weak Roots")          \
@@ -146,7 +142,6 @@
   f(degen_gc_update_roots,                           "  Degen Update Roots")            \
   f(degen_gc_update_thread_roots,                    "    DU: Thread Roots")            \
   f(degen_gc_update_code_roots,                      "    DU: Code Cache Roots")        \
-  f(degen_gc_update_string_table_roots,              "    DU: String Table Roots")      \
   f(degen_gc_update_universe_roots,                  "    DU: Universe Roots")          \
   f(degen_gc_update_jni_roots,                       "    DU: JNI Roots")               \
   f(degen_gc_update_jni_weak_roots,                  "    DU: JNI Weak Roots")          \
@@ -169,7 +164,6 @@
   f(init_traversal_gc_work,                          "  Work")                          \
   f(init_traversal_gc_thread_roots,                  "    TI: Thread Roots")            \
   f(init_traversal_gc_code_roots,                    "    TI: Code Cache Roots")        \
-  f(init_traversal_gc_string_table_roots,            "    TI: String Table Roots")      \
   f(init_traversal_gc_universe_roots,                "    TI: Universe Roots")          \
   f(init_traversal_gc_jni_roots,                     "    TI: JNI Roots")               \
   f(init_traversal_gc_jni_weak_roots,                "    TI: JNI Weak Roots")          \
@@ -189,7 +183,6 @@
   f(final_traversal_gc_work,                         "  Work")                          \
   f(final_traversal_gc_thread_roots,                 "    TF: Thread Roots")            \
   f(final_traversal_gc_code_roots,                   "    TF: Code Cache Roots")        \
-  f(final_traversal_gc_string_table_roots,           "    TF: String Table Roots")      \
   f(final_traversal_gc_universe_roots,               "    TF: Universe Roots")          \
   f(final_traversal_gc_jni_roots,                    "    TF: JNI Roots")               \
   f(final_traversal_gc_jni_weak_roots,               "    TF: JNI Weak Roots")          \
@@ -207,7 +200,6 @@
   f(final_traversal_update_roots,                    "  Update Roots")                  \
   f(final_traversal_update_thread_roots,             "    TU: Thread Roots")            \
   f(final_traversal_update_code_roots,               "    TU: Code Cache Roots")        \
-  f(final_traversal_update_string_table_roots,       "    TU: String Table Roots")      \
   f(final_traversal_update_universe_roots,           "    TU: Universe Roots")          \
   f(final_traversal_update_jni_roots,                "    TU: JNI Roots")               \
   f(final_traversal_update_jni_weak_roots,           "    TU: JNI Weak Roots")          \
@@ -231,7 +223,6 @@
   f(full_gc_roots,                                   "  Roots")                         \
   f(full_gc_thread_roots,                            "    F: Thread Roots")             \
   f(full_gc_code_roots,                              "    F: Code Cache Roots")         \
-  f(full_gc_string_table_roots,                      "    F: String Table Roots")       \
   f(full_gc_universe_roots,                          "    F: Universe Roots")           \
   f(full_gc_jni_roots,                               "    F: JNI Roots")                \
   f(full_gc_jni_weak_roots,                          "    F: JNI Weak Roots")           \
@@ -286,7 +277,6 @@
 #define SHENANDOAH_GC_PAR_PHASE_DO(f)                           \
   f(ThreadRoots,             "Thread Roots (ms):")              \
   f(CodeCacheRoots,          "CodeCache Roots (ms):")           \
-  f(StringTableRoots,        "StringTable Roots (ms):")         \
   f(UniverseRoots,           "Universe Roots (ms):")            \
   f(JNIRoots,                "JNI Handles Roots (ms):")         \
   f(JNIWeakRoots,            "JNI Weak Roots (ms):")            \
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -78,7 +78,6 @@
   WeakProcessor::oops_do(oops);
   ObjectSynchronizer::oops_do(oops);
   SystemDictionary::oops_do(oops);
-  StringTable::oops_do(oops);
 
   if (ShenandoahStringDedup::is_enabled()) {
     ShenandoahStringDedup::oops_do_slow(oops);
@@ -209,13 +208,6 @@
       ObjectSynchronizer::oops_do(strong_roots);
     }
   }
-
-  // All threads execute the following. A specific chunk of buckets
-  // from the StringTable are the individual tasks.
-  if (weak_roots != NULL) {
-    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
-    StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
-  }
 }
 
 uint ShenandoahRootProcessor::n_workers() const {
--- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -38,21 +38,15 @@
     _tmp(LIR_OprFact::illegalOpr),
     _runtime_stub(runtime_stub) {
 
+  assert(_ref_addr->is_address(), "Must be an address");
+  assert(_ref->is_register(), "Must be a register");
+
   // Allocate tmp register if needed
-  if (!_ref_addr->is_register()) {
-    assert(_ref_addr->is_address(), "Must be an address");
-    if (_ref_addr->as_address_ptr()->index()->is_valid() ||
-        _ref_addr->as_address_ptr()->disp() != 0) {
-      // Has index or displacement, need tmp register to load address into
-      _tmp = access.gen()->new_pointer_register();
-    } else {
-      // No index or displacement, address available in base register
-      _ref_addr = _ref_addr->as_address_ptr()->base();
-    }
+  if (_ref_addr->as_address_ptr()->index()->is_valid() ||
+      _ref_addr->as_address_ptr()->disp() != 0) {
+    // Has index or displacement, need tmp register to load address into
+    _tmp = access.gen()->new_pointer_register();
   }
-
-  assert(_ref->is_register(), "Must be a register");
-  assert(_ref_addr->is_register() != _tmp->is_register(), "Only one should be a register");
 }
 
 DecoratorSet ZLoadBarrierStubC1::decorators() const {
--- a/src/hotspot/share/gc/z/zDriver.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zDriver.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -24,7 +24,6 @@
 #include "precompiled.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.hpp"
-#include "gc/shared/gcVMOperations.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
 #include "gc/z/zCollectedHeap.hpp"
 #include "gc/z/zDriver.hpp"
@@ -45,7 +44,6 @@
 static const ZStatPhaseConcurrent ZPhaseConcurrentProcessNonStrongReferences("Concurrent Process Non-Strong References");
 static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
 static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
-static const ZStatPhasePause      ZPhasePauseVerify("Pause Verify");
 static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
 static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
 static const ZStatPhasePause      ZPhasePauseRelocateStart("Pause Relocate Start");
@@ -53,41 +51,26 @@
 static const ZStatCriticalPhase   ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */);
 static const ZStatSampler         ZSamplerJavaThreads("System", "Java Threads", ZStatUnitThreads);
 
-class ZOperationClosure : public StackObj {
+class VM_ZOperation : public VM_Operation {
+private:
+  const uint _gc_id;
+  bool       _gc_locked;
+  bool       _success;
+
 public:
-  virtual const char* name() const = 0;
+  VM_ZOperation() :
+      _gc_id(GCId::current()),
+      _gc_locked(false),
+      _success(false) {}
 
   virtual bool needs_inactive_gc_locker() const {
-    // An inactive GC locker is needed in operations where we change the good
-    // mask or move objects. Changing the good mask will invalidate all oops,
+    // An inactive GC locker is needed in operations where we change the bad
+    // mask or move objects. Changing the bad mask will invalidate all oops,
     // which makes it conceptually the same thing as moving all objects.
     return false;
   }
 
   virtual bool do_operation() = 0;
-};
-
-class VM_ZOperation : public VM_Operation {
-private:
-  ZOperationClosure* _cl;
-  uint               _gc_id;
-  bool               _gc_locked;
-  bool               _success;
-
-public:
-  VM_ZOperation(ZOperationClosure* cl) :
-      _cl(cl),
-      _gc_id(GCId::current()),
-      _gc_locked(false),
-      _success(false) {}
-
-  virtual VMOp_Type type() const {
-    return VMOp_ZOperation;
-  }
-
-  virtual const char* name() const {
-    return _cl->name();
-  }
 
   virtual bool doit_prologue() {
     Heap_lock->lock();
@@ -95,31 +78,28 @@
   }
 
   virtual void doit() {
-    assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+    // Abort if GC locker state is incompatible
+    if (needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
+      _gc_locked = true;
+      return;
+    }
 
+    // Setup GC id and active marker
+    GCIdMark gc_id_mark(_gc_id);
+    IsGCActiveMark gc_active_mark;
+
+    // Execute operation
+    _success = do_operation();
+
+    // Update statistics
     ZStatSample(ZSamplerJavaThreads, Threads::number_of_threads());
-
-    // JVMTI support
-    SvcGCMarker sgcm(SvcGCMarker::CONCURRENT);
-
-    // Setup GC id
-    GCIdMark gcid(_gc_id);
-
-    if (_cl->needs_inactive_gc_locker() && GCLocker::check_active_before_gc()) {
-      // GC locker is active, bail out
-      _gc_locked = true;
-    } else {
-      // Execute operation
-      IsGCActiveMark mark;
-      _success = _cl->do_operation();
-    }
   }
 
   virtual void doit_epilogue() {
     Heap_lock->unlock();
   }
 
-  bool gc_locked() {
+  bool gc_locked() const {
     return _gc_locked;
   }
 
@@ -169,10 +149,10 @@
   return false;
 }
 
-class ZMarkStartClosure : public ZOperationClosure {
+class VM_ZMarkStart : public VM_ZOperation {
 public:
-  virtual const char* name() const {
-    return "ZMarkStart";
+  virtual VMOp_Type type() const {
+    return VMOp_ZMarkStart;
   }
 
   virtual bool needs_inactive_gc_locker() const {
@@ -198,37 +178,23 @@
   }
 };
 
-class ZMarkEndClosure : public ZOperationClosure {
+class VM_ZMarkEnd : public VM_ZOperation {
 public:
-  virtual const char* name() const {
-    return "ZMarkEnd";
+  virtual VMOp_Type type() const {
+    return VMOp_ZMarkEnd;
   }
 
   virtual bool do_operation() {
     ZStatTimer timer(ZPhasePauseMarkEnd);
     ZServiceabilityMarkEndTracer tracer;
-
     return ZHeap::heap()->mark_end();
   }
 };
 
-class ZVerifyClosure : public ZOperationClosure {
+class VM_ZRelocateStart : public VM_ZOperation {
 public:
-  virtual const char* name() const {
-    return "ZVerify";
-  }
-
-  virtual bool do_operation() {
-    ZStatTimer timer(ZPhasePauseVerify);
-    Universe::verify();
-    return true;
-  }
-};
-
-class ZRelocateStartClosure : public ZOperationClosure {
-public:
-  virtual const char* name() const {
-    return "ZRelocateStart";
+  virtual VMOp_Type type() const {
+    return VMOp_ZRelocateStart;
   }
 
   virtual bool needs_inactive_gc_locker() const {
@@ -238,7 +204,6 @@
   virtual bool do_operation() {
     ZStatTimer timer(ZPhasePauseRelocateStart);
     ZServiceabilityRelocateStartTracer tracer;
-
     ZHeap::heap()->relocate_start();
     return true;
   }
@@ -251,24 +216,6 @@
   create_and_start();
 }
 
-bool ZDriver::vm_operation(ZOperationClosure* cl) {
-  for (;;) {
-    VM_ZOperation op(cl);
-    VMThread::execute(&op);
-    if (op.gc_locked()) {
-      // Wait for GC to become unlocked and restart the VM operation
-      ZStatTimer timer(ZCriticalPhaseGCLockerStall);
-      _gc_locker_port.wait();
-      continue;
-    }
-
-    // Notify VM operation completed
-    _gc_locker_port.ack();
-
-    return op.success();
-  }
-}
-
 void ZDriver::collect(GCCause::Cause cause) {
   switch (cause) {
   case GCCause::_wb_young_gc:
@@ -306,19 +253,96 @@
   }
 }
 
-GCCause::Cause ZDriver::start_gc_cycle() {
-  // Wait for GC request
-  return _gc_cycle_port.receive();
+template <typename T>
+bool ZDriver::pause() {
+  for (;;) {
+    T op;
+    VMThread::execute(&op);
+    if (op.gc_locked()) {
+      // Wait for GC to become unlocked and restart the VM operation
+      ZStatTimer timer(ZCriticalPhaseGCLockerStall);
+      _gc_locker_port.wait();
+      continue;
+    }
+
+    // Notify VM operation completed
+    _gc_locker_port.ack();
+
+    return op.success();
+  }
 }
 
-class ZDriverCycleScope : public StackObj {
+void ZDriver::pause_mark_start() {
+  pause<VM_ZMarkStart>();
+}
+
+void ZDriver::concurrent_mark() {
+  ZStatTimer timer(ZPhaseConcurrentMark);
+  ZHeap::heap()->mark(true /* initial */);
+}
+
+bool ZDriver::pause_mark_end() {
+  return pause<VM_ZMarkEnd>();
+}
+
+void ZDriver::concurrent_mark_continue() {
+  ZStatTimer timer(ZPhaseConcurrentMarkContinue);
+  ZHeap::heap()->mark(false /* initial */);
+}
+
+void ZDriver::concurrent_process_non_strong_references() {
+  ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
+  ZHeap::heap()->process_non_strong_references();
+}
+
+void ZDriver::concurrent_reset_relocation_set() {
+  ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
+  ZHeap::heap()->reset_relocation_set();
+}
+
+void ZDriver::concurrent_destroy_detached_pages() {
+  ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
+  ZHeap::heap()->destroy_detached_pages();
+}
+
+void ZDriver::pause_verify() {
+  if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
+    VM_Verify op;
+    VMThread::execute(&op);
+  }
+}
+
+void ZDriver::concurrent_select_relocation_set() {
+  ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
+  ZHeap::heap()->select_relocation_set();
+}
+
+void ZDriver::concurrent_prepare_relocation_set() {
+  ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
+  ZHeap::heap()->prepare_relocation_set();
+}
+
+void ZDriver::pause_relocate_start() {
+  pause<VM_ZRelocateStart>();
+}
+
+void ZDriver::concurrent_relocate() {
+  ZStatTimer timer(ZPhaseConcurrentRelocated);
+  ZHeap::heap()->relocate();
+}
+
+void ZDriver::check_out_of_memory() {
+  ZHeap::heap()->check_out_of_memory();
+}
+
+class ZDriverGCScope : public StackObj {
 private:
   GCIdMark      _gc_id;
   GCCauseSetter _gc_cause_setter;
   ZStatTimer    _timer;
 
 public:
-  ZDriverCycleScope(GCCause::Cause cause) :
+  ZDriverGCScope(GCCause::Cause cause) :
       _gc_id(),
       _gc_cause_setter(ZCollectedHeap::heap(), cause),
       _timer(ZPhaseCycle) {
@@ -326,7 +350,7 @@
     ZStatCycle::at_start();
   }
 
-  ~ZDriverCycleScope() {
+  ~ZDriverGCScope() {
     // Calculate boost factor
     const double boost_factor = (double)ZHeap::heap()->nconcurrent_worker_threads() /
                                 (double)ZHeap::heap()->nconcurrent_no_boost_worker_threads();
@@ -339,96 +363,63 @@
   }
 };
 
-void ZDriver::run_gc_cycle(GCCause::Cause cause) {
-  ZDriverCycleScope scope(cause);
+void ZDriver::gc(GCCause::Cause cause) {
+  ZDriverGCScope scope(cause);
 
   // Phase 1: Pause Mark Start
-  {
-    ZMarkStartClosure cl;
-    vm_operation(&cl);
-  }
+  pause_mark_start();
 
   // Phase 2: Concurrent Mark
-  {
-    ZStatTimer timer(ZPhaseConcurrentMark);
-    ZHeap::heap()->mark(true /* initial */);
-  }
+  concurrent_mark();
 
   // Phase 3: Pause Mark End
-  {
-    ZMarkEndClosure cl;
-    while (!vm_operation(&cl)) {
-      // Phase 3.5: Concurrent Mark Continue
-      ZStatTimer timer(ZPhaseConcurrentMarkContinue);
-      ZHeap::heap()->mark(false /* initial */);
-    }
+  while (!pause_mark_end()) {
+    // Phase 3.5: Concurrent Mark Continue
+    concurrent_mark_continue();
   }
 
   // Phase 4: Concurrent Process Non-Strong References
-  {
-    ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
-    ZHeap::heap()->process_non_strong_references();
-  }
+  concurrent_process_non_strong_references();
 
   // Phase 5: Concurrent Reset Relocation Set
-  {
-    ZStatTimer timer(ZPhaseConcurrentResetRelocationSet);
-    ZHeap::heap()->reset_relocation_set();
-  }
+  concurrent_reset_relocation_set();
 
   // Phase 6: Concurrent Destroy Detached Pages
-  {
-    ZStatTimer timer(ZPhaseConcurrentDestroyDetachedPages);
-    ZHeap::heap()->destroy_detached_pages();
-  }
+  concurrent_destroy_detached_pages();
 
   // Phase 7: Pause Verify
-  if (VerifyBeforeGC || VerifyDuringGC || VerifyAfterGC) {
-    ZVerifyClosure cl;
-    vm_operation(&cl);
-  }
+  pause_verify();
 
   // Phase 8: Concurrent Select Relocation Set
-  {
-    ZStatTimer timer(ZPhaseConcurrentSelectRelocationSet);
-    ZHeap::heap()->select_relocation_set();
-  }
+  concurrent_select_relocation_set();
 
   // Phase 9: Concurrent Prepare Relocation Set
-  {
-    ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
-    ZHeap::heap()->prepare_relocation_set();
-  }
+  concurrent_prepare_relocation_set();
 
   // Phase 10: Pause Relocate Start
-  {
-    ZRelocateStartClosure cl;
-    vm_operation(&cl);
-  }
+  pause_relocate_start();
 
   // Phase 11: Concurrent Relocate
-  {
-    ZStatTimer timer(ZPhaseConcurrentRelocated);
-    ZHeap::heap()->relocate();
-  }
-}
-
-void ZDriver::end_gc_cycle() {
-  // Notify GC cycle completed
-  _gc_cycle_port.ack();
-
-  // Check for out of memory condition
-  ZHeap::heap()->check_out_of_memory();
+  concurrent_relocate();
 }
 
 void ZDriver::run_service() {
   // Main loop
   while (!should_terminate()) {
-    const GCCause::Cause cause = start_gc_cycle();
-    if (cause != GCCause::_no_gc) {
-      run_gc_cycle(cause);
-      end_gc_cycle();
+    // Wait for GC request
+    const GCCause::Cause cause = _gc_cycle_port.receive();
+    if (cause == GCCause::_no_gc) {
+      continue;
     }
+
+    // Run GC
+    gc(cause);
+
+    // Notify GC completed
+    _gc_cycle_port.ack();
+
+    // Check for out of memory condition
+    check_out_of_memory();
   }
 }
 
--- a/src/hotspot/share/gc/z/zDriver.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zDriver.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,31 @@
 #include "gc/shared/gcCause.hpp"
 #include "gc/z/zMessagePort.hpp"
 
-class ZOperationClosure;
+class VM_ZOperation;
 
 class ZDriver : public ConcurrentGCThread {
 private:
   ZMessagePort<GCCause::Cause> _gc_cycle_port;
   ZRendezvousPort              _gc_locker_port;
 
-  bool vm_operation(ZOperationClosure* cl);
+  template <typename T> bool pause();
 
-  GCCause::Cause start_gc_cycle();
-  void run_gc_cycle(GCCause::Cause cause);
-  void end_gc_cycle();
+  void pause_mark_start();
+  void concurrent_mark();
+  bool pause_mark_end();
+  void concurrent_mark_continue();
+  void concurrent_process_non_strong_references();
+  void concurrent_reset_relocation_set();
+  void concurrent_destroy_detached_pages();
+  void pause_verify();
+  void concurrent_select_relocation_set();
+  void concurrent_prepare_relocation_set();
+  void pause_relocate_start();
+  void concurrent_relocate();
+
+  void check_out_of_memory();
+
+  void gc(GCCause::Cause cause);
 
 protected:
   virtual void run_service();
--- a/src/hotspot/share/gc/z/zFuture.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zFuture.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 #define SHARE_GC_Z_ZFUTURE_INLINE_HPP
 
 #include "gc/z/zFuture.hpp"
-#include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/semaphore.inline.hpp"
 #include "runtime/thread.hpp"
 
--- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -39,45 +39,11 @@
 static const ZStatSubPhase ZSubPhaseConcurrentReferencesProcess("Concurrent References Process");
 static const ZStatSubPhase ZSubPhaseConcurrentReferencesEnqueue("Concurrent References Enqueue");
 
-ZReferenceProcessor::ZReferenceProcessor(ZWorkers* workers) :
-    _workers(workers),
-    _soft_reference_policy(NULL),
-    _encountered_count(),
-    _discovered_count(),
-    _enqueued_count(),
-    _discovered_list(NULL),
-    _pending_list(NULL),
-    _pending_list_tail(_pending_list.addr()) {}
-
-void ZReferenceProcessor::set_soft_reference_policy(bool clear) {
-  static AlwaysClearPolicy always_clear_policy;
-  static LRUMaxHeapPolicy lru_max_heap_policy;
-
-  if (clear) {
-    log_info(gc, ref)("Clearing All Soft References");
-    _soft_reference_policy = &always_clear_policy;
-  } else {
-    _soft_reference_policy = &lru_max_heap_policy;
-  }
-
-  _soft_reference_policy->setup();
+static ReferenceType reference_type(oop reference) {
+  return InstanceKlass::cast(reference->klass())->reference_type();
 }
 
-void ZReferenceProcessor::update_soft_reference_clock() const {
-  const jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
-  java_lang_ref_SoftReference::set_clock(now);
-}
-
-bool ZReferenceProcessor::is_inactive_final_reference(oop obj, ReferenceType type) const {
-  // A non-null next field for a FinalReference means the reference is inactive.
-  return (type == REF_FINAL) && (java_lang_ref_Reference::next(obj) != NULL);
-}
-
-ReferenceType ZReferenceProcessor::reference_type(oop obj) const {
-  return InstanceKlass::cast(obj->klass())->reference_type();
-}
-
-const char* ZReferenceProcessor::reference_type_name(ReferenceType type) const {
+static const char* reference_type_name(ReferenceType type) {
   switch (type) {
   case REF_SOFT:
     return "Soft";
@@ -97,53 +63,134 @@
   }
 }
 
-volatile oop* ZReferenceProcessor::reference_referent_addr(oop obj) const {
-  return (volatile oop*)java_lang_ref_Reference::referent_addr_raw(obj);
+static volatile oop* reference_referent_addr(oop reference) {
+  return (volatile oop*)java_lang_ref_Reference::referent_addr_raw(reference);
 }
 
-oop ZReferenceProcessor::reference_referent(oop obj) const {
-  return *reference_referent_addr(obj);
+static oop reference_referent(oop reference) {
+  return *reference_referent_addr(reference);
 }
 
-bool ZReferenceProcessor::is_referent_strongly_alive_or_null(oop obj, ReferenceType type) const {
-  // Check if the referent is strongly alive or null, in which case we don't want to
-  // discover the reference. It can only be null if the application called
-  // Reference.enqueue() or Reference.clear().
-  //
+static void reference_set_referent(oop reference, oop referent) {
+  java_lang_ref_Reference::set_referent_raw(reference, referent);
+}
+
+static oop* reference_discovered_addr(oop reference) {
+  return (oop*)java_lang_ref_Reference::discovered_addr_raw(reference);
+}
+
+static oop reference_discovered(oop reference) {
+  return *reference_discovered_addr(reference);
+}
+
+static void reference_set_discovered(oop reference, oop discovered) {
+  java_lang_ref_Reference::set_discovered_raw(reference, discovered);
+}
+
+static oop* reference_next_addr(oop reference) {
+  return (oop*)java_lang_ref_Reference::next_addr_raw(reference);
+}
+
+static oop reference_next(oop reference) {
+  return *reference_next_addr(reference);
+}
+
+static void reference_set_next(oop reference, oop next) {
+  java_lang_ref_Reference::set_next_raw(reference, next);
+}
+
+static void soft_reference_update_clock() {
+  const jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+  java_lang_ref_SoftReference::set_clock(now);
+}
+
+ZReferenceProcessor::ZReferenceProcessor(ZWorkers* workers) :
+    _workers(workers),
+    _soft_reference_policy(NULL),
+    _encountered_count(),
+    _discovered_count(),
+    _enqueued_count(),
+    _discovered_list(NULL),
+    _pending_list(NULL),
+    _pending_list_tail(_pending_list.addr()) {}
+
+void ZReferenceProcessor::set_soft_reference_policy(bool clear) {
+  static AlwaysClearPolicy always_clear_policy;
+  static LRUMaxHeapPolicy lru_max_heap_policy;
+
+  if (clear) {
+    log_info(gc, ref)("Clearing All SoftReferences");
+    _soft_reference_policy = &always_clear_policy;
+  } else {
+    _soft_reference_policy = &lru_max_heap_policy;
+  }
+
+  _soft_reference_policy->setup();
+}
+
+bool ZReferenceProcessor::is_inactive(oop reference, oop referent, ReferenceType type) const {
+  if (type == REF_FINAL) {
+    // A FinalReference is inactive if its next field is non-null. An application can't
+    // call enqueue() or clear() on a FinalReference.
+    return reference_next(reference) != NULL;
+  } else {
+    // A non-FinalReference is inactive if the referent is null. The referent can only
+    // be null if the application called Reference.enqueue() or Reference.clear().
+    return referent == NULL;
+  }
+}
+
+bool ZReferenceProcessor::is_strongly_live(oop referent) const {
+  return ZHeap::heap()->is_object_strongly_live(ZOop::to_address(referent));
+}
+
+bool ZReferenceProcessor::is_softly_live(oop reference, ReferenceType type) const {
+  if (type != REF_SOFT) {
+    // Not a SoftReference
+    return false;
+  }
+
+  // Ask SoftReference policy
+  const jlong clock = java_lang_ref_SoftReference::clock();
+  assert(clock != 0, "Clock not initialized");
+  assert(_soft_reference_policy != NULL, "Policy not initialized");
+  return !_soft_reference_policy->should_clear_reference(reference, clock);
+}
+
+bool ZReferenceProcessor::should_discover(oop reference, ReferenceType type) const {
+  volatile oop* const referent_addr = reference_referent_addr(reference);
+  const oop referent = ZBarrier::weak_load_barrier_on_oop_field(referent_addr);
+
+  if (is_inactive(reference, referent, type)) {
+    return false;
+  }
+
+  if (is_strongly_live(referent)) {
+    return false;
+  }
+
+  if (is_softly_live(reference, type)) {
+    return false;
+  }
+
   // PhantomReferences with finalizable marked referents should technically not have
   // to be discovered. However, InstanceRefKlass::oop_oop_iterate_ref_processing()
   // does not know about the finalizable mark concept, and will therefore mark
   // referents in non-discovered PhantomReferences as strongly live. To prevent
   // this, we always discover PhantomReferences with finalizable marked referents.
   // They will automatically be dropped during the reference processing phase.
-
-  volatile oop* const p = reference_referent_addr(obj);
-  const oop o = ZBarrier::weak_load_barrier_on_oop_field(p);
-  return o == NULL || ZHeap::heap()->is_object_strongly_live(ZOop::to_address(o));
+  return true;
 }
 
-bool ZReferenceProcessor::is_referent_softly_alive(oop obj, ReferenceType type) const {
-  if (type != REF_SOFT) {
-    // Not a soft reference
-    return false;
-  }
-
-  // Ask soft reference policy
-  const jlong clock = java_lang_ref_SoftReference::clock();
-  assert(clock != 0, "Clock not initialized");
-  assert(_soft_reference_policy != NULL, "Policy not initialized");
-  return !_soft_reference_policy->should_clear_reference(obj, clock);
-}
-
-bool ZReferenceProcessor::should_drop_reference(oop obj, ReferenceType type) const {
+bool ZReferenceProcessor::should_drop(oop reference, ReferenceType type) const {
   // This check is racing with a call to Reference.clear() from the application.
   // If the application clears the reference after this check it will still end
   // up on the pending list, and there's nothing we can do about that without
   // changing the Reference.clear() API. This check is also racing with a call
   // to Reference.enqueue() from the application, which is unproblematic, since
   // the application wants the reference to be enqueued anyway.
-  const oop o = reference_referent(obj);
-  if (o == NULL) {
+  const oop referent = reference_referent(reference);
+  if (referent == NULL) {
     // Reference has been cleared, by a call to Reference.enqueue()
     // or Reference.clear() from the application, which means we
     // should drop the reference.
@@ -153,22 +200,14 @@
   // Check if the referent is still alive, in which case we should
   // drop the reference.
   if (type == REF_PHANTOM) {
-    return ZBarrier::is_alive_barrier_on_phantom_oop(o);
+    return ZBarrier::is_alive_barrier_on_phantom_oop(referent);
   } else {
-    return ZBarrier::is_alive_barrier_on_weak_oop(o);
+    return ZBarrier::is_alive_barrier_on_weak_oop(referent);
   }
 }
 
-bool ZReferenceProcessor::should_mark_referent(ReferenceType type) const {
-  // Referents of final references (and its reachable sub graph) are
-  // always marked finalizable during discovery. This avoids the problem
-  // of later having to mark those objects if the referent is still final
-  // reachable during processing.
-  return type == REF_FINAL;
-}
-
-void ZReferenceProcessor::keep_referent_alive(oop obj, ReferenceType type) const {
-  volatile oop* const p = reference_referent_addr(obj);
+void ZReferenceProcessor::keep_alive(oop reference, ReferenceType type) const {
+  volatile oop* const p = reference_referent_addr(reference);
   if (type == REF_PHANTOM) {
     ZBarrier::keep_alive_barrier_on_phantom_oop_field(p);
   } else {
@@ -176,82 +215,86 @@
   }
 }
 
-bool ZReferenceProcessor::discover_reference(oop obj, ReferenceType type) {
+void ZReferenceProcessor::make_inactive(oop reference, ReferenceType type) const {
+  if (type == REF_FINAL) {
+    // Don't clear referent. It is needed by the Finalizer thread to make the call
+    // to finalize(). A FinalReference is instead made inactive by self-looping the
+    // next field. An application can't call FinalReference.enqueue(), so there is
+    // no race to worry about when setting the next field.
+    assert(reference_next(reference) == NULL, "Already inactive");
+    reference_set_next(reference, reference);
+  } else {
+    // Clear referent
+    reference_set_referent(reference, NULL);
+  }
+}
+
+void ZReferenceProcessor::discover(oop reference, ReferenceType type) {
+  log_trace(gc, ref)("Discovered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type));
+
+  // Update statistics
+  _discovered_count.get()[type]++;
+
+  if (type == REF_FINAL) {
+    // Mark referent (and its reachable subgraph) finalizable. This avoids
+    // the problem of later having to mark those objects if the referent is
+    // still final reachable during processing.
+    volatile oop* const referent_addr = reference_referent_addr(reference);
+    ZBarrier::mark_barrier_on_oop_field(referent_addr, true /* finalizable */);
+  }
+
+  // Add reference to discovered list
+  assert(reference_discovered(reference) == NULL, "Already discovered");
+  oop* const list = _discovered_list.addr();
+  reference_set_discovered(reference, *list);
+  *list = reference;
+}
+
+bool ZReferenceProcessor::discover_reference(oop reference, ReferenceType type) {
   if (!RegisterReferences) {
     // Reference processing disabled
     return false;
   }
 
-  log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+  log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type));
 
   // Update statistics
   _encountered_count.get()[type]++;
 
-  if (is_referent_strongly_alive_or_null(obj, type) ||
-      is_inactive_final_reference(obj, type) ||
-      is_referent_softly_alive(obj, type)) {
+  if (!should_discover(reference, type)) {
     // Not discovered
     return false;
   }
 
-  discover(obj, type);
+  discover(reference, type);
 
   // Discovered
   return true;
 }
 
-void ZReferenceProcessor::discover(oop obj, ReferenceType type) {
-  log_trace(gc, ref)("Discovered Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
-
-  // Update statistics
-  _discovered_count.get()[type]++;
-
-  // Mark referent finalizable
-  if (should_mark_referent(type)) {
-    oop* const referent_addr = (oop*)java_lang_ref_Reference::referent_addr_raw(obj);
-    ZBarrier::mark_barrier_on_oop_field(referent_addr, true /* finalizable */);
-  }
-
-  // Add reference to discovered list
-  assert(java_lang_ref_Reference::discovered(obj) == NULL, "Already discovered");
-  oop* const list = _discovered_list.addr();
-  java_lang_ref_Reference::set_discovered(obj, *list);
-  *list = obj;
-}
-
-oop ZReferenceProcessor::drop(oop obj, ReferenceType type) {
-  log_trace(gc, ref)("Dropped Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+oop ZReferenceProcessor::drop(oop reference, ReferenceType type) {
+  log_trace(gc, ref)("Dropped Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type));
 
   // Keep referent alive
-  keep_referent_alive(obj, type);
+  keep_alive(reference, type);
 
   // Unlink and return next in list
-  const oop next = java_lang_ref_Reference::discovered(obj);
-  java_lang_ref_Reference::set_discovered(obj, NULL);
+  const oop next = reference_discovered(reference);
+  reference_set_discovered(reference, NULL);
   return next;
 }
 
-oop* ZReferenceProcessor::keep(oop obj, ReferenceType type) {
-  log_trace(gc, ref)("Enqueued Reference: " PTR_FORMAT " (%s)", p2i(obj), reference_type_name(type));
+oop* ZReferenceProcessor::keep(oop reference, ReferenceType type) {
+  log_trace(gc, ref)("Enqueued Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type));
 
   // Update statistics
   _enqueued_count.get()[type]++;
 
-  if (type != REF_FINAL) {
-    // Clear referent
-    java_lang_ref_Reference::set_referent(obj, NULL);
-  } else {
-    // For a FinalReference, don't clear the referent, because it is
-    // needed for the finalize call.  Instead, make the reference
-    // inactive by self-looping the 'next' field.  FinalReference
-    // doesn't allow Reference.enqueue, so there's no race to worry
-    // about when setting 'next'.
-    assert(java_lang_ref_Reference::next(obj) == NULL, "enqueued FinalReference");
-    java_lang_ref_Reference::set_next_raw(obj, obj);
-  }
+  // Make reference inactive
+  make_inactive(reference, type);
 
   // Return next in list
-  return (oop*)java_lang_ref_Reference::discovered_addr_raw(obj);
+  return reference_discovered_addr(reference);
 }
 
 void ZReferenceProcessor::work() {
@@ -260,13 +303,13 @@
   oop* p = list;
 
   while (*p != NULL) {
-    const oop obj = *p;
-    const ReferenceType type = reference_type(obj);
+    const oop reference = *p;
+    const ReferenceType type = reference_type(reference);
 
-    if (should_drop_reference(obj, type)) {
-      *p = drop(obj, type);
+    if (should_drop(reference, type)) {
+      *p = drop(reference, type);
     } else {
-      p = keep(obj, type);
+      p = keep(reference, type);
     }
   }
 
@@ -390,8 +433,8 @@
   ZReferenceProcessorTask task(this);
   _workers->run_concurrent(&task);
 
-  // Update soft reference clock
-  update_soft_reference_clock();
+  // Update SoftReference clock
+  soft_reference_update_clock();
 
   // Collect, log and trace statistics
   collect_statistics();
--- a/src/hotspot/share/gc/z/zReferenceProcessor.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -46,22 +46,19 @@
   ZContended<oop>      _pending_list;
   oop*                 _pending_list_tail;
 
-  void update_soft_reference_clock() const;
+  bool is_inactive(oop reference, oop referent, ReferenceType type) const;
+  bool is_strongly_live(oop referent) const;
+  bool is_softly_live(oop reference, ReferenceType type) const;
 
-  ReferenceType reference_type(oop obj) const;
-  const char* reference_type_name(ReferenceType type) const;
-  volatile oop* reference_referent_addr(oop obj) const;
-  oop reference_referent(oop obj) const;
-  bool is_inactive_final_reference(oop obj, ReferenceType type) const;
-  bool is_referent_strongly_alive_or_null(oop obj, ReferenceType type) const;
-  bool is_referent_softly_alive(oop obj, ReferenceType type) const;
-  bool should_drop_reference(oop obj, ReferenceType type) const;
-  bool should_mark_referent(ReferenceType type) const;
-  void keep_referent_alive(oop obj, ReferenceType type) const;
+  bool should_discover(oop reference, ReferenceType type) const;
+  bool should_drop(oop reference, ReferenceType type) const;
+  void keep_alive(oop reference, ReferenceType type) const;
+  void make_inactive(oop reference, ReferenceType type) const;
 
-  void discover(oop obj, ReferenceType type);
-  oop drop(oop obj, ReferenceType type);
-  oop* keep(oop obj, ReferenceType type);
+  void discover(oop reference, ReferenceType type);
+
+  oop drop(oop reference, ReferenceType type);
+  oop* keep(oop reference, ReferenceType type);
 
   bool is_empty() const;
 
--- a/src/hotspot/share/gc/z/zServiceability.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/gc/z/zServiceability.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #define SHARE_GC_Z_ZSERVICEABILITY_HPP
 
 #include "gc/shared/collectorCounters.hpp"
+#include "gc/shared/gcVMOperations.hpp"
 #include "memory/allocation.hpp"
 #include "services/memoryManager.hpp"
 #include "services/memoryPool.hpp"
@@ -88,12 +89,14 @@
 template <bool IsGCStart, bool IsGCEnd>
 class ZServiceabilityTracer : public StackObj {
 private:
+  SvcGCMarker                       _svc_gc_marker;
   ZServiceabilityMemoryUsageTracker _memory_usage_tracker;
   ZServiceabilityManagerStatsTracer _manager_stats_tracer;
   ZServiceabilityCountersTracer     _counters_tracer;
 
 public:
   ZServiceabilityTracer() :
+      _svc_gc_marker(SvcGCMarker::CONCURRENT),
       _memory_usage_tracker(),
       _manager_stats_tracer(IsGCStart, IsGCEnd),
       _counters_tracer() {}
--- a/src/hotspot/share/interpreter/bytecodeStream.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/bytecodeStream.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -211,7 +211,6 @@
     return _code;
   }
 
-  bool            is_active_breakpoint() const   { return Bytecodes::is_active_breakpoint_at(bcp()); }
   Bytecodes::Code code() const                   { return _code; }
 
   // Unsigned indices, widening
--- a/src/hotspot/share/interpreter/bytecodeTracer.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/bytecodeTracer.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -225,7 +225,6 @@
   int ilimit = constants->length();
   Bytecodes::Code code = raw_code();
 
-  ConstantPoolCache* cache = NULL;
   if (Bytecodes::uses_cp_cache(code)) {
     bool okay = true;
     switch (code) {
@@ -256,8 +255,7 @@
 
 bool BytecodePrinter::check_cp_cache_index(int i, int& cp_index, outputStream* st) {
   ConstantPool* constants = method()->constants();
-  int ilimit = constants->length(), climit = 0;
-  Bytecodes::Code code = raw_code();
+  int climit = 0;
 
   ConstantPoolCache* cache = constants->cache();
   // If rewriter hasn't run, the index is the cp_index
@@ -307,7 +305,6 @@
 
 
 bool BytecodePrinter::check_invokedynamic_index(int i, int& cp_index, outputStream* st) {
-  ConstantPool* constants = method()->constants();
   assert(ConstantPool::is_invokedynamic_index(i), "not secondary index?");
   i = ConstantPool::decode_invokedynamic_index(i) + ConstantPool::CPCACHE_INDEX_TAG;
 
--- a/src/hotspot/share/interpreter/bytecodes.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/bytecodes.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -380,7 +380,6 @@
   static Code       code_or_bp_at(address bcp)    { return (Code)cast(*bcp); }
 
   static Code       code_at(Method* method, int bci);
-  static bool       is_active_breakpoint_at(address bcp) { return (Code)*bcp == _breakpoint; }
 
   // find a bytecode, behind a breakpoint if necessary:
   static Code       non_breakpoint_code_at(const Method* method, address bcp);
@@ -405,18 +404,12 @@
   // if 'end' is provided, it indicates the end of the code buffer which
   // should not be read past when parsing.
   static int         special_length_at(Bytecodes::Code code, address bcp, address end = NULL);
-  static int         special_length_at(Method* method, address bcp, address end = NULL) { return special_length_at(code_at(method, bcp), bcp, end); }
   static int         raw_special_length_at(address bcp, address end = NULL);
   static int         length_for_code_at(Bytecodes::Code code, address bcp)  { int l = length_for(code); return l > 0 ? l : special_length_at(code, bcp); }
   static int         length_at      (Method* method, address bcp)  { return length_for_code_at(code_at(method, bcp), bcp); }
   static int         java_length_at (Method* method, address bcp)  { return length_for_code_at(java_code_at(method, bcp), bcp); }
   static bool        is_java_code   (Code code)    { return 0 <= code && code < number_of_java_codes; }
 
-  static bool        is_aload       (Code code)    { return (code == _aload  || code == _aload_0  || code == _aload_1
-                                                                             || code == _aload_2  || code == _aload_3); }
-  static bool        is_astore      (Code code)    { return (code == _astore || code == _astore_0 || code == _astore_1
-                                                                             || code == _astore_2 || code == _astore_3); }
-
   static bool        is_store_into_local(Code code){ return (_istore <= code && code <= _astore_3); }
   static bool        is_const       (Code code)    { return (_aconst_null <= code && code <= _ldc2_w); }
   static bool        is_zero_const  (Code code)    { return (code == _aconst_null || code == _iconst_0
@@ -433,7 +426,6 @@
     assert(code == (u_char)code, "must be a byte");
     return _flags[code + (is_wide ? (1<<BitsPerByte) : 0)];
   }
-  static int         format_bits    (Code code, bool is_wide) { return flags(code, is_wide) & _all_fmt_bits; }
   static bool        has_all_flags  (Code code, int test_flags, bool is_wide) {
     return (flags(code, is_wide) & test_flags) == test_flags;
   }
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -135,11 +135,6 @@
   frame& get_frame()                             { return _last_frame; }
 };
 
-
-bool InterpreterRuntime::is_breakpoint(JavaThread *thread) {
-  return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint;
-}
-
 //------------------------------------------------------------------------------------------------------------------------
 // State accessors
 
--- a/src/hotspot/share/interpreter/interpreterRuntime.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -126,7 +126,6 @@
   static void _breakpoint(JavaThread* thread, Method* method, address bcp);
   static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
   static void            set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
-  static bool is_breakpoint(JavaThread *thread);
 
   // Safepoints
   static void    at_safepoint(JavaThread* thread);
--- a/src/hotspot/share/interpreter/invocationCounter.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/invocationCounter.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -78,10 +78,11 @@
 
 int                       InvocationCounter::_init  [InvocationCounter::number_of_states];
 InvocationCounter::Action InvocationCounter::_action[InvocationCounter::number_of_states];
+
+#ifdef CC_INTERP
 int                       InvocationCounter::InterpreterInvocationLimit;
 int                       InvocationCounter::InterpreterBackwardBranchLimit;
-int                       InvocationCounter::InterpreterProfileLimit;
-
+#endif
 
 const char* InvocationCounter::state_as_string(State state) {
   switch (state) {
@@ -136,8 +137,8 @@
   def(wait_for_nothing, 0, do_nothing);
   def(wait_for_compile, 0, do_decay);
 
+#ifdef CC_INTERP
   InterpreterInvocationLimit = CompileThreshold << number_of_noncount_bits;
-  InterpreterProfileLimit = ((CompileThreshold * InterpreterProfilePercentage) / 100)<< number_of_noncount_bits;
 
   // When methodData is collected, the backward branch limit is compared against a
   // methodData counter, rather than an InvocationCounter.  In the former case, we
@@ -149,12 +150,8 @@
     InterpreterBackwardBranchLimit = (int)(((int64_t)CompileThreshold * OnStackReplacePercentage / 100) << number_of_noncount_bits);
   }
 
-  assert(0 <= InterpreterBackwardBranchLimit,
-         "OSR threshold should be non-negative");
-  assert(0 <= InterpreterProfileLimit &&
-         InterpreterProfileLimit <= InterpreterInvocationLimit,
-         "profile threshold should be less than the compilation threshold "
-         "and non-negative");
+  assert(0 <= InterpreterBackwardBranchLimit, "OSR threshold should be non-negative");
+#endif
 }
 
 void invocationCounter_init() {
--- a/src/hotspot/share/interpreter/invocationCounter.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/interpreter/invocationCounter.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -57,10 +57,6 @@
   };
 
  public:
-  static int InterpreterInvocationLimit;        // CompileThreshold scaled for interpreter use
-  static int InterpreterBackwardBranchLimit;    // A separate threshold for on stack replacement
-  static int InterpreterProfileLimit;           // Profiling threshold scaled for interpreter use
-
   typedef address (*Action)(const methodHandle& method, TRAPS);
 
   enum PublicConstants {
@@ -95,11 +91,10 @@
   Action action() const                          { return _action[state()]; }
   int    count() const                           { return _counter >> number_of_noncount_bits; }
 
-  int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
-  int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
-  int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
+#ifdef CC_INTERP
+  static int InterpreterInvocationLimit;        // CompileThreshold scaled for interpreter use
+  static int InterpreterBackwardBranchLimit;    // A separate threshold for on stack replacement
 
-#ifdef CC_INTERP
   // Test counter using scaled limits like the asm interpreter would do rather than doing
   // the shifts to normalize the counter.
   // Checks sum of invocation_counter and backedge_counter as the template interpreter does.
@@ -111,11 +106,6 @@
     return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >=
            (unsigned int) InterpreterBackwardBranchLimit;
   }
-  // Do this just like asm interpreter does for max speed.
-  bool reached_ProfileLimit(InvocationCounter *back_edge_count) const {
-    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >=
-           (unsigned int) InterpreterProfileLimit;
-  }
 #endif // CC_INTERP
 
   void increment()                               { _counter += count_increment; }
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #include "jfr/jni/jfrJavaSupport.hpp"
 #include "jfr/recorder/repository/jfrChunkRotation.hpp"
 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
+#include "runtime/handles.inline.hpp"
 
 static jobject chunk_monitor = NULL;
 static intptr_t threshold = 0;
--- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
 #include "jfr/utilities/jfrTypes.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.hpp"
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/thread.inline.hpp"
 
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "aot/aotLoader.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "interpreter/linkResolver.hpp"
@@ -29,12 +30,12 @@
 #include "oops/cpCache.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/compilationPolicy.hpp"
+#include "runtime/deoptimization.hpp"
 #include "runtime/frame.inline.hpp"
-#include "runtime/deoptimization.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/vframe.inline.hpp"
 #include "utilities/sizes.hpp"
-#include "aot/aotLoader.hpp"
 
 // Resolve and allocate String
 JRT_BLOCK_ENTRY(void, CompilerRuntime::resolve_string_by_symbol(JavaThread *thread, void* string_result, const char* name))
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -39,6 +39,7 @@
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -40,6 +40,7 @@
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/timerTrace.hpp"
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/reflection.hpp"
--- a/src/hotspot/share/libadt/set.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/libadt/set.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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,22 +35,8 @@
 
 //-------------------------Virtual Functions-----------------------------------
 // These functions MUST be implemented by the inheriting class.
-class SparseSet;
-/* Removed for MCC BUG
-   Set::operator const SparseSet*() const { assert(0); return NULL; } */
-const SparseSet *Set::asSparseSet() const { assert(0); return NULL; }
 class VectorSet;
-/* Removed for MCC BUG
-   Set::operator const VectorSet*() const { assert(0); return NULL; } */
 const VectorSet *Set::asVectorSet() const { assert(0); return NULL; }
-class ListSet;
-/* Removed for MCC BUG
-   Set::operator const ListSet*() const { assert(0); return NULL; } */
-const ListSet *Set::asListSet() const { assert(0); return NULL; }
-class CoSet;
-/* Removed for MCC BUG
-   Set::operator const CoSet*() const { assert(0); return NULL; } */
-const CoSet *Set::asCoSet() const { assert(0); return NULL; }
 
 //------------------------------setstr-----------------------------------------
 // Create a string with a printable representation of a set.
--- a/src/hotspot/share/libadt/set.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/libadt/set.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -164,9 +164,6 @@
   virtual int operator <=(const Set &s) const=0;
   int operator >=(const Set &s) const { return s <= *this; }
 
-  // Return any member of the Set.  Undefined if the Set is empty.
-  virtual uint getelem(void) const=0;
-
   // Clear all the elements in the Set
   virtual void Clear(void)=0;
 
@@ -188,15 +185,7 @@
   virtual int parse(const char *s);
 
   // Convert a generic Set to a specific Set
-  /* Removed for MCC BUG
-     virtual operator const SparseSet* (void) const;
-     virtual operator const VectorSet* (void) const;
-     virtual operator const ListSet  * (void) const;
-     virtual operator const CoSet    * (void) const; */
-  virtual const SparseSet *asSparseSet(void) const;
   virtual const VectorSet *asVectorSet(void) const;
-  virtual const ListSet   *asListSet  (void) const;
-  virtual const CoSet     *asCoSet    (void) const;
 
   // Hash the set.  Sets of different types but identical elements will NOT
   // hash the same.  Same set type, same elements WILL hash the same.
@@ -204,16 +193,11 @@
 
 protected:
   friend class SetI;
-  friend class CoSet;
   virtual class SetI_ *iterate(uint&) const=0;
 
   // Need storeage for the set
   Arena *_set_arena;
 };
-typedef Set&((*Set_Constructor)(Arena *arena));
-extern Set &ListSet_Construct(Arena *arena);
-extern Set &VectorSet_Construct(Arena *arena);
-extern Set &SparseSet_Construct(Arena *arena);
 
 //------------------------------Iteration--------------------------------------
 // Loop thru all elements of the set, setting "elem" to the element numbers
--- a/src/hotspot/share/libadt/vectset.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/libadt/vectset.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,12 +60,6 @@
   data[1] = 0;
 }
 
-//------------------------------Construct--------------------------------------
-Set &VectorSet_Construct(Arena *arena)
-{
-  return *(new VectorSet(arena));
-}
-
 //------------------------------operator=--------------------------------------
 Set &VectorSet::operator = (const Set &set)
 {
@@ -293,20 +287,6 @@
   return ((data[word] & mask))!=0;    // Return the sense of the bit
 }
 
-//------------------------------getelem----------------------------------------
-// Get any element from the set.
-uint VectorSet::getelem(void) const
-{
-  uint i;                       // Exit value of loop
-  for( i=0; i<size; i++ )
-    if( data[i] )
-      break;
-  uint32_t word = data[i];
-  int j;                        // Exit value of loop
-  for( j= -1; word; j++, word>>=1 );
-  return (i<<5)+j;
-}
-
 //------------------------------Clear------------------------------------------
 // Clear a set
 void VectorSet::Clear(void)
--- a/src/hotspot/share/libadt/vectset.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/libadt/vectset.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -95,7 +95,6 @@
   int disjoint   (const Set       &s) const;  // True if sets are disjoint
 
   int operator [](uint elem) const; // Test for membership
-  uint getelem(void) const;         // Return a random element
   void Clear(void);                 // Clear a set
   uint Size(void) const;            // Number of elements in the Set.
   void Sort(void);                  // Sort before iterating
--- a/src/hotspot/share/logging/logPrefix.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/logging/logPrefix.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -79,7 +79,6 @@
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, reloc)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \
-  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, stringtable)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, symboltable)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, sweep)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task)) \
--- a/src/hotspot/share/memory/binaryTreeDictionary.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/binaryTreeDictionary.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -120,7 +120,6 @@
   // node to point to the new node.
   TreeList<Chunk_t, FreeList_t>* remove_chunk_replace_if_needed(TreeChunk<Chunk_t, FreeList_t>* tc);
   // See FreeList.
-  void return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* tc);
   void return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* tc);
 };
 
@@ -236,7 +235,6 @@
   size_t     num_free_blocks()  const;
   size_t     tree_height() const;
   size_t     tree_height_helper(TreeList<Chunk_t, FreeList_t>* tl) const;
-  size_t     total_nodes_in_tree(TreeList<Chunk_t, FreeList_t>* tl) const;
   size_t     total_nodes_helper(TreeList<Chunk_t, FreeList_t>* tl) const;
 
  public:
--- a/src/hotspot/share/memory/binaryTreeDictionary.inline.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/binaryTreeDictionary.inline.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -245,35 +245,6 @@
   assert(tail() == NULL || tail()->next() == NULL, "list invariant");
 }
 
-// Add this chunk at the head of the list.  "At the head of the list"
-// is defined to be after the chunk pointer to by head().  This is
-// because the TreeList<Chunk_t, FreeList_t> is embedded in the first TreeChunk<Chunk_t, FreeList_t> in the
-// list.  See the definition of TreeChunk<Chunk_t, FreeList_t>.
-template <class Chunk_t, class FreeList_t>
-void TreeList<Chunk_t, FreeList_t>::return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* chunk) {
-  assert(chunk->list() == this, "list should be set for chunk");
-  assert(head() != NULL, "The tree list is embedded in the first chunk");
-  assert(chunk != NULL, "returning NULL chunk");
-  // This is expensive for metaspace
-  assert(!FLSVerifyDictionary || !this->verify_chunk_in_free_list(chunk), "Double entry");
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-
-  Chunk_t* fc = head()->next();
-  if (fc != NULL) {
-    chunk->link_after(fc);
-  } else {
-    assert(tail() == NULL, "List is inconsistent");
-    this->link_tail(chunk);
-  }
-  head()->link_after(chunk);
-  assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
-  FreeList_t::increment_count();
-  debug_only(this->increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-}
-
 template <class Chunk_t, class FreeList_t>
 void TreeChunk<Chunk_t, FreeList_t>::assert_is_mangled() const {
   assert((ZapUnusedHeapArea &&
@@ -799,11 +770,6 @@
     total_nodes_helper(tl->right());
 }
 
-template <class Chunk_t, class FreeList_t>
-size_t BinaryTreeDictionary<Chunk_t, FreeList_t>::total_nodes_in_tree(TreeList<Chunk_t, FreeList_t>* tl) const {
-  return total_nodes_helper(root());
-}
-
 // Searches the tree for a chunk that ends at the
 // specified address.
 template <class Chunk_t, class FreeList_t>
--- a/src/hotspot/share/memory/heapShared.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/heapShared.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -191,9 +191,6 @@
   static void verify_subgraph_from(oop orig_obj) PRODUCT_RETURN;
 
   static KlassSubGraphInfo* get_subgraph_info(Klass *k);
-  static int num_of_subgraph_infos();
-
-  static void build_archived_subgraph_info_records(int num_records);
 
   static void init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[],
                                          int num, Thread* THREAD);
@@ -321,10 +318,6 @@
 
   inline static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
 
-  static void archive_java_heap_objects() NOT_CDS_JAVA_HEAP_RETURN;
-
-  static char* read_archived_subgraph_infos(char* buffer) NOT_CDS_JAVA_HEAP_RETURN_(buffer);
-  static void write_archived_subgraph_infos() NOT_CDS_JAVA_HEAP_RETURN;
   static void initialize_from_archived_subgraph(Klass* k) NOT_CDS_JAVA_HEAP_RETURN;
 
   // NarrowOops stored in the CDS archive may use a different encoding scheme
--- a/src/hotspot/share/memory/metaspace.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/metaspace.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -132,7 +132,15 @@
   return value;
 }
 
-bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) {
+// Try to increase the _capacity_until_GC limit counter by v bytes.
+// Returns true if it succeeded. It may fail if either another thread
+// concurrently increased the limit or the new limit would be larger
+// than MaxMetaspaceSize.
+// On success, optionally returns new and old metaspace capacity in
+// new_cap_until_GC and old_cap_until_GC respectively.
+// On error, optionally sets can_retry to indicate whether if there is
+// actually enough space remaining to satisfy the request.
+bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC, bool* can_retry) {
   assert_is_aligned(v, Metaspace::commit_alignment());
 
   size_t old_capacity_until_GC = _capacity_until_GC;
@@ -143,6 +151,16 @@
     new_value = align_down(max_uintx, Metaspace::commit_alignment());
   }
 
+  if (new_value > MaxMetaspaceSize) {
+    if (can_retry != NULL) {
+      *can_retry = false;
+    }
+    return false;
+  }
+
+  if (can_retry != NULL) {
+    *can_retry = true;
+  }
   size_t prev_value = Atomic::cmpxchg(new_value, &_capacity_until_GC, old_capacity_until_GC);
 
   if (old_capacity_until_GC != prev_value) {
@@ -236,7 +254,7 @@
 
   const double min_tmp = used_after_gc / maximum_used_percentage;
   size_t minimum_desired_capacity =
-    (size_t)MIN2(min_tmp, double(max_uintx));
+    (size_t)MIN2(min_tmp, double(MaxMetaspaceSize));
   // Don't shrink less than the initial generation size
   minimum_desired_capacity = MAX2(minimum_desired_capacity,
                                   MetaspaceSize);
@@ -283,7 +301,7 @@
     const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0;
     const double minimum_used_percentage = 1.0 - maximum_free_percentage;
     const double max_tmp = used_after_gc / minimum_used_percentage;
-    size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
+    size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(MaxMetaspaceSize));
     maximum_desired_capacity = MAX2(maximum_desired_capacity,
                                     MetaspaceSize);
     log_trace(gc, metaspace)("    maximum_free_percentage: %6.2f  minimum_used_percentage: %6.2f",
@@ -586,15 +604,15 @@
   if (Metaspace::using_class_space()) {
     out->print("   Non-Class:  ");
   }
-  print_human_readable_size(out, Metaspace::chunk_manager_metadata()->free_chunks_total_words(), scale);
+  print_human_readable_size(out, Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale);
   out->cr();
   if (Metaspace::using_class_space()) {
     out->print("       Class:  ");
-    print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_words(), scale);
+    print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes(), scale);
     out->cr();
     out->print("        Both:  ");
-    print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_words() +
-                              Metaspace::chunk_manager_metadata()->free_chunks_total_words(), scale);
+    print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes() +
+                              Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale);
     out->cr();
   }
   out->cr();
@@ -873,19 +891,6 @@
   return vsn;
 }
 
-bool MetaspaceUtils::is_in_committed(const void* p) {
-#if INCLUDE_CDS
-  if (UseSharedSpaces) {
-    for (int idx = MetaspaceShared::ro; idx <= MetaspaceShared::mc; idx++) {
-      if (FileMapInfo::current_info()->is_in_shared_region(p, idx)) {
-        return true;
-      }
-    }
-  }
-#endif
-  return find_enclosing_virtual_space(p) != NULL;
-}
-
 bool MetaspaceUtils::is_range_in_committed(const void* from, const void* to) {
 #if INCLUDE_CDS
   if (UseSharedSpaces) {
@@ -1483,6 +1488,7 @@
 
   size_t before = 0;
   size_t after = 0;
+  bool can_retry = true;
   MetaWord* res;
   bool incremented;
 
@@ -1490,9 +1496,9 @@
   // the HWM, an allocation is still attempted. This is because another thread must then
   // have incremented the HWM and therefore the allocation might still succeed.
   do {
-    incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before);
+    incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry);
     res = allocate(word_size, mdtype);
-  } while (!incremented && res == NULL);
+  } while (!incremented && res == NULL && can_retry);
 
   if (incremented) {
     Metaspace::tracer()->report_gc_threshold(before, after,
--- a/src/hotspot/share/memory/metaspace.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/metaspace.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -333,7 +333,6 @@
   // Utils to check if a pointer or range is part of a committed metaspace region
   // without acquiring any locks.
   static metaspace::VirtualSpaceNode* find_enclosing_virtual_space(const void* p);
-  static bool is_in_committed(const void* p);
   static bool is_range_in_committed(const void* from, const void* to);
 
 public:
@@ -387,9 +386,6 @@
   }
 
   static size_t min_chunk_size_words();
-  static size_t min_chunk_size_bytes() {
-    return min_chunk_size_words() * BytesPerWord;
-  }
 
   // Flags for print_report().
   enum ReportFlag {
@@ -461,7 +457,8 @@
   static size_t capacity_until_GC();
   static bool inc_capacity_until_GC(size_t v,
                                     size_t* new_cap_until_GC = NULL,
-                                    size_t* old_cap_until_GC = NULL);
+                                    size_t* old_cap_until_GC = NULL,
+                                    bool* can_retry = NULL);
   static size_t dec_capacity_until_GC(size_t v);
 
   static bool should_concurrent_collect() { return _should_concurrent_collect; }
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -218,10 +218,6 @@
   return _ro_region.allocate(num_bytes);
 }
 
-char* MetaspaceShared::read_only_space_top() {
-  return _ro_region.top();
-}
-
 void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
   assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled");
 
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -168,14 +168,11 @@
 
   static bool try_link_class(InstanceKlass* ik, TRAPS);
   static void link_and_cleanup_shared_classes(TRAPS);
-  static void check_shared_class_loader_type(InstanceKlass* ik);
 
   // Allocate a block of memory from the "mc", "ro", or "rw" regions.
   static char* misc_code_space_alloc(size_t num_bytes);
   static char* read_only_space_alloc(size_t num_bytes);
 
-  static char* read_only_space_top();
-
   template <typename T>
   static Array<T>* new_ro_array(int length) {
 #if INCLUDE_CDS
--- a/src/hotspot/share/memory/universe.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/universe.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -1286,14 +1286,6 @@
 #endif // PRODUCT
 
 
-void Universe::compute_verify_oop_data() {
-  verify_oop_mask();
-  verify_oop_bits();
-  verify_mark_mask();
-  verify_mark_bits();
-}
-
-
 void LatestMethodCache::init(Klass* k, Method* m) {
   if (!UseSharedSpaces) {
     _klass = k;
--- a/src/hotspot/share/memory/universe.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/universe.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -258,7 +258,6 @@
   static uintptr_t _verify_oop_bits;
 
   static void calculate_verify_data(HeapWord* low_boundary, HeapWord* high_boundary) PRODUCT_RETURN;
-  static void compute_verify_oop_data();
 
  public:
   // Known classes in the VM
@@ -392,8 +391,6 @@
   };
   static NARROW_OOP_MODE narrow_oop_mode();
   static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode);
-  static char*    preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode);
-  static char*    preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
   static address  narrow_oop_base()                  { return  _narrow_oop._base; }
   // Test whether bits of addr and possible offsets into the heap overlap.
   static bool     is_disjoint_heap_base_address(address addr) {
@@ -416,10 +413,8 @@
 
   // For UseCompressedClassPointers
   static address  narrow_klass_base()                     { return  _narrow_klass._base; }
-  static bool  is_narrow_klass_base(void* addr)           { return (narrow_klass_base() == (address)addr); }
   static uint64_t narrow_klass_range()                    { return  _narrow_klass_range; }
   static int      narrow_klass_shift()                    { return  _narrow_klass._shift; }
-  static bool     narrow_klass_use_implicit_null_checks() { return  _narrow_klass._use_implicit_null_checks; }
 
   static address* narrow_ptrs_base_addr()                 { return &_narrow_ptrs_base; }
   static void     set_narrow_ptrs_base(address a)         { _narrow_ptrs_base = a; }
@@ -441,7 +436,6 @@
   static ReservedSpace reserve_heap(size_t heap_size, size_t alignment);
 
   // Historic gc information
-  static size_t get_heap_capacity_at_last_gc()         { return _heap_capacity_at_last_gc; }
   static size_t get_heap_free_at_last_gc()             { return _heap_capacity_at_last_gc - _heap_used_at_last_gc; }
   static size_t get_heap_used_at_last_gc()             { return _heap_used_at_last_gc; }
   static void update_heap_info_at_gc();
@@ -517,25 +511,4 @@
   static int base_vtable_size()               { return _base_vtable_size; }
 };
 
-class DeferredObjAllocEvent : public CHeapObj<mtInternal> {
-  private:
-    oop    _oop;
-    size_t _bytesize;
-    jint   _arena_id;
-
-  public:
-    DeferredObjAllocEvent(const oop o, const size_t s, const jint id) {
-      _oop      = o;
-      _bytesize = s;
-      _arena_id = id;
-    }
-
-    ~DeferredObjAllocEvent() {
-    }
-
-    jint   arena_id() { return _arena_id; }
-    size_t bytesize() { return _bytesize; }
-    oop    get_oop()  { return _oop; }
-};
-
 #endif // SHARE_MEMORY_UNIVERSE_HPP
--- a/src/hotspot/share/memory/virtualspace.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/virtualspace.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -266,11 +266,6 @@
 }
 
 
-size_t ReservedSpace::allocation_align_size_down(size_t size) {
-  return align_down(size, os::vm_allocation_granularity());
-}
-
-
 void ReservedSpace::release() {
   if (is_reserved()) {
     char *real_base = _base - _noaccess_prefix;
--- a/src/hotspot/share/memory/virtualspace.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/memory/virtualspace.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -88,7 +88,6 @@
   static size_t page_align_size_up(size_t size);
   static size_t page_align_size_down(size_t size);
   static size_t allocation_align_size_up(size_t size);
-  static size_t allocation_align_size_down(size_t size);
   bool contains(const void* p) const {
     return (base() <= ((char*)p)) && (((char*)p) < (base() + size()));
   }
--- a/src/hotspot/share/oops/compiledICHolder.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/compiledICHolder.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -65,9 +65,6 @@
   Klass*    holder_klass()  const     { return _holder_klass; }
   Metadata* holder_metadata() const   { return _holder_metadata; }
 
-  void set_holder_metadata(Metadata* m) { _holder_metadata = m; }
-  void set_holder_klass(Klass* k)     { _holder_klass = k; }
-
   static int holder_metadata_offset() { return offset_of(CompiledICHolder, _holder_metadata); }
   static int holder_klass_offset()    { return offset_of(CompiledICHolder, _holder_klass); }
 
--- a/src/hotspot/share/oops/constMethod.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/constMethod.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -426,7 +426,6 @@
 
 void ConstMethod::print_on(outputStream* st) const {
   ResourceMark rm;
-  assert(is_constMethod(), "must be constMethod");
   st->print_cr("%s", internal_name());
   Method* m = method();
   st->print(" - method:       " INTPTR_FORMAT " ", p2i((address)m));
@@ -444,7 +443,6 @@
 // Short version of printing ConstMethod* - just print the name of the
 // method it belongs to.
 void ConstMethod::print_value_on(outputStream* st) const {
-  assert(is_constMethod(), "must be constMethod");
   st->print(" const part of method " );
   Method* m = method();
   if (m != NULL) {
@@ -487,8 +485,6 @@
 // Verification
 
 void ConstMethod::verify_on(outputStream* st) {
-  guarantee(is_constMethod(), "object must be constMethod");
-
   // Verification can occur during oop construction before the method or
   // other fields have been initialized.
   guarantee(method() != NULL && method()->is_method(), "should be method");
--- a/src/hotspot/share/oops/constMethod.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/constMethod.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -241,8 +241,6 @@
                                MethodType mt,
                                TRAPS);
 
-  bool is_constMethod() const { return true; }
-
   // Inlined tables
   void set_inlined_tables_length(InlineTableSizes* sizes);
 
--- a/src/hotspot/share/oops/constantPool.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/constantPool.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,7 @@
 #include "runtime/init.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
 #include "runtime/vframe.inline.hpp"
 #include "utilities/copy.hpp"
 
@@ -448,6 +449,7 @@
 Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int which,
                                    bool save_resolution_error, TRAPS) {
   assert(THREAD->is_Java_thread(), "must be a Java thread");
+  JavaThread* javaThread = (JavaThread*)THREAD;
 
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
   // It is not safe to rely on the tag bit's here, since we don't have a lock, and
@@ -480,7 +482,14 @@
   Symbol* name = this_cp->symbol_at(name_index);
   Handle loader (THREAD, this_cp->pool_holder()->class_loader());
   Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain());
-  Klass* k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD);
+
+  Klass* k;
+  {
+    // Turn off the single stepping while doing class resolution
+    JvmtiHideSingleStepping jhss(javaThread);
+    k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD);
+  } //  JvmtiHideSingleStepping jhss(javaThread);
+
   if (!HAS_PENDING_EXCEPTION) {
     // preserve the resolved klass from unloading
     mirror_handle = Handle(THREAD, k->java_mirror());
@@ -817,9 +826,9 @@
   constantTag tag = tag_at(which);
   if (tag.is_dynamic_constant() ||
       tag.is_dynamic_constant_in_error()) {
-    // have to look at the signature for this one
-    Symbol* constant_type = uncached_signature_ref_at(which);
-    return constantTag::ofBasicType(FieldType::basic_type(constant_type));
+    BasicType bt = basic_type_for_constant_at(which);
+    // dynamic constant could return an array, treat as object
+    return constantTag::ofBasicType(is_reference_type(bt) ? T_OBJECT : bt);
   }
   return tag;
 }
@@ -2515,11 +2524,6 @@
       guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");
     }
   }
-  if (cache() != NULL) {
-    // Note: cache() can be NULL before a class is completely setup or
-    // in temporary constant pools used during constant pool merging
-    guarantee(cache()->is_constantPoolCache(), "should be constant pool cache");
-  }
   if (pool_holder() != NULL) {
     // Note: pool_holder() can be NULL in temporary constant pools
     // used during constant pool merging
--- a/src/hotspot/share/oops/cpCache.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/cpCache.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -851,14 +851,12 @@
 // Printing
 
 void ConstantPoolCache::print_on(outputStream* st) const {
-  assert(is_constantPoolCache(), "obj must be constant pool cache");
   st->print_cr("%s", internal_name());
   // print constant pool cache entries
   for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
 }
 
 void ConstantPoolCache::print_value_on(outputStream* st) const {
-  assert(is_constantPoolCache(), "obj must be constant pool cache");
   st->print("cache [%d]", length());
   print_address_on(st);
   st->print(" for ");
@@ -869,7 +867,6 @@
 // Verification
 
 void ConstantPoolCache::verify_on(outputStream* st) {
-  guarantee(is_constantPoolCache(), "obj must be constant pool cache");
   // print constant pool cache entries
   for (int i = 0; i < length(); i++) entry_at(i)->verify(st);
 }
--- a/src/hotspot/share/oops/cpCache.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/cpCache.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -444,7 +444,6 @@
                                      const intStack& cp_cache_map,
                                      const intStack& invokedynamic_cp_cache_map,
                                      const intStack& invokedynamic_references_map, TRAPS);
-  bool is_constantPoolCache() const { return true; }
 
   int length() const                      { return _length; }
   void metaspace_pointers_do(MetaspaceClosure* it);
--- a/src/hotspot/share/oops/method.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/oops/method.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -2403,7 +2403,6 @@
 void Method::verify_on(outputStream* st) {
   guarantee(is_method(), "object must be method");
   guarantee(constants()->is_constantPool(), "should be constant pool");
-  guarantee(constMethod()->is_constMethod(), "should be ConstMethod*");
   MethodData* md = method_data();
   guarantee(md == NULL ||
       md->is_methodData(), "should be method data");
--- a/src/hotspot/share/opto/c2_globals.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/c2_globals.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -516,7 +516,7 @@
           "Sets max value cached by the java.lang.Integer autobox cache")   \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(bool, AggressiveUnboxing, false,                             \
+  experimental(bool, AggressiveUnboxing, true,                              \
           "Control optimizations for aggressive boxing elimination")        \
                                                                             \
   develop(bool, TracePostallocExpand, false, "Trace expanding nodes after"  \
--- a/src/hotspot/share/opto/c2compiler.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/c2compiler.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "runtime/handles.inline.hpp"
 #include "jfr/support/jfrIntrinsics.hpp"
 #include "opto/c2compiler.hpp"
 #include "opto/compile.hpp"
--- a/src/hotspot/share/opto/callGenerator.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/callGenerator.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -459,7 +459,7 @@
   C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops());
   C->env()->notice_inlined_method(_inline_cg->method());
   C->set_inlining_progress(true);
-
+  C->set_do_cleanup(kit.stopped()); // path is dead; needs cleanup
   kit.replace_call(call, result, true);
 }
 
@@ -652,11 +652,13 @@
   CallGenerator* _if_missed;
   CallGenerator* _if_hit;
   float          _hit_prob;
+  bool           _exact_check;
 
 public:
   PredictedCallGenerator(ciKlass* predicted_receiver,
                          CallGenerator* if_missed,
-                         CallGenerator* if_hit, float hit_prob)
+                         CallGenerator* if_hit, bool exact_check,
+                         float hit_prob)
     : CallGenerator(if_missed->method())
   {
     // The call profile data may predict the hit_prob as extreme as 0 or 1.
@@ -668,6 +670,7 @@
     _if_missed          = if_missed;
     _if_hit             = if_hit;
     _hit_prob           = hit_prob;
+    _exact_check        = exact_check;
   }
 
   virtual bool      is_virtual()   const    { return true; }
@@ -682,9 +685,16 @@
                                                  CallGenerator* if_missed,
                                                  CallGenerator* if_hit,
                                                  float hit_prob) {
-  return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit, hit_prob);
+  return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit,
+                                    /*exact_check=*/true, hit_prob);
 }
 
+CallGenerator* CallGenerator::for_guarded_call(ciKlass* guarded_receiver,
+                                               CallGenerator* if_missed,
+                                               CallGenerator* if_hit) {
+  return new PredictedCallGenerator(guarded_receiver, if_missed, if_hit,
+                                    /*exact_check=*/false, PROB_ALWAYS);
+}
 
 JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
   GraphKit kit(jvms);
@@ -695,8 +705,8 @@
   Node* receiver = kit.argument(0);
   CompileLog* log = kit.C->log();
   if (log != NULL) {
-    log->elem("predicted_call bci='%d' klass='%d'",
-              jvms->bci(), log->identify(_predicted_receiver));
+    log->elem("predicted_call bci='%d' exact='%d' klass='%d'",
+              jvms->bci(), (_exact_check ? 1 : 0), log->identify(_predicted_receiver));
   }
 
   receiver = kit.null_check_receiver_before_call(method());
@@ -708,10 +718,15 @@
   ReplacedNodes replaced_nodes = kit.map()->replaced_nodes();
   replaced_nodes.clone();
 
-  Node* exact_receiver = receiver;  // will get updated in place...
-  Node* slow_ctl = kit.type_check_receiver(receiver,
-                                           _predicted_receiver, _hit_prob,
-                                           &exact_receiver);
+  Node* casted_receiver = receiver;  // will get updated in place...
+  Node* slow_ctl = NULL;
+  if (_exact_check) {
+    slow_ctl = kit.type_check_receiver(receiver, _predicted_receiver, _hit_prob,
+                                       &casted_receiver);
+  } else {
+    slow_ctl = kit.subtype_check_receiver(receiver, _predicted_receiver,
+                                          &casted_receiver);
+  }
 
   SafePointNode* slow_map = NULL;
   JVMState* slow_jvms = NULL;
@@ -736,7 +751,7 @@
   }
 
   // fall through if the instance exactly matches the desired type
-  kit.replace_in_map(receiver, exact_receiver);
+  kit.replace_in_map(receiver, casted_receiver);
 
   // Make the hot call:
   JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
--- a/src/hotspot/share/opto/callGenerator.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/callGenerator.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -144,6 +144,10 @@
                                            CallGenerator* if_hit,
                                            float hit_prob);
 
+  static CallGenerator* for_guarded_call(ciKlass* predicted_receiver,
+                                         CallGenerator* if_missed,
+                                         CallGenerator* if_hit);
+
   // How to make a call that optimistically assumes a MethodHandle target:
   static CallGenerator* for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
                                                    CallGenerator* if_missed,
--- a/src/hotspot/share/opto/castnode.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/castnode.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -410,11 +410,11 @@
                                 Node* dispX,
                                 bool negate = false) {
   if (negate) {
-    dispX = new SubXNode(phase->MakeConX(0), phase->transform(dispX));
+    dispX = phase->transform(new SubXNode(phase->MakeConX(0), dispX));
   }
   return new AddPNode(phase->C->top(),
                       phase->transform(new CastX2PNode(base)),
-                      phase->transform(dispX));
+                      dispX);
 }
 
 Node *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) {
--- a/src/hotspot/share/opto/cfgnode.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/cfgnode.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -119,11 +119,13 @@
 // can turn PhiNodes into copys in-place by NULL'ing out their RegionNode
 // input in slot 0.
 class PhiNode : public TypeNode {
+  friend class PhaseRenumberLive;
+
   const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes.
   // The following fields are only used for data PhiNodes to indicate
   // that the PhiNode represents the value of a known instance field.
         int _inst_mem_id; // Instance memory id (node index of the memory Phi)
-  const int _inst_id;     // Instance id of the memory slice.
+        int _inst_id;     // Instance id of the memory slice.
   const int _inst_index;  // Alias index of the instance memory slice.
   // Array elements references have the same alias_idx but different offset.
   const int _inst_offset; // Offset of the instance memory slice.
--- a/src/hotspot/share/opto/compile.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/compile.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -648,6 +648,7 @@
                   _orig_pc_slot_offset_in_bytes(0),
                   _inlining_progress(false),
                   _inlining_incrementally(false),
+                  _do_cleanup(false),
                   _has_reserved_stack_access(target->has_reserved_stack_access()),
 #ifndef PRODUCT
                   _trace_opto_output(directive->TraceOptoOutputOption),
@@ -2051,52 +2052,49 @@
     }
     _boxing_late_inlines.trunc_to(0);
 
-    {
-      ResourceMark rm;
-      PhaseRemoveUseless pru(gvn, for_igvn());
-    }
-
-    igvn = PhaseIterGVN(gvn);
-    igvn.optimize();
-
-    set_inlining_progress(false);
+    inline_incrementally_cleanup(igvn);
+
     set_inlining_incrementally(false);
   }
 }
 
-void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
+bool Compile::inline_incrementally_one() {
   assert(IncrementalInline, "incremental inlining should be on");
-  PhaseGVN* gvn = initial_gvn();
-
+
+  TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
   set_inlining_progress(false);
-  for_igvn()->clear();
-  gvn->replace_with(&igvn);
-
-  {
-    TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
-    int i = 0;
-    for (; i <_late_inlines.length() && !inlining_progress(); i++) {
-      CallGenerator* cg = _late_inlines.at(i);
-      _late_inlines_pos = i+1;
-      cg->do_late_inline();
-      if (failing())  return;
-    }
-    int j = 0;
-    for (; i < _late_inlines.length(); i++, j++) {
-      _late_inlines.at_put(j, _late_inlines.at(i));
-    }
-    _late_inlines.trunc_to(j);
+  set_do_cleanup(false);
+  int i = 0;
+  for (; i <_late_inlines.length() && !inlining_progress(); i++) {
+    CallGenerator* cg = _late_inlines.at(i);
+    _late_inlines_pos = i+1;
+    cg->do_late_inline();
+    if (failing())  return false;
   }
-
+  int j = 0;
+  for (; i < _late_inlines.length(); i++, j++) {
+    _late_inlines.at_put(j, _late_inlines.at(i));
+  }
+  _late_inlines.trunc_to(j);
+  assert(inlining_progress() || _late_inlines.length() == 0, "");
+
+  bool needs_cleanup = do_cleanup() || over_inlining_cutoff();
+
+  set_inlining_progress(false);
+  set_do_cleanup(false);
+  return (_late_inlines.length() > 0) && !needs_cleanup;
+}
+
+void Compile::inline_incrementally_cleanup(PhaseIterGVN& igvn) {
   {
     TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
     ResourceMark rm;
-    PhaseRemoveUseless pru(gvn, for_igvn());
+    PhaseRemoveUseless pru(initial_gvn(), for_igvn());
   }
-
   {
     TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
-    igvn = PhaseIterGVN(gvn);
+    igvn = PhaseIterGVN(initial_gvn());
+    igvn.optimize();
   }
 }
 
@@ -2104,14 +2102,10 @@
 void Compile::inline_incrementally(PhaseIterGVN& igvn) {
   TracePhase tp("incrementalInline", &timers[_t_incrInline]);
 
-  PhaseGVN* gvn = initial_gvn();
-
   set_inlining_incrementally(true);
-  set_inlining_progress(true);
   uint low_live_nodes = 0;
 
-  while(inlining_progress() && _late_inlines.length() > 0) {
-
+  while (_late_inlines.length() > 0) {
     if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
       if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
         TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]);
@@ -2125,22 +2119,23 @@
       }
 
       if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
-        break;
+        break; // finish
       }
     }
 
-    inline_incrementally_one(igvn);
+    for_igvn()->clear();
+    initial_gvn()->replace_with(&igvn);
+
+    while (inline_incrementally_one()) {
+      assert(!failing(), "inconsistent");
+    }
 
     if (failing())  return;
 
-    {
-      TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
-      igvn.optimize();
-    }
+    inline_incrementally_cleanup(igvn);
 
     if (failing())  return;
   }
-
   assert( igvn._worklist.size() == 0, "should be done with igvn" );
 
   if (_string_late_inlines.length() > 0) {
@@ -2152,17 +2147,7 @@
 
     if (failing())  return;
 
-    {
-      TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
-      ResourceMark rm;
-      PhaseRemoveUseless pru(initial_gvn(), for_igvn());
-    }
-
-    {
-      TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
-      igvn = PhaseIterGVN(gvn);
-      igvn.optimize();
-    }
+    inline_incrementally_cleanup(igvn);
   }
 
   set_inlining_incrementally(false);
--- a/src/hotspot/share/opto/compile.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/compile.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -383,6 +383,7 @@
   int                   _major_progress;        // Count of something big happening
   bool                  _inlining_progress;     // progress doing incremental inlining?
   bool                  _inlining_incrementally;// Are we doing incremental inlining (post parse)
+  bool                  _do_cleanup;            // Cleanup is needed before proceeding with incremental inlining
   bool                  _has_loops;             // True if the method _may_ have some loops
   bool                  _has_split_ifs;         // True if the method _may_ have some split-if
   bool                  _has_unsafe_access;     // True if the method _may_ produce faults in unsafe loads or stores.
@@ -653,6 +654,8 @@
   int               inlining_progress() const   { return _inlining_progress; }
   void          set_inlining_incrementally(bool z) { _inlining_incrementally = z; }
   int               inlining_incrementally() const { return _inlining_incrementally; }
+  void          set_do_cleanup(bool z)          { _do_cleanup = z; }
+  int               do_cleanup() const          { return _do_cleanup; }
   void          set_major_progress()            { _major_progress++; }
   void        clear_major_progress()            { _major_progress = 0; }
   int               max_inline_size() const     { return _max_inline_size; }
@@ -1022,6 +1025,11 @@
                       ciMethodData* logmd = NULL);
   // Report if there were too many recompiles at a method and bci.
   bool too_many_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason);
+  // Report if there were too many traps or recompiles at a method and bci.
+  bool too_many_traps_or_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason) {
+    return too_many_traps(method, bci, reason) ||
+           too_many_recompiles(method, bci, reason);
+  }
   // Return a bitset with the reasons where deoptimization is allowed,
   // i.e., where there were not too many uncommon traps.
   int _allowed_reasons;
@@ -1075,7 +1083,11 @@
     if (!inlining_incrementally()) {
       return unique() > (uint)NodeCountInliningCutoff;
     } else {
-      return live_nodes() > (uint)LiveNodeCountInliningCutoff;
+      // Give some room for incremental inlining algorithm to "breathe"
+      // and avoid thrashing when live node count is close to the limit.
+      // Keep in mind that live_nodes() isn't accurate during inlining until
+      // dead node elimination step happens (see Compile::inline_incrementally).
+      return live_nodes() > (uint)LiveNodeCountInliningCutoff * 11 / 10;
     }
   }
 
@@ -1083,7 +1095,8 @@
   void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; }
   bool has_mh_late_inlines() const     { return _number_of_mh_late_inlines > 0; }
 
-  void inline_incrementally_one(PhaseIterGVN& igvn);
+  bool inline_incrementally_one();
+  void inline_incrementally_cleanup(PhaseIterGVN& igvn);
   void inline_incrementally(PhaseIterGVN& igvn);
   void inline_string_calls(bool parse_time);
   void inline_boxing_calls(PhaseIterGVN& igvn);
--- a/src/hotspot/share/opto/doCall.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/doCall.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -209,7 +209,7 @@
 
       int morphism = profile.morphism();
       if (speculative_receiver_type != NULL) {
-        if (!too_many_traps(caller, bci, Deoptimization::Reason_speculate_class_check)) {
+        if (!too_many_traps_or_recompiles(caller, bci, Deoptimization::Reason_speculate_class_check)) {
           // We have a speculative type, we should be able to resolve
           // the call. We do that before looking at the profiling at
           // this invoke because it may lead to bimorphic inlining which
@@ -262,7 +262,7 @@
                                                ? Deoptimization::Reason_bimorphic
                                                : Deoptimization::reason_class_check(speculative_receiver_type != NULL));
           if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) &&
-              !too_many_traps(caller, bci, reason)
+              !too_many_traps_or_recompiles(caller, bci, reason)
              ) {
             // Generate uncommon trap for class check failure path
             // in case of monomorphic or bimorphic virtual call site.
@@ -292,6 +292,51 @@
         }
       }
     }
+
+    // If there is only one implementor of this interface then we
+    // may be able to bind this invoke directly to the implementing
+    // klass but we need both a dependence on the single interface
+    // and on the method we bind to. Additionally since all we know
+    // about the receiver type is that it's supposed to implement the
+    // interface we have to insert a check that it's the class we
+    // expect.  Interface types are not checked by the verifier so
+    // they are roughly equivalent to Object.
+    // The number of implementors for declared_interface is less or
+    // equal to the number of implementors for target->holder() so
+    // if number of implementors of target->holder() == 1 then
+    // number of implementors for decl_interface is 0 or 1. If
+    // it's 0 then no class implements decl_interface and there's
+    // no point in inlining.
+    if (call_does_dispatch && bytecode == Bytecodes::_invokeinterface) {
+      ciInstanceKlass* declared_interface =
+          caller->get_declared_method_holder_at_bci(bci)->as_instance_klass();
+
+      if (declared_interface->nof_implementors() == 1 &&
+          (!callee->is_default_method() || callee->is_overpass()) /* CHA doesn't support default methods yet */) {
+        ciInstanceKlass* singleton = declared_interface->implementor();
+        ciMethod* cha_monomorphic_target =
+            callee->find_monomorphic_target(caller->holder(), declared_interface, singleton);
+
+        if (cha_monomorphic_target != NULL &&
+            cha_monomorphic_target->holder() != env()->Object_klass()) { // subtype check against Object is useless
+          ciKlass* holder = cha_monomorphic_target->holder();
+
+          // Try to inline the method found by CHA. Inlined method is guarded by the type check.
+          CallGenerator* hit_cg = call_generator(cha_monomorphic_target,
+              vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor);
+
+          // Deoptimize on type check fail. The interpreter will throw ICCE for us.
+          CallGenerator* miss_cg = CallGenerator::for_uncommon_trap(callee,
+              Deoptimization::Reason_class_check, Deoptimization::Action_none);
+
+          CallGenerator* cg = CallGenerator::for_guarded_call(holder, miss_cg, hit_cg);
+          if (hit_cg != NULL && cg != NULL) {
+            dependencies()->assert_unique_concrete_method(declared_interface, cha_monomorphic_target);
+            return cg;
+          }
+        }
+      }
+    }
   }
 
   // Nothing claimed the intrinsic, we go with straight-forward inlining
--- a/src/hotspot/share/opto/graphKit.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/graphKit.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -2794,6 +2794,22 @@
   return fail;
 }
 
+//------------------------------subtype_check_receiver-------------------------
+Node* GraphKit::subtype_check_receiver(Node* receiver, ciKlass* klass,
+                                       Node** casted_receiver) {
+  const TypeKlassPtr* tklass = TypeKlassPtr::make(klass);
+  Node* recv_klass = load_object_klass(receiver);
+  Node* want_klass = makecon(tklass);
+
+  Node* slow_ctl = gen_subtype_check(recv_klass, want_klass);
+
+  // Cast receiver after successful check
+  const TypeOopPtr* recv_type = tklass->cast_to_exactness(false)->is_klassptr()->as_instance_type();
+  Node* cast = new CheckCastPPNode(control(), receiver, recv_type);
+  (*casted_receiver) = _gvn.transform(cast);
+
+  return slow_ctl;
+}
 
 //------------------------------seems_never_null-------------------------------
 // Use null_seen information if it is available from the profile.
@@ -2836,7 +2852,7 @@
   Deoptimization::DeoptReason reason = Deoptimization::reason_class_check(spec_klass != NULL);
 
   // Make sure we haven't already deoptimized from this tactic.
-  if (too_many_traps(reason) || too_many_recompiles(reason))
+  if (too_many_traps_or_recompiles(reason))
     return NULL;
 
   // (No, this isn't a call, but it's enough like a virtual call
@@ -2891,9 +2907,8 @@
     Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check;
     Deoptimization::DeoptReason null_reason = Deoptimization::Reason_speculate_null_check;
 
-    if (!too_many_traps(null_reason) && !too_many_recompiles(null_reason) &&
-        !too_many_traps(class_reason) &&
-        !too_many_recompiles(class_reason)) {
+    if (!too_many_traps_or_recompiles(null_reason) &&
+        !too_many_traps_or_recompiles(class_reason)) {
       Node* not_null_obj = NULL;
       // not_null is true if we know the object is not null and
       // there's no need for a null check
@@ -2918,8 +2933,7 @@
       obj = exact_obj;
     }
   } else {
-    if (!too_many_traps(Deoptimization::Reason_null_assert) &&
-        !too_many_recompiles(Deoptimization::Reason_null_assert)) {
+    if (!too_many_traps_or_recompiles(Deoptimization::Reason_null_assert)) {
       Node* exact_obj = null_assert(obj);
       replace_in_map(obj, exact_obj);
       obj = exact_obj;
--- a/src/hotspot/share/opto/graphKit.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/graphKit.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -751,6 +751,10 @@
     return C->too_many_recompiles(method(), bci(), reason);
   }
 
+  bool too_many_traps_or_recompiles(Deoptimization::DeoptReason reason) {
+      return C->too_many_traps_or_recompiles(method(), bci(), reason);
+  }
+
   // Returns the object (if any) which was created the moment before.
   Node* just_allocated_object(Node* current_control);
 
@@ -830,6 +834,10 @@
   Node* type_check_receiver(Node* receiver, ciKlass* klass, float prob,
                             Node* *casted_receiver);
 
+  // Inexact type check used for predicted calls.
+  Node* subtype_check_receiver(Node* receiver, ciKlass* klass,
+                               Node** casted_receiver);
+
   // implementation of object creation
   Node* set_output_for_allocation(AllocateNode* alloc,
                                   const TypeOopPtr* oop_type,
--- a/src/hotspot/share/opto/phaseX.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/phaseX.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -461,55 +461,115 @@
 PhaseRenumberLive::PhaseRenumberLive(PhaseGVN* gvn,
                                      Unique_Node_List* worklist, Unique_Node_List* new_worklist,
                                      PhaseNumber phase_num) :
-  PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live) {
-
+  PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live),
+  _new_type_array(C->comp_arena()),
+  _old2new_map(C->unique(), C->unique(), -1),
+  _delayed(Thread::current()->resource_area()),
+  _is_pass_finished(false),
+  _live_node_count(C->live_nodes())
+{
   assert(RenumberLiveNodes, "RenumberLiveNodes must be set to true for node renumbering to take place");
   assert(C->live_nodes() == _useful.size(), "the number of live nodes must match the number of useful nodes");
   assert(gvn->nodes_size() == 0, "GVN must not contain any nodes at this point");
+  assert(_delayed.size() == 0, "should be empty");
 
-  uint old_unique_count = C->unique();
-  uint live_node_count = C->live_nodes();
   uint worklist_size = worklist->size();
 
-  // Storage for the updated type information.
-  Type_Array new_type_array(C->comp_arena());
-
   // Iterate over the set of live nodes.
-  uint current_idx = 0; // The current new node ID. Incremented after every assignment.
-  for (uint i = 0; i < _useful.size(); i++) {
-    Node* n = _useful.at(i);
-    // Sanity check that fails if we ever decide to execute this phase after EA
-    assert(!n->is_Phi() || n->as_Phi()->inst_mem_id() == -1, "should not be linked to data Phi");
-    const Type* type = gvn->type_or_null(n);
-    new_type_array.map(current_idx, type);
+  for (uint current_idx = 0; current_idx < _useful.size(); current_idx++) {
+    Node* n = _useful.at(current_idx);
 
     bool in_worklist = false;
     if (worklist->member(n)) {
       in_worklist = true;
     }
 
+    const Type* type = gvn->type_or_null(n);
+    _new_type_array.map(current_idx, type);
+
+    assert(_old2new_map.at(n->_idx) == -1, "already seen");
+    _old2new_map.at_put(n->_idx, current_idx);
+
     n->set_idx(current_idx); // Update node ID.
 
     if (in_worklist) {
       new_worklist->push(n);
     }
 
-    current_idx++;
+    if (update_embedded_ids(n) < 0) {
+      _delayed.push(n); // has embedded IDs; handle later
+    }
   }
 
   assert(worklist_size == new_worklist->size(), "the new worklist must have the same size as the original worklist");
-  assert(live_node_count == current_idx, "all live nodes must be processed");
+  assert(_live_node_count == _useful.size(), "all live nodes must be processed");
+
+  _is_pass_finished = true; // pass finished; safe to process delayed updates
+
+  while (_delayed.size() > 0) {
+    Node* n = _delayed.pop();
+    int no_of_updates = update_embedded_ids(n);
+    assert(no_of_updates > 0, "should be updated");
+  }
 
   // Replace the compiler's type information with the updated type information.
-  gvn->replace_types(new_type_array);
+  gvn->replace_types(_new_type_array);
 
   // Update the unique node count of the compilation to the number of currently live nodes.
-  C->set_unique(live_node_count);
+  C->set_unique(_live_node_count);
 
   // Set the dead node count to 0 and reset dead node list.
   C->reset_dead_node_list();
 }
 
+int PhaseRenumberLive::new_index(int old_idx) {
+  assert(_is_pass_finished, "not finished");
+  if (_old2new_map.at(old_idx) == -1) { // absent
+    // Allocate a placeholder to preserve uniqueness
+    _old2new_map.at_put(old_idx, _live_node_count);
+    _live_node_count++;
+  }
+  return _old2new_map.at(old_idx);
+}
+
+int PhaseRenumberLive::update_embedded_ids(Node* n) {
+  int no_of_updates = 0;
+  if (n->is_Phi()) {
+    PhiNode* phi = n->as_Phi();
+    if (phi->_inst_id != -1) {
+      if (!_is_pass_finished) {
+        return -1; // delay
+      }
+      int new_idx = new_index(phi->_inst_id);
+      assert(new_idx != -1, "");
+      phi->_inst_id = new_idx;
+      no_of_updates++;
+    }
+    if (phi->_inst_mem_id != -1) {
+      if (!_is_pass_finished) {
+        return -1; // delay
+      }
+      int new_idx = new_index(phi->_inst_mem_id);
+      assert(new_idx != -1, "");
+      phi->_inst_mem_id = new_idx;
+      no_of_updates++;
+    }
+  }
+
+  const Type* type = _new_type_array.fast_lookup(n->_idx);
+  if (type != NULL && type->isa_oopptr() && type->is_oopptr()->is_known_instance()) {
+    if (!_is_pass_finished) {
+        return -1; // delay
+    }
+    int old_idx = type->is_oopptr()->instance_id();
+    int new_idx = new_index(old_idx);
+    const Type* new_type = type->is_oopptr()->with_instance_id(new_idx);
+    _new_type_array.map(n->_idx, new_type);
+    no_of_updates++;
+  }
+
+  return no_of_updates;
+}
 
 //=============================================================================
 //------------------------------PhaseTransform---------------------------------
--- a/src/hotspot/share/opto/phaseX.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/phaseX.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -157,6 +157,16 @@
 // Phase that first performs a PhaseRemoveUseless, then it renumbers compiler
 // structures accordingly.
 class PhaseRenumberLive : public PhaseRemoveUseless {
+protected:
+  Type_Array _new_type_array; // Storage for the updated type information.
+  GrowableArray<int> _old2new_map;
+  Node_List _delayed;
+  bool _is_pass_finished;
+  uint _live_node_count;
+
+  int update_embedded_ids(Node* n);
+  int new_index(int old_idx);
+
 public:
   PhaseRenumberLive(PhaseGVN* gvn,
                     Unique_Node_List* worklist, Unique_Node_List* new_worklist,
--- a/src/hotspot/share/opto/type.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/type.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -3436,6 +3436,12 @@
   return make(_ptr, _offset, _instance_id, _speculative, depth);
 }
 
+//------------------------------with_instance_id--------------------------------
+const TypePtr* TypeOopPtr::with_instance_id(int instance_id) const {
+  assert(_instance_id != -1, "should be known");
+  return make(_ptr, _offset, instance_id, _speculative, _inline_depth);
+}
+
 //------------------------------meet_instance_id--------------------------------
 int TypeOopPtr::meet_instance_id( int instance_id ) const {
   // Either is 'TOP' instance?  Return the other instance!
@@ -4044,6 +4050,11 @@
   return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth);
 }
 
+const TypePtr *TypeInstPtr::with_instance_id(int instance_id) const {
+  assert(is_known_instance(), "should be known");
+  return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, instance_id, _speculative, _inline_depth);
+}
+
 //=============================================================================
 // Convenience common pre-built types.
 const TypeAryPtr *TypeAryPtr::RANGE;
@@ -4530,6 +4541,11 @@
   return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, _speculative, depth);
 }
 
+const TypePtr *TypeAryPtr::with_instance_id(int instance_id) const {
+  assert(is_known_instance(), "should be known");
+  return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
+}
+
 //=============================================================================
 
 //------------------------------hash-------------------------------------------
--- a/src/hotspot/share/opto/type.hpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/opto/type.hpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1045,6 +1045,8 @@
   virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
   virtual const TypePtr* with_inline_depth(int depth) const;
 
+  virtual const TypePtr* with_instance_id(int instance_id) const;
+
   virtual const Type *xdual() const;    // Compute dual right now.
   // the core of the computation of the meet for TypeOopPtr and for its subclasses
   virtual const Type *xmeet_helper(const Type *t) const;
@@ -1123,6 +1125,7 @@
   // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
   virtual const TypePtr* with_inline_depth(int depth) const;
+  virtual const TypePtr* with_instance_id(int instance_id) const;
 
   // the core of the computation of the meet of 2 types
   virtual const Type *xmeet_helper(const Type *t) const;
@@ -1212,6 +1215,7 @@
   // Speculative type helper methods.
   virtual const Type* remove_speculative() const;
   virtual const TypePtr* with_inline_depth(int depth) const;
+  virtual const TypePtr* with_instance_id(int instance_id) const;
 
   // the core of the computation of the meet of 2 types
   virtual const Type *xmeet_helper(const Type *t) const;
--- a/src/hotspot/share/prims/jni.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jni.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -2591,9 +2591,10 @@
     ret = JNIHandles::make_local(env, a->obj_at(index));
     return ret;
   } else {
-    char buf[jintAsStringSize];
-    sprintf(buf, "%d", index);
-    THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
+    ResourceMark rm(THREAD);
+    stringStream ss;
+    ss.print("Index %d out of bounds for length %d", index, a->length());
+    THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
 JNI_END
 
@@ -2624,9 +2625,10 @@
       THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
     }
   } else {
-    char buf[jintAsStringSize];
-    sprintf(buf, "%d", index);
-    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
+    ResourceMark rm(THREAD);
+    stringStream ss;
+    ss.print("Index %d out of bounds for length %d", index, a->length());
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
 JNI_END
 
@@ -2801,6 +2803,19 @@
                                   , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
                                   HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
 
+static void check_bounds(jsize start, jsize copy_len, jsize array_len, TRAPS) {
+  ResourceMark rm(THREAD);
+  if (copy_len < 0) {
+    stringStream ss;
+    ss.print("Length %d is negative", copy_len);
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
+  } else if (start < 0 || (start > array_len - copy_len)) {
+    stringStream ss;
+    ss.print("Array region %d.." INT64_FORMAT " out of bounds for length %d",
+             start, (int64_t)start+(int64_t)copy_len, array_len);
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
+  }
+}
 
 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
                                     , EntryProbe, ReturnProbe); \
@@ -2814,12 +2829,9 @@
   EntryProbe; \
   DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
   typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
-  if (start < 0 || len < 0 || (start > src->length() - len)) { \
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
-  } else { \
-    if (len > 0) { \
-      ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
-    } \
+  check_bounds(start, len, src->length(), CHECK); \
+  if (len > 0) {    \
+    ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
   } \
 JNI_END
 
@@ -2861,12 +2873,9 @@
   EntryProbe; \
   DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
   typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
-  if (start < 0 || len < 0 || (start > dst->length() - len)) { \
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
-  } else { \
-    if (len > 0) { \
-      ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
-    } \
+  check_bounds(start, len, dst->length(), CHECK); \
+  if (len > 0) { \
+    ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
   } \
 JNI_END
 
--- a/src/hotspot/share/prims/jvm.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jvm.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -870,10 +870,6 @@
   Handle h_prot  (THREAD, protection_domain);
   jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
                                                h_prot, true, thread);
-  if (result != NULL) {
-    oop mirror = JNIHandles::resolve_non_null(result);
-    Klass* to_class = java_lang_Class::as_Klass(mirror);
-  }
 
   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
     // this function is generally only used for class loading during verification.
--- a/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiCodeBlobEvents.hpp"
 #include "prims/jvmtiExport.hpp"
-#include "runtime/handles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/vmThread.hpp"
 
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jfieldIDWorkaround.hpp"
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
 #include "runtime/biasedLocking.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jfieldIDWorkaround.hpp"
 #include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Sat Feb 02 10:00:05 2019 -0800
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Mon Feb 04 11:01:04 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -49,7 +49,7 @@
 #include "prims/jvmtiThreadState.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
@@ -2426,7 +2426,7 @@
   Handle h(thread, object);
 
   EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
-                     ("[%s] montior contended enter event triggered",
+                     ("[%s] monitor contended enter event triggered",
                       JvmtiTrace::safe_get_thread_name(thread)));
 
   JvmtiEnvThreadStateIterator it(state);
@@ -2457,7 +2457,7 @@
   Handle h(thread, object);
 
   EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
-                     ("[%s] montior contended entered event triggered",
+                     ("[%s] monitor contended entered event triggered",
                       JvmtiTrace::safe_get_thread_name(thread)));
 
   JvmtiEnvThreadStateIterator it(state);
@@ -2488,7 +2488,7 @@
   Handle h(thread, object);
 
   EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,
-                     ("[%s] montior wait event triggered",
+                     ("[%s] monitor wait event triggered",
                       JvmtiTrace::safe_get_thread_name(thread)));