changeset 51922:16c6d8d35fd7

Merge
author prr
date Thu, 13 Sep 2018 10:54:11 -0700
parents 372cbac1a862 a3989376ade2
children 16a0f33a5052
files make/jdk/src/classes/build/tools/hasher/Hasher.java make/jdk/src/classes/build/tools/jarreorder/JarReorder.java make/mapfiles/libjsig/mapfile-vers-solaris src/java.desktop/windows/native/common/awt_makecube.cpp test/hotspot/jtreg/vmTestbase/nsk/share/test/timeoutwatchdog/TimeoutHandler.java test/hotspot/jtreg/vmTestbase/nsk/share/test/timeoutwatchdog/TimeoutWatchdog.java test/hotspot/jtreg/vmTestbase/vm/share/gc/TriggerUnloadingByFillingHeap.java test/hotspot/jtreg/vmTestbase/vm/share/vmstresser/CompileAndDeoptimize.java test/hotspot/jtreg/vmTestbase/vm/share/vmstresser/MetaspaceStresser.java test/jdk/com/sun/jdi/JdbArgTest.sh test/jdk/com/sun/jdi/JdbLockTest.sh test/jdk/com/sun/jdi/JdbMissStep.sh test/jdk/com/sun/jdi/JdbVarargsTest.sh test/jdk/com/sun/jdi/MixedSuspendTest.sh test/jdk/com/sun/jdi/NotAField.sh test/jdk/com/sun/jdi/NullLocalVariable.sh test/jdk/com/sun/jdi/Redefine-g.sh test/jdk/com/sun/jdi/RedefineAbstractClass.sh test/jdk/com/sun/jdi/RedefineAddPrivateMethod.sh test/jdk/com/sun/jdi/RedefineAnnotation.sh test/jdk/com/sun/jdi/RedefineChangeClassOrder.sh test/jdk/com/sun/jdi/RedefineClasses.sh test/jdk/com/sun/jdi/RedefineClearBreakpoint.sh test/jdk/com/sun/jdi/RedefineImplementor.sh test/jdk/java/util/zip/ZipFile/deletetempjar.sh test/jdk/javax/naming/module/basic.sh test/jdk/lib/testlibrary/jdk/testlibrary/JDKToolFinder.java test/jdk/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java test/jdk/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java test/jdk/lib/testlibrary/jdk/testlibrary/OutputBuffer.java test/jdk/lib/testlibrary/jdk/testlibrary/ProcessTools.java test/jdk/lib/testlibrary/jdk/testlibrary/StreamPumper.java
diffstat 650 files changed, 8566 insertions(+), 12641 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Thu Sep 13 10:54:11 2018 -0700
@@ -0,0 +1,15 @@
+/build/
+/dist/
+/.idea/
+nbproject/private/
+/webrev
+/.src-rev
+/.jib/
+.DS_Store
+.metadata/
+.recommenders/
+test/nashorn/script/external
+test/nashorn/lib
+NashornProfile.txt
+**/JTreport/**
+**/JTwork/**
--- a/.hgtags	Wed Sep 12 11:51:39 2018 +0530
+++ b/.hgtags	Thu Sep 13 10:54:11 2018 -0700
@@ -510,3 +510,5 @@
 76072a077ee1d815152d45d1692c4b36c53c5c49 jdk-11+28
 492b366f8e5784cc4927c2c98f9b8a3f16c067eb jdk-12+8
 31b159f30fb281016c5f0c103552809aeda84063 jdk-12+9
+8f594f75e0547d4ca16649cb3501659e3155e81b jdk-12+10
+f0f5d23449d31f1b3580c8a73313918cafeaefd7 jdk-12+11
--- a/bin/idea.sh	Wed Sep 12 11:51:39 2018 +0530
+++ b/bin/idea.sh	Thu Sep 13 10:54:11 2018 -0700
@@ -113,21 +113,14 @@
   echo "FATAL: SPEC is empty" >&2; exit 1
 fi
 
-
-addSourceFolder() {
-  root=$@
-  relativePath="`echo "$root" | sed -e s@"$TOP/\(.*$\)"@"\1"@`"
-  folder="`echo "$SOURCE_FOLDER" | sed -e s@"\(.*/\)####\(.*\)"@"\1$relativePath\2"@`"
-  printf "%s\n" "$folder" >> $IDEA_JDK
-}
-
 ### Replace template variables
 
 NUM_REPLACEMENTS=0
 
 replace_template_file() {
     for i in $(seq 1 $NUM_REPLACEMENTS); do
-      eval "sed -i \"s|\${FROM${i}}|\${TO${i}}|g\" $1"
+      eval "sed \"s|\${FROM${i}}|\${TO${i}}|g\" $1 > $1.tmp"
+      mv $1.tmp $1
     done
 }
 
@@ -154,7 +147,7 @@
 SOURCE_POSTFIX="\" isTestSource=\"false\" />"
 
 for root in $MODULE_ROOTS; do
-    SOURCES=$SOURCES"\n$SOURCE_PREFIX""$root""$SOURCE_POSTFIX"
+    SOURCES=$SOURCES" $SOURCE_PREFIX""$root""$SOURCE_POSTFIX"
 done
 
 add_replacement "###SOURCE_ROOTS###" "$SOURCES"
--- a/make/Init.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/Init.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -240,6 +240,11 @@
     override BUILD_LOG_PIPE :=
   endif
 
+  ifeq ($(filter dist-clean, $(SEQUENTIAL_TARGETS)), dist-clean)
+    # We can't have a log file if we're about to remove it.
+    override BUILD_LOG_PIPE :=
+  endif
+
   ifeq ($(OUTPUT_SYNC_SUPPORTED), true)
     OUTPUT_SYNC_FLAG := -O$(OUTPUT_SYNC)
   endif
--- a/make/Main.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/Main.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -1107,7 +1107,8 @@
 # directory was created by configure and now becomes empty, remove it as well.
 dist-clean: clean
 	($(CD) $(OUTPUTDIR) && \
-	    $(RM) -r *spec.gmk $(CONFIGURESUPPORT_OUTPUTDIR) Makefile compare.sh ide)
+	    $(RM) -r *spec.gmk $(CONFIGURESUPPORT_OUTPUTDIR) Makefile compare.sh ide \
+	    configure.log* build.log*)
 	$(if $(filter $(CONF_NAME),$(notdir $(OUTPUTDIR))), \
 	  if test "x`$(LS) $(OUTPUTDIR)`" != x; then \
 	    $(ECHO) "Warning: Not removing non-empty configuration directory for '$(CONF_NAME)'" ; \
--- a/make/SourceRevision.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/SourceRevision.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -31,23 +31,35 @@
 ################################################################################
 # Keep track of what source revision is used to create the build, by creating
 # a tracker file in the output directory. This tracker file is included in the
-# image, and can be used to recreate the source revision used.
+# source image, and can be used to recreate the source revision used.
 #
-# We're either building directly from a mercurial forest, and if so, use the
-# current revision from mercurial. Otherwise, we are building from a source
-# bundle. As a part of creating this source bundle, the current mercurial
-# revisions of all repos will be stored in a file in the top dir, which is then
-# used when creating the tracker file.
+# We're either building directly from an SCM repository, and if so, use the
+# current revision from that SCM. Otherwise, we are building from a source
+# bundle. As a part of creating this source bundle, the current SCM revisions of
+# all repos will be stored in a file in the top dir, which is then used when
+# creating the tracker file.
 
 STORED_SOURCE_REVISION := $(TOPDIR)/.src-rev
 
-# Are we using mercurial?
+USE_SCM := false
 ifneq ($(and $(HG), $(wildcard $(TOPDIR)/.hg)), )
+  USE_SCM := true
+  SCM_DIR := .hg
+  ID_COMMAND := $(PRINTF) "hg:%s" "$$($(HG) id -i)"
+else ifneq ($(and $(GIT), $(wildcard $(TOPDIR)/.git)), )
+  USE_SCM := true
+  SCM_DIR := .git
+  ID_COMMAND := $(PRINTF) "git:%s%s\n" \
+      "$$(git log -n1 --format=%H | cut -c1-12)" \
+      "$$(if test -n "$$(git status --porcelain)"; then printf '+'; fi)"
+endif
+
+ifeq ($(USE_SCM), true)
 
   # Verify that the entire forest is consistent
   $(foreach repo, $(call FindAllReposRel), \
-    $(if $(wildcard $(TOPDIR)/$(repo)/.hg),, \
-        $(error Inconsistent revision control: $(repo) is missing .hg directory)) \
+    $(if $(wildcard $(TOPDIR)/$(repo)/$(SCM_DIR)),, \
+        $(error Inconsistent revision control: $(repo) is missing $(SCM_DIR) directory)) \
   )
 
   # Replace "." with "_top" and "/" with "-"
@@ -56,7 +68,9 @@
 
   ################################################################################
   # SetupGetRevisionForRepo defines a make rule for creating a file containing
-  # the name of the repository and the output of "hg id" for that repository.
+  # the name of the repository and the output of the scm command for that
+  # repository.
+  #
   # Argument 1 is the relative path to the repository from the top dir.
   #
   SetupGetRevisionForRepo = $(NamedParamsMacroTemplate)
@@ -66,7 +80,7 @@
 
     $$(SUPPORT_OUTPUTDIR)/src-rev/$$($1_FILENAME): FRC
 	$$(call MakeDir, $$(@D))
-	$$(ECHO) $$(strip $1):`$$(HG) id -i --repository $$($1_REPO_PATH)` > $$@
+	$$(ECHO) $$(strip $1):`$$(CD) $$($1_REPO_PATH) && $$(ID_COMMAND)` > $$@
 
     REPO_REVISIONS += $$(SUPPORT_OUTPUTDIR)/src-rev/$$($1_FILENAME)
   endef
@@ -92,23 +106,25 @@
 
   $(eval $(call CreateSourceRevisionFile, $(STORED_SOURCE_REVISION)))
 
-  hg-store-source-revision: $(STORED_SOURCE_REVISION)
+  scm-store-source-revision: $(STORED_SOURCE_REVISION)
 
   $(eval $(call CreateSourceRevisionFile, $(SOURCE_REVISION_TRACKER)))
 
-  hg-create-source-revision-tracker: $(SOURCE_REVISION_TRACKER)
+  scm-create-source-revision-tracker: $(SOURCE_REVISION_TRACKER)
 
-  STORE_SOURCE_REVISION_TARGET := hg-store-source-revision
-  CREATE_SOURCE_REVISION_TRACKER_TARGET := hg-create-source-revision-tracker
+  STORE_SOURCE_REVISION_TARGET := scm-store-source-revision
+  CREATE_SOURCE_REVISION_TRACKER_TARGET := scm-create-source-revision-tracker
+
+  .PHONY: scm-store-source-revision scm-create-source-revision-tracker
 
 else
-  # Not using HG
+  # Not using any SCM
 
   ifneq ($(wildcard $(STORED_SOURCE_REVISION)), )
     # We have a stored source revision (.src-rev)
 
     src-store-source-revision:
-	$(call LogInfo, No mercurial configuration present$(COMMA) not updating .src-rev)
+	$(call LogInfo, No SCM configuration present$(COMMA) not updating .src-rev)
 
     $(SOURCE_REVISION_TRACKER): $(STORED_SOURCE_REVISION)
 	$(install-file)
@@ -118,16 +134,18 @@
     # We don't have a stored source revision. Can't do anything, really.
 
     src-store-source-revision:
-	$(call LogWarn, Error: No mercurial configuration present$(COMMA) cannot create .src-rev)
+	$(call LogWarn, Error: No SCM configuration present$(COMMA) cannot create .src-rev)
 	exit 2
 
     src-create-source-revision-tracker:
-	$(call LogWarn, Warning: No mercurial configuration present and no .src-rev)
+	$(call LogWarn, Warning: No SCM configuration present and no .src-rev)
   endif
 
   STORE_SOURCE_REVISION_TARGET := src-store-source-revision
   CREATE_SOURCE_REVISION_TRACKER_TARGET := src-create-source-revision-tracker
 
+  .PHONY: src-store-source-revision src-create-source-revision-tracker
+
 endif
 
 ################################################################################
--- a/make/ToolsJdk.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/ToolsJdk.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -47,9 +47,6 @@
 TOOL_COMPILEPROPERTIES = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.compileproperties.CompileProperties
 
-TOOL_JARREORDER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
-    build.tools.jarreorder.JarReorder
-
 TOOL_GENERATECHARACTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.generatecharacter.GenerateCharacter
 
@@ -67,9 +64,6 @@
 TOOL_GENERATECURRENCYDATA = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.generatecurrencydata.GenerateCurrencyData
 
-TOOL_HASHER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
-    build.tools.hasher.Hasher
-
 TOOL_TZDB = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.tzdb.TzdbZoneRulesCompiler
 
@@ -109,10 +103,6 @@
 TOOL_GENERATELSREQUIVMAPS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
     build.tools.generatelsrequivmaps.EquivMapsGenerator
 
-TOOL_GENMODULESXML = $(JAVA_SMALL) $(INTERIM_LANGTOOLS_BOOTCLASSPATH) \
-    -cp $(call PathList, $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes) \
-    build.tools.module.GenJdepsModulesXml
-
 TOOL_GENMODULEINFOSOURCE = $(JAVA_SMALL) $(INTERIM_LANGTOOLS_BOOTCLASSPATH) \
     -cp $(call PathList, $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes) \
     build.tools.module.GenModuleInfoSource
--- a/make/autoconf/basics.m4	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/autoconf/basics.m4	Thu Sep 13 10:54:11 2018 -0700
@@ -1190,6 +1190,7 @@
   BASIC_PATH_PROGS(READELF, [greadelf readelf])
   BASIC_PATH_PROGS(DOT, dot)
   BASIC_PATH_PROGS(HG, hg)
+  BASIC_PATH_PROGS(GIT, git)
   BASIC_PATH_PROGS(STAT, stat)
   BASIC_PATH_PROGS(TIME, time)
   BASIC_PATH_PROGS(FLOCK, flock)
--- a/make/autoconf/spec.gmk.in	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/autoconf/spec.gmk.in	Thu Sep 13 10:54:11 2018 -0700
@@ -723,6 +723,7 @@
 FILE:=@FILE@
 DOT:=@DOT@
 HG:=@HG@
+GIT:=@GIT@
 OBJCOPY:=@OBJCOPY@
 SETFILE:=@SETFILE@
 XATTR:=@XATTR@
--- a/make/common/MakeBase.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/common/MakeBase.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -347,6 +347,7 @@
 FindAllReposAbs = \
     $(strip $(sort $(dir $(filter-out $(TOPDIR)/build/%, $(wildcard \
         $(addprefix $(TOPDIR)/, .hg */.hg */*/.hg */*/*/.hg */*/*/*/.hg) \
+        $(addprefix $(TOPDIR)/, .git */.git */*/.git */*/*/.git */*/*/*/.git) \
     )))))
 
 # Locate all hg repositories included in the forest, as relative paths
--- a/make/copy/Copy-java.base.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/copy/Copy-java.base.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -183,7 +183,7 @@
 
 TARGETS += $(COPY_NET_PROPERTIES)
 
-ifeq ($(OPENJDK_TARGET_OS), solaris)
+ifneq ($(filter $(OPENJDK_TARGET_OS), solaris linux), )
   $(eval $(call SetupCopyFiles, COPY_SDP_CONF, \
       FILES := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/conf/sdp/sdp.conf.template, \
       DEST := $(CONF_DST_DIR)/sdp, \
--- a/make/jdk/src/classes/build/tools/hasher/Hasher.java	Wed Sep 12 11:51:39 2018 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-/*
- * Copyright (c) 2004, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package build.tools.hasher;
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * Reads a map in the form of a sequence of key/value-expression pairs from the
- * standard input, attempts to construct a hash map that fits within the given
- * table-size and chain-depth constraints, and, if successful, writes source
- * code to the standard output for a subclass of sun.util.PreHashedMap that
- * implements the map.
- *
- * @see sun.util.PreHashedMap
- *
- * @author Mark Reinhold
- */
-
-public class Hasher {
-
-    static final PrintStream out = System.out;
-    static final PrintStream err = System.err;
-
-    boolean verbose = false;
-
-    List<String> keys = new ArrayList<>();      // Key strings
-    List<String> values = new ArrayList<>();    // Value expressions
-    String pkg = null;                          // Package prefix for generated class
-    String cln = null;                          // Name of generated class
-    String vtype = "String";                    // Value type
-    int maxBits = 11;                           // lg table size
-    int maxDepth = 3;                           // Max chain depth
-    boolean inner = false;                      // Generating an inner class?
-    boolean empty = false;                      // Generating an empty table?
-
-    void usage() {
-        err.println("usage: java Hasher [options] [[pkgName.]ClassName]");
-        err.println("options:");
-        err.println("    -e           generate empty table (ignores value exprs)");
-        err.println("    -i           generate a static inner class");
-        err.println("    -md depth    max chain depth (default 3)");
-        err.println("    -mb bits     max index bits (lg of table size, default 10)");
-        err.println("    -t type      value type (default String)");
-        err.println("    -v           verbose");
-        err.println("Key/value-expression pairs are read from standard input");
-        err.println("If class name is given then source is written to standard output");
-        System.exit(1);
-    }
-
-    Hasher(String[] args) {
-        List<String> as = Arrays.asList(args);
-        for (Iterator<String> i = as.iterator(); i.hasNext();) {
-            String a = i.next();
-            if (a.equals("-e")) {
-                empty = true;
-            } else if (a.equals("-i")) {
-                inner = true;
-            } else if (a.equals("-v")) {
-                verbose = true;
-            } else if (a.equals("-md")) {
-                if (!i.hasNext())
-                    usage();
-                maxDepth = Integer.parseInt(i.next());
-            } else if (a.equals("-mb")) {
-                if (!i.hasNext())
-                    usage();
-                maxBits = Integer.parseInt(i.next());
-            } else if (a.equals("-t")) {
-                if (!i.hasNext())
-                    usage();
-                vtype = i.next();
-            } else if (a.startsWith("-")) {
-                usage();
-            } else {
-                int j = a.lastIndexOf('.');
-                if (j >= 0) {
-                    pkg = a.substring(0, j);
-                    cln = a.substring(j + 1);
-                } else {
-                    cln = a;
-                }
-            }
-        }
-        if (verbose)
-            err.println("pkg=" + pkg + ", cln=" + cln);
-    }
-
-    // Read keys and values
-    //
-    Hasher load() throws IOException {
-        BufferedReader br
-            = new BufferedReader(new InputStreamReader(System.in));
-        for (String ln; (ln = br.readLine()) != null;) {
-            String[] ws = ln.split(",?\\s+", 2);
-            String w = ws[0].replaceAll("\"", "");
-            if (keys.contains(w))
-                throw new RuntimeException("Duplicate word in input: " + w);
-            keys.add(w);
-            if (ws.length < 2)
-                throw new RuntimeException("Missing expression for key " + w);
-            values.add(ws[1]);
-        }
-        return this;
-    }
-
-    Object[] ht;                        // Hash table itself
-    int nb;                             // Number of bits (lg table size)
-    int md;                             // Maximum chain depth
-    int mask;                           // Hash-code mask
-    int shift;                          // Hash-code shift size
-
-    int hash(String w) {
-        return (w.hashCode() >> shift) & mask;
-    }
-
-    // Build a hash table of size 2^nb, shifting the hash code by s bits
-    //
-    void build(int nb, int s) {
-
-        this.nb = nb;
-        this.shift = s;
-        int n = 1 << nb;
-        this.mask = n - 1;
-        ht = new Object[n];
-        int nw = keys.size();
-
-        for (int i = 0; i < nw; i++) {
-            String w = keys.get(i);
-            String v = values.get(i);
-            int h = hash(w);
-            if (ht[h] == null)
-                ht[h] = new Object[] { w, v };
-            else
-                ht[h] = new Object[] { w, v, ht[h] };
-        }
-
-        this.md = 0;
-        for (int i = 0; i < n; i++) {
-            int d = 1;
-            for (Object[] a = (Object[])ht[i];
-                 a != null && a.length > 2;
-                 a = (Object[])a[2], d++);
-            this.md = Math.max(md, d);
-        }
-
-    }
-
-    Hasher build() {
-        // Iterate through acceptable table sizes
-        for (int nb = 2; nb < maxBits; nb++) {
-            // Iterate through possible shift sizes
-            for (int s = 0; s < (32 - nb); s++) {
-                build(nb, s);
-                if (verbose)
-                    err.println("nb=" + nb + " s=" + s + " md=" + md);
-                if (md <= maxDepth) {
-                    // Success
-                    out.flush();
-                    if (verbose) {
-                        if (cln != null)
-                            err.print(cln + ": ");
-                        err.println("Table size " + (1 << nb) + " (" + nb + " bits)"
-                                    + ", shift " + shift
-                                    + ", max chain depth " + md);
-                    }
-                    return this;
-                }
-            }
-        }
-        throw new RuntimeException("Cannot find a suitable size"
-                                   + " within given constraints");
-    }
-
-    // Look for the given key in the hash table
-    //
-    String get(String k) {
-        int h = hash(k);
-        Object[] a = (Object[])ht[h];
-        for (;;) {
-            if (a[0].equals(k))
-                return (String)a[1];
-            if (a.length < 3)
-                return null;
-            a = (Object[])a[2];
-        }
-    }
-
-    // Test that all input keys can be found in the table
-    //
-    Hasher test() {
-        if (verbose)
-            err.println();
-        for (int i = 0, n = keys.size(); i < n; i++) {
-            String w = keys.get(i);
-            String v = get(w);
-            if (verbose)
-                err.println(hash(w) + "\t" + w);
-            if (!v.equals(values.get(i)))
-                throw new Error("Incorrect value: " + w + " --> "
-                                + v + ", should be " + values.get(i));
-        }
-        return this;
-    }
-
-    String ind = "";                    // Indent prefix
-
-    // Generate code for a single table entry
-    //
-    void genEntry(Object[] a, int depth, PrintWriter pw) {
-        Object v = empty ? null : a[1];
-        pw.print("new Object[] { \"" + a[0] + "\", " + v);
-        if (a.length < 3) {
-            pw.print(" }");
-            return;
-        }
-        pw.println(",");
-        pw.print(ind + "                     ");
-        for (int i = 0; i < depth; i++)
-            pw.print("    ");
-        genEntry((Object[])a[2], depth + 1, pw);
-        pw.print(" }");
-    }
-
-    // Generate a PreHashedMap subclass from the computed hash table
-    //
-    Hasher generate() throws IOException {
-        if (cln == null)
-            return this;
-        PrintWriter pw
-            = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)));
-
-        if (inner)
-            ind = "    ";
-
-        if (!inner && pkg != null) {
-            pw.println();
-            pw.println("package " + pkg + ";");
-            pw.println();
-        }
-
-        if (inner) {
-            pw.println(ind + "private static final class " + cln);
-        } else {
-            pw.println();
-            pw.println("public final class " + cln);
-        }
-        pw.println(ind + "    extends sun.util.PreHashedMap<" + vtype +">");
-        pw.println(ind + "{");
-
-        pw.println();
-        pw.println(ind + "    private static final int ROWS = "
-                   + ht.length + ";");
-        pw.println(ind + "    private static final int SIZE = "
-                   + keys.size() + ";");
-        pw.println(ind + "    private static final int SHIFT = "
-                   + shift + ";");
-        pw.println(ind + "    private static final int MASK = 0x"
-                   + Integer.toHexString(mask) + ";");
-        pw.println();
-
-        pw.println(ind + "    " + (inner ? "private " : "public ")
-                   + cln + "() {");
-        pw.println(ind + "        super(ROWS, SIZE, SHIFT, MASK);");
-        pw.println(ind + "    }");
-        pw.println();
-
-        pw.println(ind + "    protected void init(Object[] ht) {");
-        for (int i = 0; i < ht.length; i++) {
-            if (ht[i] == null)
-                continue;
-            Object[] a = (Object[])ht[i];
-            pw.print(ind + "        ht[" + i + "] = ");
-            genEntry(a, 0, pw);
-            pw.println(";");
-        }
-        pw.println(ind + "    }");
-        pw.println();
-
-        pw.println(ind + "}");
-        if (inner)
-            pw.println();
-
-        pw.close();
-        return this;
-    }
-
-    public static void main(String[] args) throws IOException {
-        new Hasher(args)
-            .load()
-            .build()
-            .test()
-            .generate();
-    }
-
-}
--- a/make/jdk/src/classes/build/tools/jarreorder/JarReorder.java	Wed Sep 12 11:51:39 2018 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-/*
- * Read an input file which is output from a java -verbose run,
- * combine with an argument list of files and directories, and
- * write a list of items to be included in a jar file.
- */
-package build.tools.jarreorder;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.io.PrintStream;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class JarReorder {
-
-    // To deal with output
-    private PrintStream out;
-
-    private void usage() {
-        String help;
-        help =
-                "Usage:  jar JarReorder [-m] [-o <outputfile>] <order_list> <exclude_list> <file> ...\n"
-                + "   -m            activate module mode, where every direct sub\n"
-                + "                 directory of the current working directory\n"
-                + "                 will be assumed to be a separate source root\n"
-                + "   order_list    is a file containing names of files to load\n"
-                + "                 in order at the end of a jar file unless\n"
-                + "                 excluded in the exclude list.\n"
-                + "   exclude_list  is a file containing names of files/directories\n"
-                + "                 NOT to be included in a jar file.\n"
-                + "\n"
-                + "The order_list or exclude_list may be replaced by a \"-\" if no\n"
-                + "data is to be provided.\n"
-                + "\n"
-                + "   The remaining arguments are files or directories to be included\n"
-                + "   in a jar file, from which will be excluded those entries which\n"
-                + "   appear in the exclude list.\n";
-        System.err.println(help);
-    }
-
-
-    /*
-     * Create the file list to be included in a jar file, such that the
-     * list will appear in a specific order, and allowing certain
-     * files and directories to be excluded.
-     *
-     * Command path arguments are
-     *    - optional -m for module mode.
-     *    - optional -o outputfile
-     *    - name of a file containing a set of files to be included in a jar file.
-     *    - name of a file containing a set of files (or directories) to be
-     *      excluded from the jar file.
-     *    - names of files or directories to be searched for files to include
-     *      in the jar file.
-     */
-    public static void main(String[] args) {
-        JarReorder jr = new JarReorder();
-        jr.run(args);
-    }
-
-    private void run(String args[]) {
-
-        int arglen = args.length;
-        int argpos = 0;
-
-        boolean moduleMode = false;
-
-        if (arglen > 0) {
-            // Check for module mode
-            if (args[argpos].equals("-m")) {
-                moduleMode = true;
-                argpos++;
-                arglen--;
-            }
-            // Look for "-o outputfilename" option
-            if (arglen >= 2 && args[argpos].equals("-o")) {
-                try {
-                    out = new PrintStream(new FileOutputStream(args[argpos+1]));
-                } catch (FileNotFoundException e) {
-                    System.err.println("Error: " + e.getMessage());
-                    e.printStackTrace(System.err);
-                    System.exit(1);
-                }
-                argpos += 2;
-                arglen -= 2;
-            } else {
-                System.err.println("Error: Illegal arg count");
-                System.exit(1);
-            }
-        } else {
-            out = System.out;
-        }
-
-        // Should be 2 or more args left
-        if (arglen <= 2) {
-            usage();
-            System.exit(1);
-        }
-
-        // Read the ordered set of files to be included in rt.jar.
-        // Read the set of files/directories to be excluded from rt.jar.
-        String classListFile = args[argpos];
-        String excludeListFile = args[argpos + 1];
-        argpos += 2;
-        arglen -= 2;
-
-        // If we run module mode, this will contain the list of subdirs to use
-        // as source roots. Otherwise it will just contain the current working
-        // dir.
-        List<File> moduleDirs = findModuleDirs(moduleMode);
-
-        // Create 2 lists and a set of processed files
-        List<String> orderList = readListFromFile(classListFile, true, moduleDirs);
-        List<String> excludeList = readListFromFile(excludeListFile, false, moduleDirs);
-        Set<String> processed = new HashSet<String>();
-
-        // Create set of all files and directories excluded, then expand
-        //   that list completely
-        Set<String> excludeSet = new HashSet<String>(excludeList);
-        Set<String> allFilesExcluded = expand(null, excludeSet, processed);
-
-        // Indicate all these have been processed, orderList too, kept to end.
-        processed.addAll(orderList);
-
-        // The remaining arguments are names of files/directories to be included
-        // in the jar file.
-        Set<String> inputSet = new HashSet<String>();
-        for (int i = 0; i < arglen; ++i) {
-            String name = args[argpos + i];
-            for (File dir : moduleDirs) {
-                String cleanName = cleanPath(new File(dir, name));
-                if ( cleanName != null && cleanName.length() > 0 && !inputSet.contains(cleanName) ) {
-                    inputSet.add(cleanName);
-                }
-            }
-        }
-
-        // Expand file/directory input so we get a complete set (except ordered)
-        //   Should be everything not excluded and not in order list.
-        Set<String> allFilesIncluded = expand(null, inputSet, processed);
-
-        // Create simple sorted list so we can add ordered items at end.
-        List<String> allFiles = new ArrayList<String>(allFilesIncluded);
-        Collections.sort(allFiles);
-
-        // Now add the ordered set to the end of the list.
-        // Add in REVERSE ORDER, so that the first element is closest to
-        // the end (and the index).
-        for (int i = orderList.size() - 1; i >= 0; --i) {
-            String s = orderList.get(i);
-            if (allFilesExcluded.contains(s)) {
-                // Disable this warning until 8005688 is fixed
-                // System.err.println("Included order file " + s
-                //    + " is also excluded, skipping.");
-            } else if (new File(s).exists()) {
-                allFiles.add(s);
-            } else {
-                System.err.println("Included order file " + s
-                    + " missing, skipping.");
-            }
-        }
-
-        // Print final results.
-        for (String str : allFiles) {
-            // If running in module mode, each line must be prepended with a
-            // '-C dir ' which points to the source root where that file is
-            // found.
-            if (moduleMode) {
-                int firstPathSep = str.indexOf(File.separator);
-                String moduleDir;
-                if (firstPathSep < 0) {
-                    moduleDir = ".";
-                } else {
-                    moduleDir = str.substring(0, firstPathSep);
-                }
-                String filePath = str.substring(firstPathSep + 1);
-                out.println("-C " + moduleDir + " " + filePath);
-            } else {
-                out.println(str);
-            }
-        }
-        out.flush();
-        out.close();
-    }
-
-    /*
-     * Read a file containing a list of files and directories into a List.
-     */
-    private List<String> readListFromFile(String fileName,
-            boolean addClassSuffix, List<File> moduleDirs) {
-
-        BufferedReader br = null;
-        List<String> list = new ArrayList<String>();
-        // If you see "-" for the name, just assume nothing was provided.
-        if ("-".equals(fileName)) {
-            return list;
-        }
-        try {
-            br = new BufferedReader(new FileReader(fileName));
-            // Read the input file a path at a time. # in column 1 is a comment.
-            while (true) {
-                String path = br.readLine();
-                if (path == null) {
-                    break;
-                }
-                // Look for comments
-                path = path.trim();
-                if (path.length() == 0
-                        || path.charAt(0) == '#') {
-                    continue;
-                }
-                // Add trailing .class if necessary
-                if (addClassSuffix && !path.endsWith(".class")) {
-                    path = path + ".class";
-                }
-                // Look for file in each module source root
-                boolean pathFound = false;
-                for (File dir : moduleDirs) {
-                    File file = new File(dir, path);
-                    if (file.exists()) {
-                        pathFound = true;
-                        // Normalize the path
-                        String cleanPath = cleanPath(new File(dir, path));
-                        // Add to list
-                        if (cleanPath != null && cleanPath.length() > 0 && !list.contains(cleanPath)) {
-                            list.add(cleanPath);
-                        }
-                    }
-                }
-                if (!pathFound) {
-                    System.err.println("WARNING: Path does not exist as file or directory: " + path);
-                }
-            }
-            br.close();
-        } catch (FileNotFoundException e) {
-            System.err.println("Can't find file \"" + fileName + "\".");
-            System.exit(1);
-        } catch (IOException e) {
-            e.printStackTrace();
-            System.exit(2);
-        }
-        return list;
-    }
-
-    /*
-     * Expands inputSet (files or dirs) into full set of all files that
-     * can be found by recursively descending directories.
-     * @param dir root directory
-     * @param inputSet set of files or dirs to look into
-     * @param processed files or dirs already processed
-     * @return set of files
-     */
-    private Set<String> expand(File dir,
-            Set<String> inputSet,
-            Set<String> processed) {
-        Set<String> includedFiles = new HashSet<String>();
-        if (inputSet.isEmpty()) {
-            return includedFiles;
-        }
-        for (String name : inputSet) {
-            // Depending on start location
-            File f = (dir == null) ? new File(name)
-                    : new File(dir, name);
-            // Normalized path to use
-            String path = cleanPath(f);
-            if (path != null && path.length() > 0
-                    && !processed.contains(path)) {
-                if (f.isFile()) {
-                    // Not in the excludeList, add it to both lists
-                    includedFiles.add(path);
-                    processed.add(path);
-                } else if (f.isDirectory()) {
-                    // Add the directory entries
-                    String[] dirList = f.list();
-                    Set<String> dirInputSet = new HashSet<String>();
-                    for (String x : dirList) {
-                        dirInputSet.add(x);
-                    }
-                    // Process all entries in this directory
-                    Set<String> subList = expand(f, dirInputSet, processed);
-                    includedFiles.addAll(subList);
-                    processed.add(path);
-                }
-            }
-        }
-        return includedFiles;
-    }
-
-    /**
-     * Find all module sub directories to be used as source roots.
-     * @param moduleMode If true, assume sub directories are modules, otherwise
-     *                   just use current working directory.
-     * @return List of all found source roots
-     */
-    private List<File> findModuleDirs(boolean moduleMode) {
-        File cwd = new File(".");
-        List<File> moduleDirs = new ArrayList<File>();
-        if (moduleMode) {
-            for (File f : cwd.listFiles()) {
-                if (f.isDirectory()) {
-                    moduleDirs.add(f);
-                }
-            }
-        } else {
-            moduleDirs.add(cwd);
-        }
-        return moduleDirs;
-    }
-
-    private String cleanPath(File f) {
-        String path = f.getPath();
-        if (f.isFile()) {
-            path = cleanFilePath(path);
-        } else if (f.isDirectory()) {
-            path = cleanDirPath(path);
-        } else {
-            System.err.println("WARNING: Path does not exist as file or directory: " + path);
-            path = null;
-        }
-        return path;
-    }
-
-    private String cleanFilePath(String path) {
-        // Remove leading and trailing whitespace
-        path = path.trim();
-        // Make all / and \ chars one
-        if (File.separatorChar == '/') {
-            path = path.replace('\\', '/');
-        } else {
-            path = path.replace('/', '\\');
-        }
-        // Remove leading ./
-        while (path.startsWith("." + File.separator)) {
-            path = path.substring(2);
-        }
-        return path;
-    }
-
-    private String cleanDirPath(String path) {
-        path = cleanFilePath(path);
-        // Make sure it ends with a file separator
-        if (!path.endsWith(File.separator)) {
-            path = path + File.separator;
-        }
-        // Remove any /./ in the path.
-        if (path.endsWith(File.separator + "." + File.separator)) {
-            path = path.substring(0, path.length() - 2);
-        }
-        return path;
-    }
-
-}
--- a/make/langtools/intellij/template/runConfigurations/javac.xml	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/langtools/intellij/template/runConfigurations/javac.xml	Thu Sep 13 10:54:11 2018 -0700
@@ -16,7 +16,7 @@
     <ConfigurationWrapper RunnerId="Run" />
     <method>
       <option name="Make" enabled="false" />
-      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/make/langtools/intellij/build.xml" target="build-all-classes" />
     </method>
   </configuration>
 </component>
--- a/make/langtools/intellij/template/runConfigurations/javadoc.xml	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/langtools/intellij/template/runConfigurations/javadoc.xml	Thu Sep 13 10:54:11 2018 -0700
@@ -16,7 +16,7 @@
     <ConfigurationWrapper RunnerId="Run" />
     <method>
       <option name="Make" enabled="false" />
-      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/make/langtools/intellij/build.xml" target="build-all-classes" />
     </method>
   </configuration>
 </component>
--- a/make/langtools/intellij/template/runConfigurations/javap.xml	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/langtools/intellij/template/runConfigurations/javap.xml	Thu Sep 13 10:54:11 2018 -0700
@@ -16,7 +16,7 @@
     <ConfigurationWrapper RunnerId="Run" />
     <method>
       <option name="Make" enabled="false" />
-      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/make/langtools/intellij/build.xml" target="build-all-classes" />
     </method>
   </configuration>
 </component>
--- a/make/langtools/intellij/template/runConfigurations/jshell.xml	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/langtools/intellij/template/runConfigurations/jshell.xml	Thu Sep 13 10:54:11 2018 -0700
@@ -14,7 +14,7 @@
     <envs />
     <method>
       <option name="Make" enabled="false" />
-      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/make/langtools/intellij/build.xml" target="build-all-classes" />
     </method>
   </configuration>
 </component>
--- a/make/langtools/intellij/template/runConfigurations/sjavac.xml	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/langtools/intellij/template/runConfigurations/sjavac.xml	Thu Sep 13 10:54:11 2018 -0700
@@ -16,7 +16,7 @@
     <ConfigurationWrapper RunnerId="Run" />
     <method>
       <option name="Make" enabled="false" />
-      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/make/langtools/intellij/build.xml" target="build-all-classes" />
     </method>
   </configuration>
 </component>
--- a/make/lib/CoreLibraries.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/lib/CoreLibraries.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -68,7 +68,7 @@
       CFLAGS_linux_ppc64le := -ffp-contract=off, \
       CFLAGS_linux_s390x := -ffp-contract=off, \
       CFLAGS_linux_aarch64 := -ffp-contract=off, \
-      DISABLED_WARNINGS_gcc := sign-compare misleading-indentation, \
+      DISABLED_WARNINGS_gcc := sign-compare misleading-indentation array-bounds, \
       DISABLED_WARNINGS_microsoft := 4146 4244 4018, \
       ARFLAGS := $(ARFLAGS), \
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \
--- a/make/lib/Lib-java.base.gmk	Wed Sep 12 11:51:39 2018 +0530
+++ b/make/lib/Lib-java.base.gmk	Thu Sep 13 10:54:11 2018 -0700
@@ -128,14 +128,6 @@
 
 ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
   ifeq ($(STATIC_BUILD), false)
-
-    LIBJSIG_MAPFILE := $(wildcard $(TOPDIR)/make/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
-
-    ifeq ($(OPENJDK_TARGET_OS), linux)
-      # FIXME: This is probably not what we want to do, but keep it now for compatibility.
-      LIBJSIG_CFLAGS := $(EXPORT_ALL_SYMBOLS)
-    endif
-
     $(eval $(call SetupJdkLibrary, BUILD_LIBJSIG, \
         NAME := jsig, \
         CFLAGS := $(CFLAGS_JDKLIB) $(LIBJSIG_CFLAGS), \
@@ -144,7 +136,6 @@
         LIBS_linux := $(LIBDL), \
         LIBS_solaris := $(LIBDL), \
         LIBS_aix := $(LIBDL), \
-        MAPFILE := $(LIBJSIG_MAPFILE), \
     ))
 
     TARGETS += $(BUILD_LIBJSIG)
--- a/make/mapfiles/libjsig/mapfile-vers-solaris	Wed Sep 12 11:51:39 2018 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#
-# Copyright (c) 2005, 2018, 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.
-#  
-#
-
-# Define library interface.
-
-SUNWprivate_1.1 {
-        global:
-            JVM_begin_signal_setting;
-            JVM_end_signal_setting;
-            JVM_get_signal_action;
-            sigaction;
-            signal;
-            sigset;
-        local:
-                *;
-};
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Thu Sep 13 10:54:11 2018 -0700
@@ -3378,26 +3378,18 @@
     // Load markOop from object into displaced_header.
     __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
 
-    // Always do locking in runtime.
-    if (EmitSync & 0x01) {
-      __ cmp(oop, zr);
-      return;
-    }
-
     if (UseBiasedLocking && !UseOptoBiasInlining) {
       __ biased_locking_enter(box, oop, disp_hdr, tmp, true, cont);
     }
 
     // Handle existing monitor
-    if ((EmitSync & 0x02) == 0) {
-      // we can use AArch64's bit test and branch here but
-      // markoopDesc does not define a bit index just the bit value
-      // so assert in case the bit pos changes
-#     define __monitor_value_log2 1
-      assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position");
-      __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor);
-#     undef __monitor_value_log2
-    }
+    // we can use AArch64's bit test and branch here but
+    // markoopDesc does not define a bit index just the bit value
+    // so assert in case the bit pos changes
+#   define __monitor_value_log2 1
+    assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position");
+    __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor);
+#   undef __monitor_value_log2
 
     // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
     __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value);
@@ -3455,63 +3447,62 @@
     __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 
     // Handle existing monitor.
-    if ((EmitSync & 0x02) == 0) {
-      __ b(cont);
-
-      __ bind(object_has_monitor);
-      // The object's monitor m is unlocked iff m->owner == NULL,
-      // otherwise m->owner may contain a thread or a stack address.
-      //
-      // Try to CAS m->owner from NULL to current thread.
-      __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
-      __ mov(disp_hdr, zr);
-
-      if (UseLSE) {
-        __ mov(rscratch1, disp_hdr);
-        __ casal(Assembler::xword, rscratch1, rthread, tmp);
-        __ cmp(rscratch1, disp_hdr);
-      } else {
-        Label retry_load, fail;
-        if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
-          __ prfm(Address(tmp), PSTL1STRM);
-        __ bind(retry_load);
-        __ ldaxr(rscratch1, tmp);
-        __ cmp(disp_hdr, rscratch1);
-        __ br(Assembler::NE, fail);
-        // use stlxr to ensure update is immediately visible
-        __ stlxr(rscratch1, rthread, tmp);
-        __ cbnzw(rscratch1, retry_load);
-        __ bind(fail);
+    __ b(cont);
+
+    __ bind(object_has_monitor);
+    // The object's monitor m is unlocked iff m->owner == NULL,
+    // otherwise m->owner may contain a thread or a stack address.
+    //
+    // Try to CAS m->owner from NULL to current thread.
+    __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value));
+    __ mov(disp_hdr, zr);
+
+    if (UseLSE) {
+      __ mov(rscratch1, disp_hdr);
+      __ casal(Assembler::xword, rscratch1, rthread, tmp);
+      __ cmp(rscratch1, disp_hdr);
+    } else {
+      Label retry_load, fail;
+      if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) {
+        __ prfm(Address(tmp), PSTL1STRM);
       }
-
-      // Label next;
-      // __ cmpxchgptr(/*oldv=*/disp_hdr,
-      //               /*newv=*/rthread,
-      //               /*addr=*/tmp,
-      //               /*tmp=*/rscratch1,
-      //               /*succeed*/next,
-      //               /*fail*/NULL);
-      // __ bind(next);
-
-      // store a non-null value into the box.
-      __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes()));
-
-      // PPC port checks the following invariants
-      // #ifdef ASSERT
-      // bne(flag, cont);
-      // We have acquired the monitor, check some invariants.
-      // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes());
-      // Invariant 1: _recursions should be 0.
-      // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size");
-      // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp,
-      //                        "monitor->_recursions should be 0", -1);
-      // Invariant 2: OwnerIsThread shouldn't be 0.
-      // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size");
-      //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp,
-      //                           "monitor->OwnerIsThread shouldn't be 0", -1);
-      // #endif
+      __ bind(retry_load);
+      __ ldaxr(rscratch1, tmp);
+      __ cmp(disp_hdr, rscratch1);
+      __ br(Assembler::NE, fail);
+      // use stlxr to ensure update is immediately visible
+      __ stlxr(rscratch1, rthread, tmp);
+      __ cbnzw(rscratch1, retry_load);
+      __ bind(fail);
     }
 
+    // Label next;
+    // __ cmpxchgptr(/*oldv=*/disp_hdr,
+    //               /*newv=*/rthread,
+    //               /*addr=*/tmp,
+    //               /*tmp=*/rscratch1,
+    //               /*succeed*/next,
+    //               /*fail*/NULL);
+    // __ bind(next);
+
+    // store a non-null value into the box.
+    __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes()));
+
+    // PPC port checks the following invariants
+    // #ifdef ASSERT
+    // bne(flag, cont);
+    // We have acquired the monitor, check some invariants.
+    // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes());
+    // Invariant 1: _recursions should be 0.
+    // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size");
+    // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp,
+    //                        "monitor->_recursions should be 0", -1);
+    // Invariant 2: OwnerIsThread shouldn't be 0.
+    // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size");
+    //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp,
+    //                           "monitor->OwnerIsThread shouldn't be 0", -1);
+    // #endif
+
     __ bind(cont);
     // flag == EQ indicates success
     // flag == NE indicates failure
@@ -3533,12 +3524,6 @@
 
     assert_different_registers(oop, box, tmp, disp_hdr);
 
-    // Always do locking in runtime.
-    if (EmitSync & 0x01) {
-      __ cmp(oop, zr); // Oop can't be 0 here => always false.
-      return;
-    }
-
     if (UseBiasedLocking && !UseOptoBiasInlining) {
       __ biased_locking_exit(oop, tmp, cont);
     }
@@ -3552,10 +3537,8 @@
 
 
     // Handle existing monitor.
-    if ((EmitSync & 0x02) == 0) {
-      __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
-      __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
-    }
+    __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
+    __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor);
 
     // Check if it is still a light weight lock, this is is true if we
     // see the stack address of the basicLock in the markOop of the
@@ -3590,27 +3573,25 @@
     __ bind(cas_failed);
 
     // Handle existing monitor.
-    if ((EmitSync & 0x02) == 0) {
-      __ b(cont);
-
-      __ bind(object_has_monitor);
-      __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor
-      __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
-      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
-      __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
-      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
-      __ cmp(rscratch1, zr);
-      __ br(Assembler::NE, cont);
-
-      __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
-      __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
-      __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
-      __ cmp(rscratch1, zr);
-      __ cbnz(rscratch1, cont);
-      // need a release store here
-      __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
-      __ stlr(rscratch1, tmp); // rscratch1 is zero
-    }
+    __ b(cont);
+
+    __ bind(object_has_monitor);
+    __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor
+    __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
+    __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
+    __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner.
+    __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions
+    __ cmp(rscratch1, zr);
+    __ br(Assembler::NE, cont);
+
+    __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes()));
+    __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes()));
+    __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0.
+    __ cmp(rscratch1, zr);
+    __ cbnz(rscratch1, cont);
+    // need a release store here
+    __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
+    __ stlr(rscratch1, tmp); // rscratch1 is zero
 
     __ bind(cont);
     // flag == EQ indicates success
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -2356,7 +2356,7 @@
 
   // FMLA/FMLS - Vector - Scalar
   INSN(fmlavs, 0, 0b0001);
-  INSN(fmlsvs, 0, 0b0001);
+  INSN(fmlsvs, 0, 0b0101);
   // FMULX - Vector - Scalar
   INSN(fmulxvs, 1, 0b1001);
 
--- a/src/hotspot/cpu/ppc/assembler_ppc.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -521,6 +521,18 @@
     XXLOR_OPCODE   = (60u << OPCODE_SHIFT |  146u << 3),
     XXLXOR_OPCODE  = (60u << OPCODE_SHIFT |  154u << 3),
     XXLEQV_OPCODE  = (60u << OPCODE_SHIFT |  186u << 3),
+    XVDIVSP_OPCODE = (60u << OPCODE_SHIFT |   88u << 3),
+    XVDIVDP_OPCODE = (60u << OPCODE_SHIFT |  120u << 3),
+    XVABSSP_OPCODE = (60u << OPCODE_SHIFT |  409u << 2),
+    XVABSDP_OPCODE = (60u << OPCODE_SHIFT |  473u << 2),
+    XVNEGSP_OPCODE = (60u << OPCODE_SHIFT |  441u << 2),
+    XVNEGDP_OPCODE = (60u << OPCODE_SHIFT |  505u << 2),
+    XVSQRTSP_OPCODE= (60u << OPCODE_SHIFT |  139u << 2),
+    XVSQRTDP_OPCODE= (60u << OPCODE_SHIFT |  203u << 2),
+    XVADDDP_OPCODE = (60u << OPCODE_SHIFT |   96u << 3),
+    XVSUBDP_OPCODE = (60u << OPCODE_SHIFT |  104u << 3),
+    XVMULSP_OPCODE = (60u << OPCODE_SHIFT |   80u << 3),
+    XVMULDP_OPCODE = (60u << OPCODE_SHIFT |  112u << 3),
 
     // Vector Permute and Formatting
     VPKPX_OPCODE   = (4u  << OPCODE_SHIFT |  782u     ),
@@ -574,6 +586,7 @@
     VADDUBS_OPCODE = (4u  << OPCODE_SHIFT |  512u     ),
     VADDUWS_OPCODE = (4u  << OPCODE_SHIFT |  640u     ),
     VADDUHS_OPCODE = (4u  << OPCODE_SHIFT |  576u     ),
+    VADDFP_OPCODE  = (4u  << OPCODE_SHIFT |   10u     ),
     VSUBCUW_OPCODE = (4u  << OPCODE_SHIFT | 1408u     ),
     VSUBSHS_OPCODE = (4u  << OPCODE_SHIFT | 1856u     ),
     VSUBSBS_OPCODE = (4u  << OPCODE_SHIFT | 1792u     ),
@@ -581,9 +594,11 @@
     VSUBUBM_OPCODE = (4u  << OPCODE_SHIFT | 1024u     ),
     VSUBUWM_OPCODE = (4u  << OPCODE_SHIFT | 1152u     ),
     VSUBUHM_OPCODE = (4u  << OPCODE_SHIFT | 1088u     ),
+    VSUBUDM_OPCODE = (4u  << OPCODE_SHIFT | 1216u     ),
     VSUBUBS_OPCODE = (4u  << OPCODE_SHIFT | 1536u     ),
     VSUBUWS_OPCODE = (4u  << OPCODE_SHIFT | 1664u     ),
     VSUBUHS_OPCODE = (4u  << OPCODE_SHIFT | 1600u     ),
+    VSUBFP_OPCODE  = (4u  << OPCODE_SHIFT |   74u     ),
 
     VMULESB_OPCODE = (4u  << OPCODE_SHIFT |  776u     ),
     VMULEUB_OPCODE = (4u  << OPCODE_SHIFT |  520u     ),
@@ -592,7 +607,9 @@
     VMULOSB_OPCODE = (4u  << OPCODE_SHIFT |  264u     ),
     VMULOUB_OPCODE = (4u  << OPCODE_SHIFT |    8u     ),
     VMULOSH_OPCODE = (4u  << OPCODE_SHIFT |  328u     ),
+    VMULOSW_OPCODE = (4u  << OPCODE_SHIFT |  392u     ),
     VMULOUH_OPCODE = (4u  << OPCODE_SHIFT |   72u     ),
+    VMULUWM_OPCODE = (4u  << OPCODE_SHIFT |  137u     ),
     VMHADDSHS_OPCODE=(4u  << OPCODE_SHIFT |   32u     ),
     VMHRADDSHS_OPCODE=(4u << OPCODE_SHIFT |   33u     ),
     VMLADDUHM_OPCODE=(4u  << OPCODE_SHIFT |   34u     ),
@@ -602,6 +619,7 @@
     VMSUMSHS_OPCODE= (4u  << OPCODE_SHIFT |   41u     ),
     VMSUMUHM_OPCODE= (4u  << OPCODE_SHIFT |   38u     ),
     VMSUMUHS_OPCODE= (4u  << OPCODE_SHIFT |   39u     ),
+    VMADDFP_OPCODE = (4u  << OPCODE_SHIFT |   46u     ),
 
     VSUMSWS_OPCODE = (4u  << OPCODE_SHIFT | 1928u     ),
     VSUM2SWS_OPCODE= (4u  << OPCODE_SHIFT | 1672u     ),
@@ -657,6 +675,7 @@
     VSRAB_OPCODE   = (4u  << OPCODE_SHIFT |  772u     ),
     VSRAW_OPCODE   = (4u  << OPCODE_SHIFT |  900u     ),
     VSRAH_OPCODE   = (4u  << OPCODE_SHIFT |  836u     ),
+    VPOPCNTW_OPCODE= (4u  << OPCODE_SHIFT | 1923u     ),
 
     // Vector Floating-Point
     // not implemented yet
@@ -2059,6 +2078,7 @@
   inline void vaddubs(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vadduws(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vadduhs(  VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vaddfp(   VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubcuw(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubshs(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubsbs(  VectorRegister d, VectorRegister a, VectorRegister b);
@@ -2066,9 +2086,11 @@
   inline void vsububm(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubuwm(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubuhm(  VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vsubudm(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsububs(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubuws(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsubuhs(  VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vsubfp(   VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmulesb(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmuleub(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmulesh(  VectorRegister d, VectorRegister a, VectorRegister b);
@@ -2076,7 +2098,9 @@
   inline void vmulosb(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmuloub(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmulosh(  VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vmulosw(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmulouh(  VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vmuluwm(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vmhaddshs(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
   inline void vmhraddshs(VectorRegister d,VectorRegister a, VectorRegister b, VectorRegister c);
   inline void vmladduhm(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
@@ -2086,6 +2110,7 @@
   inline void vmsumshs( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
   inline void vmsumuhm( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
   inline void vmsumuhs( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
+  inline void vmaddfp(  VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c);
   inline void vsumsws(  VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsum2sws( VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsum4sbs( VectorRegister d, VectorRegister a, VectorRegister b);
@@ -2146,6 +2171,7 @@
   inline void vsrab(    VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsraw(    VectorRegister d, VectorRegister a, VectorRegister b);
   inline void vsrah(    VectorRegister d, VectorRegister a, VectorRegister b);
+  inline void vpopcntw( VectorRegister d, VectorRegister b);
   // Vector Floating-Point not implemented yet
   inline void mtvscr(   VectorRegister b);
   inline void mfvscr(   VectorRegister d);
@@ -2168,6 +2194,18 @@
   inline void xxlor(    VectorSRegister d, VectorSRegister a, VectorSRegister b);
   inline void xxlxor(   VectorSRegister d, VectorSRegister a, VectorSRegister b);
   inline void xxleqv(   VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvdivsp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvdivdp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvabssp(  VectorSRegister d, VectorSRegister b);
+  inline void xvabsdp(  VectorSRegister d, VectorSRegister b);
+  inline void xvnegsp(  VectorSRegister d, VectorSRegister b);
+  inline void xvnegdp(  VectorSRegister d, VectorSRegister b);
+  inline void xvsqrtsp( VectorSRegister d, VectorSRegister b);
+  inline void xvsqrtdp( VectorSRegister d, VectorSRegister b);
+  inline void xvadddp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvsubdp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvmulsp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
+  inline void xvmuldp(  VectorSRegister d, VectorSRegister a, VectorSRegister b);
 
   // VSX Extended Mnemonics
   inline void xxspltd(  VectorSRegister d, VectorSRegister a, int x);
--- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -769,7 +769,19 @@
 inline void Assembler::xxlor(   VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLOR_OPCODE  | vsrt(d) | vsra(a) | vsrb(b)); }
 inline void Assembler::xxlxor(  VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLXOR_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
 inline void Assembler::xxleqv(  VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLEQV_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
-inline void Assembler::mtvrd(    VectorRegister d, Register a)               { emit_int32( MTVSRD_OPCODE  | vsrt(d->to_vsr()) | ra(a)); }
+inline void Assembler::xvdivsp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVDIVSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::xvdivdp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVDIVDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::xvabssp( VectorSRegister d, VectorSRegister b)                    { emit_int32( XVABSSP_OPCODE | vsrt(d) | vsrb(b)); }
+inline void Assembler::xvabsdp( VectorSRegister d, VectorSRegister b)                    { emit_int32( XVABSDP_OPCODE | vsrt(d) | vsrb(b)); }
+inline void Assembler::xvnegsp( VectorSRegister d, VectorSRegister b)                    { emit_int32( XVNEGSP_OPCODE | vsrt(d) | vsrb(b)); }
+inline void Assembler::xvnegdp( VectorSRegister d, VectorSRegister b)                    { emit_int32( XVNEGDP_OPCODE | vsrt(d) | vsrb(b)); }
+inline void Assembler::xvsqrtsp(VectorSRegister d, VectorSRegister b)                    { emit_int32( XVSQRTSP_OPCODE| vsrt(d) | vsrb(b)); }
+inline void Assembler::xvsqrtdp(VectorSRegister d, VectorSRegister b)                    { emit_int32( XVSQRTDP_OPCODE| vsrt(d) | vsrb(b)); }
+inline void Assembler::xvadddp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVADDDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::xvsubdp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVSUBDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::xvmulsp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMULSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::xvmuldp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVMULDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); }
+inline void Assembler::mtvrd(   VectorRegister d, Register a)               { emit_int32( MTVSRD_OPCODE  | vsrt(d->to_vsr()) | ra(a)); }
 inline void Assembler::mfvrd(   Register        a, VectorRegister d)         { emit_int32( MFVSRD_OPCODE  | vsrt(d->to_vsr()) | ra(a)); }
 inline void Assembler::mtvrwz(  VectorRegister  d, Register a)               { emit_int32( MTVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
 inline void Assembler::mfvrwz(  Register        a, VectorRegister d)         { emit_int32( MFVSRWZ_OPCODE | vsrt(d->to_vsr()) | ra(a)); }
@@ -833,6 +845,7 @@
 inline void Assembler::vaddubs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUBS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vadduws( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUWS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vadduhs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDUHS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vaddfp(  VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VADDFP_OPCODE  | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubcuw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBCUW_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubshs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBSHS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubsbs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBSBS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@@ -840,9 +853,11 @@
 inline void Assembler::vsububm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUBM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubuwm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUWM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubuhm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUHM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vsubudm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUDM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsububs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUBS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubuws( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUWS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsubuhs( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBUHS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vsubfp(  VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUBFP_OPCODE  | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmulesb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULESB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmuleub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULEUB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmulesh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULESH_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@@ -850,7 +865,9 @@
 inline void Assembler::vmulosb( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULOSB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmuloub( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULOUB_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmulosh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULOSH_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vmulosw( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULOSW_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmulouh( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULOUH_OPCODE | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vmuluwm( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VMULUWM_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vmhaddshs(VectorRegister d,VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMHADDSHS_OPCODE | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
 inline void Assembler::vmhraddshs(VectorRegister d,VectorRegister a,VectorRegister b, VectorRegister c) { emit_int32( VMHRADDSHS_OPCODE| vrt(d) | vra(a) | vrb(b)| vrc(c)); }
 inline void Assembler::vmladduhm(VectorRegister d,VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMLADDUHM_OPCODE | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
@@ -860,6 +877,7 @@
 inline void Assembler::vmsumshs(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMSUMSHS_OPCODE  | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
 inline void Assembler::vmsumuhm(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMSUMUHM_OPCODE  | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
 inline void Assembler::vmsumuhs(VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMSUMUHS_OPCODE  | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
+inline void Assembler::vmaddfp( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VMADDFP_OPCODE   | vrt(d) | vra(a) | vrb(b)| vrc(c)); }
 inline void Assembler::vsumsws( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUMSWS_OPCODE  | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsum2sws(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUM2SWS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsum4sbs(VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSUM4SBS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
@@ -921,6 +939,7 @@
 inline void Assembler::vsrab(   VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSRAB_OPCODE    | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsraw(   VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSRAW_OPCODE    | vrt(d) | vra(a) | vrb(b)); }
 inline void Assembler::vsrah(   VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VSRAH_OPCODE    | vrt(d) | vra(a) | vrb(b)); }
+inline void Assembler::vpopcntw(VectorRegister d, VectorRegister b)                   { emit_int32( VPOPCNTW_OPCODE | vrt(d) | vrb(b)); }
 inline void Assembler::mtvscr(  VectorRegister b)                                     { emit_int32( MTVSCR_OPCODE   | vrb(b)); }
 inline void Assembler::mfvscr(  VectorRegister d)                                     { emit_int32( MFVSCR_OPCODE   | vrt(d)); }
 
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -2848,12 +2848,6 @@
   ld(displaced_header, oopDesc::mark_offset_in_bytes(), oop);
 
 
-  // Always do locking in runtime.
-  if (EmitSync & 0x01) {
-    cmpdi(flag, oop, 0); // Oop can't be 0 here => always false.
-    return;
-  }
-
   if (try_bias) {
     biased_locking_enter(flag, oop, displaced_header, temp, current_header, cont);
   }
@@ -2867,11 +2861,9 @@
 #endif // INCLUDE_RTM_OPT
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    // The object has an existing monitor iff (mark & monitor_value) != 0.
-    andi_(temp, displaced_header, markOopDesc::monitor_value);
-    bne(CCR0, object_has_monitor);
-  }
+  // The object has an existing monitor iff (mark & monitor_value) != 0.
+  andi_(temp, displaced_header, markOopDesc::monitor_value);
+  bne(CCR0, object_has_monitor);
 
   // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
   ori(displaced_header, displaced_header, markOopDesc::unlocked_value);
@@ -2914,48 +2906,46 @@
   std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), box);
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    b(cont);
-
-    bind(object_has_monitor);
-    // The object's monitor m is unlocked iff m->owner == NULL,
-    // otherwise m->owner may contain a thread or a stack address.
+  b(cont);
+
+  bind(object_has_monitor);
+  // The object's monitor m is unlocked iff m->owner == NULL,
+  // otherwise m->owner may contain a thread or a stack address.
 
 #if INCLUDE_RTM_OPT
-    // Use the same RTM locking code in 32- and 64-bit VM.
-    if (use_rtm) {
-      rtm_inflated_locking(flag, oop, displaced_header, box, temp, /*temp*/ current_header,
-                           rtm_counters, method_data, profile_rtm, cont);
-    } else {
+  // Use the same RTM locking code in 32- and 64-bit VM.
+  if (use_rtm) {
+    rtm_inflated_locking(flag, oop, displaced_header, box, temp, /*temp*/ current_header,
+                         rtm_counters, method_data, profile_rtm, cont);
+  } else {
 #endif // INCLUDE_RTM_OPT
 
-    // Try to CAS m->owner from NULL to current thread.
-    addi(temp, displaced_header, ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value);
-    cmpxchgd(/*flag=*/flag,
-             /*current_value=*/current_header,
-             /*compare_value=*/(intptr_t)0,
-             /*exchange_value=*/R16_thread,
-             /*where=*/temp,
-             MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
-             MacroAssembler::cmpxchgx_hint_acquire_lock());
-
-    // Store a non-null value into the box.
-    std(box, BasicLock::displaced_header_offset_in_bytes(), box);
-
-#   ifdef ASSERT
-    bne(flag, cont);
-    // We have acquired the monitor, check some invariants.
-    addi(/*monitor=*/temp, temp, -ObjectMonitor::owner_offset_in_bytes());
-    // Invariant 1: _recursions should be 0.
-    //assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size");
-    asm_assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), temp,
+  // Try to CAS m->owner from NULL to current thread.
+  addi(temp, displaced_header, ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value);
+  cmpxchgd(/*flag=*/flag,
+           /*current_value=*/current_header,
+           /*compare_value=*/(intptr_t)0,
+           /*exchange_value=*/R16_thread,
+           /*where=*/temp,
+           MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
+           MacroAssembler::cmpxchgx_hint_acquire_lock());
+
+  // Store a non-null value into the box.
+  std(box, BasicLock::displaced_header_offset_in_bytes(), box);
+
+# ifdef ASSERT
+  bne(flag, cont);
+  // We have acquired the monitor, check some invariants.
+  addi(/*monitor=*/temp, temp, -ObjectMonitor::owner_offset_in_bytes());
+  // Invariant 1: _recursions should be 0.
+  //assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size");
+  asm_assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), temp,
                             "monitor->_recursions should be 0", -1);
-#   endif
+# endif
 
 #if INCLUDE_RTM_OPT
-    } // use_rtm()
+  } // use_rtm()
 #endif
-  }
 
   bind(cont);
   // flag == EQ indicates success
@@ -2970,12 +2960,6 @@
   Label cont;
   Label object_has_monitor;
 
-  // Always do locking in runtime.
-  if (EmitSync & 0x01) {
-    cmpdi(flag, oop, 0); // Oop can't be 0 here => always false.
-    return;
-  }
-
   if (try_bias) {
     biased_locking_exit(flag, oop, current_header, cont);
   }
@@ -3002,13 +2986,11 @@
   beq(flag, cont);
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    // The object has an existing monitor iff (mark & monitor_value) != 0.
-    RTM_OPT_ONLY( if (!(UseRTMForStackLocks && use_rtm)) ) // skip load if already done
-    ld(current_header, oopDesc::mark_offset_in_bytes(), oop);
-    andi_(R0, current_header, markOopDesc::monitor_value);
-    bne(CCR0, object_has_monitor);
-  }
+  // The object has an existing monitor iff (mark & monitor_value) != 0.
+  RTM_OPT_ONLY( if (!(UseRTMForStackLocks && use_rtm)) ) // skip load if already done
+  ld(current_header, oopDesc::mark_offset_in_bytes(), oop);
+  andi_(R0, current_header, markOopDesc::monitor_value);
+  bne(CCR0, object_has_monitor);
 
   // Check if it is still a light weight lock, this is is true if we see
   // the stack address of the basicLock in the markOop of the object.
@@ -3026,40 +3008,38 @@
   assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    b(cont);
-
-    bind(object_has_monitor);
-    addi(current_header, current_header, -markOopDesc::monitor_value); // monitor
-    ld(temp,             ObjectMonitor::owner_offset_in_bytes(), current_header);
+  b(cont);
+
+  bind(object_has_monitor);
+  addi(current_header, current_header, -markOopDesc::monitor_value); // monitor
+  ld(temp,             ObjectMonitor::owner_offset_in_bytes(), current_header);
 
     // It's inflated.
 #if INCLUDE_RTM_OPT
-    if (use_rtm) {
-      Label L_regular_inflated_unlock;
-      // Clean monitor_value bit to get valid pointer
-      cmpdi(flag, temp, 0);
-      bne(flag, L_regular_inflated_unlock);
-      tend_();
-      b(cont);
-      bind(L_regular_inflated_unlock);
-    }
+  if (use_rtm) {
+    Label L_regular_inflated_unlock;
+    // Clean monitor_value bit to get valid pointer
+    cmpdi(flag, temp, 0);
+    bne(flag, L_regular_inflated_unlock);
+    tend_();
+    b(cont);
+    bind(L_regular_inflated_unlock);
+  }
 #endif
 
-    ld(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header);
-    xorr(temp, R16_thread, temp);      // Will be 0 if we are the owner.
-    orr(temp, temp, displaced_header); // Will be 0 if there are 0 recursions.
-    cmpdi(flag, temp, 0);
-    bne(flag, cont);
-
-    ld(temp,             ObjectMonitor::EntryList_offset_in_bytes(), current_header);
-    ld(displaced_header, ObjectMonitor::cxq_offset_in_bytes(), current_header);
-    orr(temp, temp, displaced_header); // Will be 0 if both are 0.
-    cmpdi(flag, temp, 0);
-    bne(flag, cont);
-    release();
-    std(temp, ObjectMonitor::owner_offset_in_bytes(), current_header);
-  }
+  ld(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header);
+  xorr(temp, R16_thread, temp);      // Will be 0 if we are the owner.
+  orr(temp, temp, displaced_header); // Will be 0 if there are 0 recursions.
+  cmpdi(flag, temp, 0);
+  bne(flag, cont);
+
+  ld(temp,             ObjectMonitor::EntryList_offset_in_bytes(), current_header);
+  ld(displaced_header, ObjectMonitor::cxq_offset_in_bytes(), current_header);
+  orr(temp, temp, displaced_header); // Will be 0 if both are 0.
+  cmpdi(flag, temp, 0);
+  bne(flag, cont);
+  release();
+  std(temp, ObjectMonitor::owner_offset_in_bytes(), current_header);
 
   bind(cont);
   // flag == EQ indicates success
--- a/src/hotspot/cpu/ppc/ppc.ad	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/ppc.ad	Thu Sep 13 10:54:11 2018 -0700
@@ -908,6 +908,7 @@
 // ----------------------------
 
 reg_class vs_reg(
+  // Attention: Only these ones are saved & restored at safepoint by RegisterSaver.
   VSR32,
   VSR33,
   VSR34,
@@ -928,18 +929,7 @@
   VSR49,
   VSR50,
   VSR51
-//  VSR52,     // nv!
-//  VSR53,     // nv!
-//  VSR54,     // nv!
-//  VSR55,     // nv!
-//  VSR56,     // nv!
-//  VSR57,     // nv!
-//  VSR58,     // nv!
-//  VSR59,     // nv!
-//  VSR60,     // nv!
-//  VSR61,     // nv!
-//  VSR62,     // nv!
-//  VSR63      // nv!
+  // VSR52-VSR63 // nv!
 );
 
  %}
@@ -2234,9 +2224,35 @@
   case Op_StrEquals:
     return SpecialStringEquals;
   case Op_StrIndexOf:
-    return SpecialStringIndexOf;
   case Op_StrIndexOfChar:
     return SpecialStringIndexOf;
+  case Op_AddVB:
+  case Op_AddVS:
+  case Op_AddVI:
+  case Op_AddVF:
+  case Op_AddVD:
+  case Op_SubVB:
+  case Op_SubVS:
+  case Op_SubVI:
+  case Op_SubVF:
+  case Op_SubVD:
+  case Op_MulVS:
+  case Op_MulVF:
+  case Op_MulVD:
+  case Op_DivVF:
+  case Op_DivVD:
+  case Op_AbsVF:
+  case Op_AbsVD:
+  case Op_NegVF:
+  case Op_NegVD:
+  case Op_SqrtVF:
+  case Op_SqrtVD:
+  case Op_AddVL:
+  case Op_SubVL:
+  case Op_MulVI:
+    return SuperwordUseVSX;
+  case Op_PopCountVI:
+    return (SuperwordUseVSX && UsePopCountInstruction);
   }
 
   return true;  // Per default match rules are supported.
@@ -10017,7 +10033,7 @@
 
 // Single-precision sqrt.
 instruct sqrtF_reg(regF dst, regF src) %{
-  match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
+  match(Set dst (SqrtF src));
   predicate(VM_Version::has_fsqrts());
   ins_cost(DEFAULT_COST);
 
@@ -13989,6 +14005,303 @@
 %}
 
 
+//----------Vector Arithmetic Instructions--------------------------------------
+
+// Vector Addition Instructions
+
+instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVB src1 src2));
+  predicate(n->as_Vector()->length() == 16);
+  format %{ "VADDUBM  $dst,$src1,$src2\t// add packed16B" %}
+  size(4);
+  ins_encode %{
+    __ vaddubm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVS src1 src2));
+  predicate(n->as_Vector()->length() == 8);
+  format %{ "VADDUHM  $dst,$src1,$src2\t// add packed8S" %}
+  size(4);
+  ins_encode %{
+    __ vadduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVI src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VADDUWM  $dst,$src1,$src2\t// add packed4I" %}
+  size(4);
+  ins_encode %{
+    __ vadduwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVF src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VADDFP  $dst,$src1,$src2\t// add packed4F" %}
+  size(4);
+  ins_encode %{
+    __ vaddfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVL src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "VADDUDM  $dst,$src1,$src2\t// add packed2L" %}
+  size(4);
+  ins_encode %{
+    __ vaddudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (AddVD src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVADDDP  $dst,$src1,$src2\t// add packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvadddp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Subtraction Instructions
+
+instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVB src1 src2));
+  predicate(n->as_Vector()->length() == 16);
+  format %{ "VSUBUBM  $dst,$src1,$src2\t// sub packed16B" %}
+  size(4);
+  ins_encode %{
+    __ vsububm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVS src1 src2));
+  predicate(n->as_Vector()->length() == 8);
+  format %{ "VSUBUHM  $dst,$src1,$src2\t// sub packed8S" %}
+  size(4);
+  ins_encode %{
+    __ vsubuhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVI src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VSUBUWM  $dst,$src1,$src2\t// sub packed4I" %}
+  size(4);
+  ins_encode %{
+    __ vsubuwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVF src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VSUBFP  $dst,$src1,$src2\t// sub packed4F" %}
+  size(4);
+  ins_encode %{
+    __ vsubfp($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVL src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "VSUBUDM  $dst,$src1,$src2\t// sub packed2L" %}
+  size(4);
+  ins_encode %{
+    __ vsubudm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (SubVD src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVSUBDP  $dst,$src1,$src2\t// sub packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvsubdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Multiplication Instructions
+
+instruct vmul8S_reg(vecX dst, vecX src1, vecX src2, vecX tmp) %{
+  match(Set dst (MulVS src1 src2));
+  predicate(n->as_Vector()->length() == 8);
+  effect(TEMP tmp);
+  format %{ "VSPLTISH  $tmp,0\t// mul packed8S" %}
+  format %{ "VMLADDUHM  $dst,$src1,$src2\t// mul packed8S" %}
+  size(8);
+  ins_encode %{
+    __ vspltish($tmp$$VectorSRegister->to_vr(), 0);
+    __ vmladduhm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr(), $tmp$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (MulVI src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VMULUWM  $dst,$src1,$src2\t// mul packed4I" %}
+  size(4);
+  ins_encode %{
+    __ vmuluwm($dst$$VectorSRegister->to_vr(), $src1$$VectorSRegister->to_vr(), $src2$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (MulVF src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "XVMULSP  $dst,$src1,$src2\t// mul packed4F" %}
+  size(4);
+  ins_encode %{
+    __ xvmulsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (MulVD src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVMULDP  $dst,$src1,$src2\t// mul packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvmuldp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Division Instructions
+
+instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (DivVF src1 src2));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "XVDIVSP  $dst,$src1,$src2\t// div packed4F" %}
+  size(4);
+  ins_encode %{
+    __ xvdivsp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
+  match(Set dst (DivVD src1 src2));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVDIVDP  $dst,$src1,$src2\t// div packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvdivdp($dst$$VectorSRegister, $src1$$VectorSRegister, $src2$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Absolute Instructions
+
+instruct vabs4F_reg(vecX dst, vecX src) %{
+  match(Set dst (AbsVF src));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "XVABSSP $dst,$src\t// absolute packed4F" %}
+  size(4);
+  ins_encode %{
+    __ xvabssp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vabs2D_reg(vecX dst, vecX src) %{
+  match(Set dst (AbsVD src));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVABSDP $dst,$src\t// absolute packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvabsdp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Negate Instructions
+
+instruct vneg4F_reg(vecX dst, vecX src) %{
+  match(Set dst (NegVF src));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "XVNEGSP $dst,$src\t// negate packed4F" %}
+  size(4);
+  ins_encode %{
+    __ xvnegsp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vneg2D_reg(vecX dst, vecX src) %{
+  match(Set dst (NegVD src));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVNEGDP $dst,$src\t// negate packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvnegdp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Square Root Instructions
+
+instruct vsqrt4F_reg(vecX dst, vecX src) %{
+  match(Set dst (SqrtVF src));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "XVSQRTSP $dst,$src\t// sqrt packed4F" %}
+  size(4);
+  ins_encode %{
+    __ xvsqrtsp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct vsqrt2D_reg(vecX dst, vecX src) %{
+  match(Set dst (SqrtVD src));
+  predicate(n->as_Vector()->length() == 2);
+  format %{ "XVSQRTDP  $dst,$src\t// sqrt packed2D" %}
+  size(4);
+  ins_encode %{
+    __ xvsqrtdp($dst$$VectorSRegister, $src$$VectorSRegister);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Vector Population Count Instructions
+
+instruct vpopcnt4I_reg(vecX dst, vecX src) %{
+  match(Set dst (PopCountVI src));
+  predicate(n->as_Vector()->length() == 4);
+  format %{ "VPOPCNTW $dst,$src\t// pop count packed4I" %}
+  size(4);
+  ins_encode %{
+    __ vpopcntw($dst$$VectorSRegister->to_vr(), $src$$VectorSRegister->to_vr());
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+
 //----------Overflow Math Instructions-----------------------------------------
 
 // Note that we have to make sure that XER.SO is reset before using overflow instructions.
--- a/src/hotspot/cpu/ppc/register_definitions_ppc.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/register_definitions_ppc.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -32,4 +32,6 @@
 
 REGISTER_DEFINITION(FloatRegister, fnoreg);
 
+REGISTER_DEFINITION(VectorRegister, vnoreg);
+
 REGISTER_DEFINITION(VectorSRegister, vsnoreg);
--- a/src/hotspot/cpu/ppc/register_ppc.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/register_ppc.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,6 @@
 #include "precompiled.hpp"
 #include "register_ppc.hpp"
 
-const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers * 2;
-const int ConcreteRegisterImpl::max_fpr = ConcreteRegisterImpl::max_gpr +
-                                          FloatRegisterImpl::number_of_registers * 2;
-const int ConcreteRegisterImpl::max_cnd = ConcreteRegisterImpl::max_fpr +
-                                          ConditionRegisterImpl::number_of_registers;
 
 const char* RegisterImpl::name() const {
   const char* names[number_of_registers] = {
@@ -92,6 +87,12 @@
 
 // Method to convert a VectorRegister to a Vector-Scalar Register (VectorSRegister)
 VectorSRegister VectorRegisterImpl::to_vsr() const {
-  if (this == vnoreg) { return vsnoregi; }
+  if (this == vnoreg) { return vsnoreg; }
   return as_VectorSRegister(encoding() + 32);
 }
+
+// Method to convert a VectorSRegister to a Vector Register (VectorRegister)
+VectorRegister VectorSRegisterImpl::to_vr() const {
+  if (this == vsnoreg) { return vnoreg; }
+  return as_VectorRegister(encoding() - 32);
+}
--- a/src/hotspot/cpu/ppc/register_ppc.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/register_ppc.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -515,11 +515,15 @@
 
   // accessors
   int encoding() const { assert(is_valid(), "invalid register"); return value(); }
+  inline VMReg as_VMReg();
 
   // testers
   bool is_valid() const { return 0 <=  value() &&  value() < number_of_registers; }
 
   const char* name() const;
+
+  // convert to VR
+  VectorRegister to_vr() const;
 };
 
 // The Vector-Scalar (VSX) registers of the POWER architecture.
@@ -592,7 +596,7 @@
 CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR63, (63));
 
 #ifndef DONT_USE_REGISTER_DEFINES
-#define vsnoregi ((VectorSRegister)(vsnoreg_VectorSRegisterEnumValue))
+#define vsnoreg ((VectorSRegister)(vsnoreg_VectorSRegisterEnumValue))
 #define VSR0    ((VectorSRegister)(   VSR0_VectorSRegisterEnumValue))
 #define VSR1    ((VectorSRegister)(   VSR1_VectorSRegisterEnumValue))
 #define VSR2    ((VectorSRegister)(   VSR2_VectorSRegisterEnumValue))
@@ -668,21 +672,16 @@
 class ConcreteRegisterImpl : public AbstractRegisterImpl {
  public:
   enum {
+    max_gpr = RegisterImpl::number_of_registers * 2,
+    max_fpr = max_gpr + FloatRegisterImpl::number_of_registers * 2,
+    max_vsr = max_fpr + VectorSRegisterImpl::number_of_registers,
+    max_cnd = max_vsr + ConditionRegisterImpl::number_of_registers,
+    max_spr = max_cnd + SpecialRegisterImpl::number_of_registers,
     // This number must be large enough to cover REG_COUNT (defined by c2) registers.
     // There is no requirement that any ordering here matches any ordering c2 gives
     // it's optoregs.
-    number_of_registers =
-      ( RegisterImpl::number_of_registers +
-        FloatRegisterImpl::number_of_registers )
-      * 2                                          // register halves
-      + ConditionRegisterImpl::number_of_registers // condition code registers
-      + SpecialRegisterImpl::number_of_registers   // special registers
-      + VectorSRegisterImpl::number_of_registers   // VSX registers
+    number_of_registers = max_spr
   };
-
-  static const int max_gpr;
-  static const int max_fpr;
-  static const int max_cnd;
 };
 
 // Common register declarations used in assembler code.
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -75,10 +75,12 @@
                          int* out_frame_size_in_bytes,
                          bool generate_oop_map,
                          int return_pc_adjustment,
-                         ReturnPCLocation return_pc_location);
+                         ReturnPCLocation return_pc_location,
+                         bool save_vectors = false);
   static void    restore_live_registers_and_pop_frame(MacroAssembler* masm,
                          int frame_size_in_bytes,
-                         bool restore_ctr);
+                         bool restore_ctr,
+                         bool save_vectors = false);
 
   static void push_frame_and_save_argument_registers(MacroAssembler* masm,
                          Register r_temp,
@@ -97,14 +99,16 @@
   // Constants and data structures:
 
   typedef enum {
-    int_reg           = 0,
-    float_reg         = 1,
-    special_reg       = 2
+    int_reg,
+    float_reg,
+    special_reg,
+    vs_reg
   } RegisterType;
 
   typedef enum {
     reg_size          = 8,
     half_reg_size     = reg_size / 2,
+    vs_reg_size       = 16
   } RegisterConstants;
 
   typedef struct {
@@ -115,14 +119,17 @@
 };
 
 
+#define RegisterSaver_LiveIntReg(regname) \
+  { RegisterSaver::int_reg,     regname->encoding(), regname->as_VMReg() }
+
+#define RegisterSaver_LiveFloatReg(regname) \
+  { RegisterSaver::float_reg,   regname->encoding(), regname->as_VMReg() }
+
 #define RegisterSaver_LiveSpecialReg(regname) \
   { RegisterSaver::special_reg, regname->encoding(), regname->as_VMReg() }
 
-#define RegisterSaver_LiveIntReg(regname) \
-  { RegisterSaver::int_reg,     regname->encoding(), regname->as_VMReg() }
-
-#define RegisterSaver_LiveFloatReg(regname) \
-  { RegisterSaver::float_reg,   regname->encoding(), regname->as_VMReg() }
+#define RegisterSaver_LiveVSReg(regname) \
+  { RegisterSaver::vs_reg,      regname->encoding(), regname->as_VMReg() }
 
 static const RegisterSaver::LiveRegType RegisterSaver_LiveRegs[] = {
   // Live registers which get spilled to the stack. Register
@@ -201,14 +208,42 @@
   RegisterSaver_LiveIntReg(   R28 ),
   RegisterSaver_LiveIntReg(   R29 ),
   RegisterSaver_LiveIntReg(   R30 ),
-  RegisterSaver_LiveIntReg(   R31 ), // must be the last register (see save/restore functions below)
+  RegisterSaver_LiveIntReg(   R31 )  // must be the last register (see save/restore functions below)
 };
 
+static const RegisterSaver::LiveRegType RegisterSaver_LiveVSRegs[] = {
+  //
+  // live vector scalar registers (optional, only these ones are used by C2):
+  //
+  RegisterSaver_LiveVSReg( VSR32 ),
+  RegisterSaver_LiveVSReg( VSR33 ),
+  RegisterSaver_LiveVSReg( VSR34 ),
+  RegisterSaver_LiveVSReg( VSR35 ),
+  RegisterSaver_LiveVSReg( VSR36 ),
+  RegisterSaver_LiveVSReg( VSR37 ),
+  RegisterSaver_LiveVSReg( VSR38 ),
+  RegisterSaver_LiveVSReg( VSR39 ),
+  RegisterSaver_LiveVSReg( VSR40 ),
+  RegisterSaver_LiveVSReg( VSR41 ),
+  RegisterSaver_LiveVSReg( VSR42 ),
+  RegisterSaver_LiveVSReg( VSR43 ),
+  RegisterSaver_LiveVSReg( VSR44 ),
+  RegisterSaver_LiveVSReg( VSR45 ),
+  RegisterSaver_LiveVSReg( VSR46 ),
+  RegisterSaver_LiveVSReg( VSR47 ),
+  RegisterSaver_LiveVSReg( VSR48 ),
+  RegisterSaver_LiveVSReg( VSR49 ),
+  RegisterSaver_LiveVSReg( VSR50 ),
+  RegisterSaver_LiveVSReg( VSR51 )
+};
+
+
 OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssembler* masm,
                          int* out_frame_size_in_bytes,
                          bool generate_oop_map,
                          int return_pc_adjustment,
-                         ReturnPCLocation return_pc_location) {
+                         ReturnPCLocation return_pc_location,
+                         bool save_vectors) {
   // Push an abi_reg_args-frame and store all registers which may be live.
   // If requested, create an OopMap: Record volatile registers as
   // callee-save values in an OopMap so their save locations will be
@@ -218,15 +253,16 @@
   // If return_pc_adjustment != 0 adjust the return pc by return_pc_adjustment.
   // Updated return pc is returned in R31 (if not return_pc_is_pre_saved).
 
-  int i;
-  int offset;
-
   // calcualte frame size
   const int regstosave_num       = sizeof(RegisterSaver_LiveRegs) /
                                    sizeof(RegisterSaver::LiveRegType);
-  const int register_save_size   = regstosave_num * reg_size;
+  const int vsregstosave_num     = save_vectors ? (sizeof(RegisterSaver_LiveVSRegs) /
+                                                   sizeof(RegisterSaver::LiveRegType))
+                                                : 0;
+  const int register_save_size   = regstosave_num * reg_size + vsregstosave_num * vs_reg_size;
   const int frame_size_in_bytes  = align_up(register_save_size, frame::alignment_in_bytes)
                                    + frame::abi_reg_args_size;
+
   *out_frame_size_in_bytes       = frame_size_in_bytes;
   const int frame_size_in_slots  = frame_size_in_bytes / sizeof(jint);
   const int register_save_offset = frame_size_in_bytes - register_save_size;
@@ -236,17 +272,18 @@
 
   BLOCK_COMMENT("push_frame_reg_args_and_save_live_registers {");
 
-  // Save some registers in the last slots of the not yet pushed frame so that we
-  // can use them as scratch regs.
-  __ std(R31, -  reg_size, R1_SP);
-  __ std(R30, -2*reg_size, R1_SP);
-  assert(-reg_size == register_save_offset - frame_size_in_bytes + ((regstosave_num-1)*reg_size),
-         "consistency check");
+  // push a new frame
+  __ push_frame(frame_size_in_bytes, noreg);
+
+  // Save some registers in the last (non-vector) slots of the new frame so we
+  // can use them as scratch regs or to determine the return pc.
+  __ std(R31, frame_size_in_bytes -   reg_size - vsregstosave_num * vs_reg_size, R1_SP);
+  __ std(R30, frame_size_in_bytes - 2*reg_size - vsregstosave_num * vs_reg_size, R1_SP);
 
   // save the flags
   // Do the save_LR_CR by hand and adjust the return pc if requested.
   __ mfcr(R30);
-  __ std(R30, _abi(cr), R1_SP);
+  __ std(R30, frame_size_in_bytes + _abi(cr), R1_SP);
   switch (return_pc_location) {
     case return_pc_is_lr: __ mflr(R31); break;
     case return_pc_is_pre_saved: assert(return_pc_adjustment == 0, "unsupported"); break;
@@ -257,14 +294,12 @@
     if (return_pc_adjustment != 0) {
       __ addi(R31, R31, return_pc_adjustment);
     }
-    __ std(R31, _abi(lr), R1_SP);
+    __ std(R31, frame_size_in_bytes + _abi(lr), R1_SP);
   }
 
-  // push a new frame
-  __ push_frame(frame_size_in_bytes, R30);
-
   // save all registers (ints and floats)
-  offset = register_save_offset;
+  int offset = register_save_offset;
+
   for (int i = 0; i < regstosave_num; i++) {
     int reg_num  = RegisterSaver_LiveRegs[i].reg_num;
     int reg_type = RegisterSaver_LiveRegs[i].reg_type;
@@ -302,6 +337,22 @@
     offset += reg_size;
   }
 
+  for (int i = 0; i < vsregstosave_num; i++) {
+    int reg_num  = RegisterSaver_LiveVSRegs[i].reg_num;
+    int reg_type = RegisterSaver_LiveVSRegs[i].reg_type;
+
+    __ li(R30, offset);
+    __ stxvd2x(as_VectorSRegister(reg_num), R30, R1_SP);
+
+    if (generate_oop_map) {
+      map->set_callee_saved(VMRegImpl::stack2reg(offset>>2),
+                            RegisterSaver_LiveVSRegs[i].vmreg);
+    }
+    offset += vs_reg_size;
+  }
+
+  assert(offset == frame_size_in_bytes, "consistency check");
+
   BLOCK_COMMENT("} push_frame_reg_args_and_save_live_registers");
 
   // And we're done.
@@ -313,18 +364,22 @@
 // saved.
 void RegisterSaver::restore_live_registers_and_pop_frame(MacroAssembler* masm,
                                                          int frame_size_in_bytes,
-                                                         bool restore_ctr) {
-  int i;
-  int offset;
+                                                         bool restore_ctr,
+                                                         bool save_vectors) {
   const int regstosave_num       = sizeof(RegisterSaver_LiveRegs) /
                                    sizeof(RegisterSaver::LiveRegType);
-  const int register_save_size   = regstosave_num * reg_size;
+  const int vsregstosave_num     = save_vectors ? (sizeof(RegisterSaver_LiveVSRegs) /
+                                                   sizeof(RegisterSaver::LiveRegType))
+                                                : 0;
+  const int register_save_size   = regstosave_num * reg_size + vsregstosave_num * vs_reg_size;
+
   const int register_save_offset = frame_size_in_bytes - register_save_size;
 
   BLOCK_COMMENT("restore_live_registers_and_pop_frame {");
 
   // restore all registers (ints and floats)
-  offset = register_save_offset;
+  int offset = register_save_offset;
+
   for (int i = 0; i < regstosave_num; i++) {
     int reg_num  = RegisterSaver_LiveRegs[i].reg_num;
     int reg_type = RegisterSaver_LiveRegs[i].reg_type;
@@ -356,14 +411,30 @@
     offset += reg_size;
   }
 
+  for (int i = 0; i < vsregstosave_num; i++) {
+    int reg_num  = RegisterSaver_LiveVSRegs[i].reg_num;
+    int reg_type = RegisterSaver_LiveVSRegs[i].reg_type;
+
+    __ li(R31, offset);
+    __ lxvd2x(as_VectorSRegister(reg_num), R31, R1_SP);
+
+    offset += vs_reg_size;
+  }
+
+  assert(offset == frame_size_in_bytes, "consistency check");
+
+  // restore link and the flags
+  __ ld(R31, frame_size_in_bytes + _abi(lr), R1_SP);
+  __ mtlr(R31);
+
+  __ ld(R31, frame_size_in_bytes + _abi(cr), R1_SP);
+  __ mtcr(R31);
+
+  // restore scratch register's value
+  __ ld(R31, frame_size_in_bytes - reg_size - vsregstosave_num * vs_reg_size, R1_SP);
+
   // pop the frame
-  __ pop_frame();
-
-  // restore the flags
-  __ restore_LR_CR(R31);
-
-  // restore scratch register's value
-  __ ld(R31, -reg_size, R1_SP);
+  __ addi(R1_SP, R1_SP, frame_size_in_bytes);
 
   BLOCK_COMMENT("} restore_live_registers_and_pop_frame");
 }
@@ -447,15 +518,13 @@
 
 // Restore the registers that might be holding a result.
 void RegisterSaver::restore_result_registers(MacroAssembler* masm, int frame_size_in_bytes) {
-  int i;
-  int offset;
   const int regstosave_num       = sizeof(RegisterSaver_LiveRegs) /
                                    sizeof(RegisterSaver::LiveRegType);
-  const int register_save_size   = regstosave_num * reg_size;
+  const int register_save_size   = regstosave_num * reg_size; // VS registers not relevant here.
   const int register_save_offset = frame_size_in_bytes - register_save_size;
 
   // restore all result registers (ints and floats)
-  offset = register_save_offset;
+  int offset = register_save_offset;
   for (int i = 0; i < regstosave_num; i++) {
     int reg_num  = RegisterSaver_LiveRegs[i].reg_num;
     int reg_type = RegisterSaver_LiveRegs[i].reg_type;
@@ -479,6 +548,8 @@
     }
     offset += reg_size;
   }
+
+  assert(offset == frame_size_in_bytes, "consistency check");
 }
 
 // Is vector's size (in bytes) bigger than a size saved by default?
@@ -3109,12 +3180,14 @@
     __ tabort_();
   }
 
+  bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
+
   // Save registers, fpu state, and flags. Set R31 = return pc.
   map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
                                                                    &frame_size_in_bytes,
                                                                    /*generate_oop_map=*/ true,
                                                                    /*return_pc_adjustment=*/0,
-                                                                   return_pc_location);
+                                                                   return_pc_location, save_vectors);
 
   // The following is basically a call_VM. However, we need the precise
   // address of the call in order to generate an oopmap. Hence, we do all the
@@ -3148,7 +3221,7 @@
   // Exception pending
   RegisterSaver::restore_live_registers_and_pop_frame(masm,
                                                       frame_size_in_bytes,
-                                                      /*restore_ctr=*/true);
+                                                      /*restore_ctr=*/true, save_vectors);
 
   BLOCK_COMMENT("  Jump to forward_exception_entry.");
   // Jump to forward_exception_entry, with the issuing PC in LR
@@ -3175,7 +3248,7 @@
   // Normal exit, restore registers and exit.
   RegisterSaver::restore_live_registers_and_pop_frame(masm,
                                                       frame_size_in_bytes,
-                                                      /*restore_ctr=*/true);
+                                                      /*restore_ctr=*/true, save_vectors);
 
   __ blr();
 
--- a/src/hotspot/cpu/ppc/vmreg_ppc.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/ppc/vmreg_ppc.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2013 SAP SE. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,16 +28,21 @@
 
 inline VMReg RegisterImpl::as_VMReg() {
   if (this == noreg) return VMRegImpl::Bad();
+  // Two halfs, multiply by 2.
   return VMRegImpl::as_VMReg(encoding() << 1);
 }
 
-// Since we don't have two halfs here, don't multiply by 2.
-inline VMReg ConditionRegisterImpl::as_VMReg() {
+inline VMReg FloatRegisterImpl::as_VMReg() {
+  // Two halfs, multiply by 2.
+  return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_gpr);
+}
+
+inline VMReg VectorSRegisterImpl::as_VMReg() {
   return VMRegImpl::as_VMReg((encoding()) + ConcreteRegisterImpl::max_fpr);
 }
 
-inline VMReg FloatRegisterImpl::as_VMReg() {
-  return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_gpr);
+inline VMReg ConditionRegisterImpl::as_VMReg() {
+  return VMRegImpl::as_VMReg((encoding()) + ConcreteRegisterImpl::max_vsr);
 }
 
 inline VMReg SpecialRegisterImpl::as_VMReg() {
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -465,19 +465,8 @@
       z_xihf(r1, -1);
     }
   } else { // Distinct src and dst registers.
-    if (VM_Version::has_DistinctOpnds()) {
-      load_const_optimized(r1, -1);
-      z_xgrk(r1, r2, r1);
-    } else {
-      if (wide) {
-        z_lgr(r1, r2);
-        z_xilf(r1, -1);
-        z_xihf(r1, -1);
-      } else {
-        z_lr(r1, r2);
-        z_xilf(r1, -1);
-      }
-    }
+    load_const_optimized(r1, -1);
+    z_xgr(r1, r2);
   }
 }
 
@@ -1158,8 +1147,10 @@
 // Make sure to keep code size constant -> no value-dependent optimizations.
 // Do not kill condition code.
 void MacroAssembler::load_const(Register t, long x) {
-  Assembler::z_iihf(t, (int)(x >> 32));
-  Assembler::z_iilf(t, (int)(x & 0xffffffff));
+  // Note: Right shift is only cleanly defined for unsigned types
+  //       or for signed types with nonnegative values.
+  Assembler::z_iihf(t, (long)((unsigned long)x >> 32));
+  Assembler::z_iilf(t, (long)((unsigned long)x & 0xffffffffUL));
 }
 
 // Load a 32bit constant into a 64bit register, sign-extend or zero-extend.
@@ -1256,8 +1247,10 @@
 // CPU-version dependend patching of load_const.
 void MacroAssembler::patch_const(address a, long x) {
   assert(is_load_const(a), "not a load of a constant");
-  set_imm32((address)a, (int) ((x >> 32) & 0xffffffff));
-  set_imm32((address)(a + 6), (int)(x & 0xffffffff));
+  // Note: Right shift is only cleanly defined for unsigned types
+  //       or for signed types with nonnegative values.
+  set_imm32((address)a, (long)((unsigned long)x >> 32));
+  set_imm32((address)(a + 6), (long)((unsigned long)x & 0xffffffffUL));
 }
 
 // Patching the value of CPU version dependent load_const_32to64 sequence.
@@ -1461,13 +1454,17 @@
 
   // 64 bit value: | part1 | part2 | part3 | part4 |
   // At least one part is not zero!
-  int part1 = ((x >> 32) & 0xffff0000) >> 16;
-  int part2 = (x >> 32) & 0x0000ffff;
-  int part3 = (x & 0xffff0000) >> 16;
-  int part4 = (x & 0x0000ffff);
+  // Note: Right shift is only cleanly defined for unsigned types
+  //       or for signed types with nonnegative values.
+  int part1 = (int)((unsigned long)x >> 48) & 0x0000ffff;
+  int part2 = (int)((unsigned long)x >> 32) & 0x0000ffff;
+  int part3 = (int)((unsigned long)x >> 16) & 0x0000ffff;
+  int part4 = (int)x & 0x0000ffff;
+  int part12 = (int)((unsigned long)x >> 32);
+  int part34 = (int)x;
 
   // Lower word only (unsigned).
-  if ((part1 == 0) && (part2 == 0)) {
+  if (part12 == 0) {
     if (part3 == 0) {
       if (emit) z_llill(t, part4);
       return 4;
@@ -1476,12 +1473,12 @@
       if (emit) z_llilh(t, part3);
       return 4;
     }
-    if (emit) z_llilf(t, (int)(x & 0xffffffff));
+    if (emit) z_llilf(t, part34);
     return 6;
   }
 
   // Upper word only.
-  if ((part3 == 0) && (part4 == 0)) {
+  if (part34 == 0) {
     if (part1 == 0) {
       if (emit) z_llihl(t, part2);
       return 4;
@@ -1490,13 +1487,13 @@
       if (emit) z_llihh(t, part1);
       return 4;
     }
-    if (emit) z_llihf(t, (int)(x >> 32));
+    if (emit) z_llihf(t, part12);
     return 6;
   }
 
   // Lower word only (signed).
   if ((part1 == 0x0000ffff) && (part2 == 0x0000ffff) && ((part3 & 0x00008000) != 0)) {
-    if (emit) z_lgfi(t, (int)(x & 0xffffffff));
+    if (emit) z_lgfi(t, part34);
     return 6;
   }
 
@@ -1511,7 +1508,7 @@
       len += 4;
     }
   } else {
-    if (emit) z_llihf(t, (int)(x >> 32));
+    if (emit) z_llihf(t, part12);
     len += 6;
   }
 
@@ -1524,7 +1521,7 @@
       len += 4;
     }
   } else {
-    if (emit) z_iilf(t, (int)(x & 0xffffffff));
+    if (emit) z_iilf(t, part34);
     len += 6;
   }
   return len;
@@ -3374,13 +3371,11 @@
   }
 
   // Handle existing monitor.
-  if ((EmitSync & 0x01) == 0) {
-    // The object has an existing monitor iff (mark & monitor_value) != 0.
-    guarantee(Immediate::is_uimm16(markOopDesc::monitor_value), "must be half-word");
-    z_lr(temp, displacedHeader);
-    z_nill(temp, markOopDesc::monitor_value);
-    z_brne(object_has_monitor);
-  }
+  // The object has an existing monitor iff (mark & monitor_value) != 0.
+  guarantee(Immediate::is_uimm16(markOopDesc::monitor_value), "must be half-word");
+  z_lr(temp, displacedHeader);
+  z_nill(temp, markOopDesc::monitor_value);
+  z_brne(object_has_monitor);
 
   // Set mark to markOop | markOopDesc::unlocked_value.
   z_oill(displacedHeader, markOopDesc::unlocked_value);
@@ -3411,28 +3406,26 @@
 
   z_bru(done);
 
-  if ((EmitSync & 0x01) == 0) {
-    Register zero = temp;
-    Register monitor_tagged = displacedHeader; // Tagged with markOopDesc::monitor_value.
-    bind(object_has_monitor);
-    // The object's monitor m is unlocked iff m->owner == NULL,
-    // otherwise m->owner may contain a thread or a stack address.
-    //
-    // Try to CAS m->owner from NULL to current thread.
-    z_lghi(zero, 0);
-    // If m->owner is null, then csg succeeds and sets m->owner=THREAD and CR=EQ.
-    z_csg(zero, Z_thread, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), monitor_tagged);
-    // Store a non-null value into the box.
-    z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box);
+  Register zero = temp;
+  Register monitor_tagged = displacedHeader; // Tagged with markOopDesc::monitor_value.
+  bind(object_has_monitor);
+  // The object's monitor m is unlocked iff m->owner == NULL,
+  // otherwise m->owner may contain a thread or a stack address.
+  //
+  // Try to CAS m->owner from NULL to current thread.
+  z_lghi(zero, 0);
+  // If m->owner is null, then csg succeeds and sets m->owner=THREAD and CR=EQ.
+  z_csg(zero, Z_thread, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), monitor_tagged);
+  // Store a non-null value into the box.
+  z_stg(box, BasicLock::displaced_header_offset_in_bytes(), box);
 #ifdef ASSERT
-      z_brne(done);
-      // We've acquired the monitor, check some invariants.
-      // Invariant 1: _recursions should be 0.
-      asm_assert_mem8_is_zero(OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions), monitor_tagged,
-                              "monitor->_recursions should be 0", -1);
-      z_ltgr(zero, zero); // Set CR=EQ.
+  z_brne(done);
+  // We've acquired the monitor, check some invariants.
+  // Invariant 1: _recursions should be 0.
+  asm_assert_mem8_is_zero(OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions), monitor_tagged,
+                          "monitor->_recursions should be 0", -1);
+  z_ltgr(zero, zero); // Set CR=EQ.
 #endif
-  }
   bind(done);
 
   BLOCK_COMMENT("} compiler_fast_lock_object");
@@ -3461,13 +3454,11 @@
   z_bre(done);
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    // The object has an existing monitor iff (mark & monitor_value) != 0.
-    z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop);
-    guarantee(Immediate::is_uimm16(markOopDesc::monitor_value), "must be half-word");
-    z_nill(currentHeader, markOopDesc::monitor_value);
-    z_brne(object_has_monitor);
-  }
+  // The object has an existing monitor iff (mark & monitor_value) != 0.
+  z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop);
+  guarantee(Immediate::is_uimm16(markOopDesc::monitor_value), "must be half-word");
+  z_nill(currentHeader, markOopDesc::monitor_value);
+  z_brne(object_has_monitor);
 
   // Check if it is still a light weight lock, this is true if we see
   // the stack address of the basicLock in the markOop of the object
@@ -3477,20 +3468,18 @@
   z_bru(done); // Csg sets CR as desired.
 
   // Handle existing monitor.
-  if ((EmitSync & 0x02) == 0) {
-    bind(object_has_monitor);
-    z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop);    // CurrentHeader is tagged with monitor_value set.
-    load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
-    z_brne(done);
-    load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-    z_brne(done);
-    load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
-    z_brne(done);
-    load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
-    z_brne(done);
-    z_release();
-    z_stg(temp/*=0*/, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), currentHeader);
-  }
+  bind(object_has_monitor);
+  z_lg(currentHeader, oopDesc::mark_offset_in_bytes(), oop);    // CurrentHeader is tagged with monitor_value set.
+  load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
+  z_brne(done);
+  load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+  z_brne(done);
+  load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
+  z_brne(done);
+  load_and_test_long(temp, Address(currentHeader, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
+  z_brne(done);
+  z_release();
+  z_stg(temp/*=0*/, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), currentHeader);
 
   bind(done);
 
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -2648,195 +2648,92 @@
      inc_counter((address) counters->total_entry_count_addr(), Rmark, Rscratch);
    }
 
-   if (EmitSync & 1) {
-     mov(3, Rscratch);
-     st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
-     cmp(SP, G0);
-     return ;
-   }
-
-   if (EmitSync & 2) {
-
-     // Fetch object's markword
-     ld_ptr(mark_addr, Rmark);
-
-     if (try_bias) {
-        biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
-     }
-
-     // Save Rbox in Rscratch to be used for the cas operation
-     mov(Rbox, Rscratch);
-
-     // set Rmark to markOop | markOopDesc::unlocked_value
-     or3(Rmark, markOopDesc::unlocked_value, Rmark);
-
-     // Initialize the box.  (Must happen before we update the object mark!)
-     st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
-
-     // compare object markOop with Rmark and if equal exchange Rscratch with object markOop
-     assert(mark_addr.disp() == 0, "cas must take a zero displacement");
-     cas_ptr(mark_addr.base(), Rmark, Rscratch);
-
-     // if compare/exchange succeeded we found an unlocked object and we now have locked it
-     // hence we are done
-     cmp(Rmark, Rscratch);
-     sub(Rscratch, STACK_BIAS, Rscratch);
-     brx(Assembler::equal, false, Assembler::pt, done);
-     delayed()->sub(Rscratch, SP, Rscratch);  //pull next instruction into delay slot
-
-     // we did not find an unlocked object so see if this is a recursive case
-     // sub(Rscratch, SP, Rscratch);
-     assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
-     andcc(Rscratch, 0xfffff003, Rscratch);
-     st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
-     bind (done);
-     return ;
-   }
-
    Label Egress ;
 
-   if (EmitSync & 256) {
-      Label IsInflated ;
-
-      ld_ptr(mark_addr, Rmark);           // fetch obj->mark
-      // Triage: biased, stack-locked, neutral, inflated
-      if (try_bias) {
-        biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
-        // Invariant: if control reaches this point in the emitted stream
-        // then Rmark has not been modified.
-      }
-
-      // Store mark into displaced mark field in the on-stack basic-lock "box"
-      // Critically, this must happen before the CAS
-      // Maximize the ST-CAS distance to minimize the ST-before-CAS penalty.
-      st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
-      andcc(Rmark, 2, G0);
-      brx(Assembler::notZero, false, Assembler::pn, IsInflated);
-      delayed()->
-
-      // Try stack-lock acquisition.
-      // Beware: the 1st instruction is in a delay slot
-      mov(Rbox,  Rscratch);
-      or3(Rmark, markOopDesc::unlocked_value, Rmark);
-      assert(mark_addr.disp() == 0, "cas must take a zero displacement");
-      cas_ptr(mark_addr.base(), Rmark, Rscratch);
-      cmp(Rmark, Rscratch);
-      brx(Assembler::equal, false, Assembler::pt, done);
-      delayed()->sub(Rscratch, SP, Rscratch);
-
-      // Stack-lock attempt failed - check for recursive stack-lock.
-      // See the comments below about how we might remove this case.
-      sub(Rscratch, STACK_BIAS, Rscratch);
-      assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
-      andcc(Rscratch, 0xfffff003, Rscratch);
-      br(Assembler::always, false, Assembler::pt, done);
-      delayed()-> st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
-
-      bind(IsInflated);
-      if (EmitSync & 64) {
-         // If m->owner != null goto IsLocked
-         // Pessimistic form: Test-and-CAS vs CAS
-         // The optimistic form avoids RTS->RTO cache line upgrades.
-         ld_ptr(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rscratch);
-         andcc(Rscratch, Rscratch, G0);
-         brx(Assembler::notZero, false, Assembler::pn, done);
-         delayed()->nop();
-         // m->owner == null : it's unlocked.
-      }
-
-      // Try to CAS m->owner from null to Self
-      // Invariant: if we acquire the lock then _recursions should be 0.
-      add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
-      mov(G2_thread, Rscratch);
-      cas_ptr(Rmark, G0, Rscratch);
-      cmp(Rscratch, G0);
-      // Intentional fall-through into done
-   } else {
-      // Aggressively avoid the Store-before-CAS penalty
-      // Defer the store into box->dhw until after the CAS
-      Label IsInflated, Recursive ;
+   // Aggressively avoid the Store-before-CAS penalty
+   // Defer the store into box->dhw until after the CAS
+   Label IsInflated, Recursive ;
 
 // Anticipate CAS -- Avoid RTS->RTO upgrade
 // prefetch (mark_addr, Assembler::severalWritesAndPossiblyReads);
 
-      ld_ptr(mark_addr, Rmark);           // fetch obj->mark
-      // Triage: biased, stack-locked, neutral, inflated
-
-      if (try_bias) {
-        biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
-        // Invariant: if control reaches this point in the emitted stream
-        // then Rmark has not been modified.
-      }
-      andcc(Rmark, 2, G0);
-      brx(Assembler::notZero, false, Assembler::pn, IsInflated);
-      delayed()->                         // Beware - dangling delay-slot
-
-      // Try stack-lock acquisition.
-      // Transiently install BUSY (0) encoding in the mark word.
-      // if the CAS of 0 into the mark was successful then we execute:
-      //   ST box->dhw  = mark   -- save fetched mark in on-stack basiclock box
-      //   ST obj->mark = box    -- overwrite transient 0 value
-      // This presumes TSO, of course.
-
-      mov(0, Rscratch);
-      or3(Rmark, markOopDesc::unlocked_value, Rmark);
-      assert(mark_addr.disp() == 0, "cas must take a zero displacement");
-      cas_ptr(mark_addr.base(), Rmark, Rscratch);
+   ld_ptr(mark_addr, Rmark);           // fetch obj->mark
+   // Triage: biased, stack-locked, neutral, inflated
+
+   if (try_bias) {
+     biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
+     // Invariant: if control reaches this point in the emitted stream
+     // then Rmark has not been modified.
+   }
+   andcc(Rmark, 2, G0);
+   brx(Assembler::notZero, false, Assembler::pn, IsInflated);
+   delayed()->                         // Beware - dangling delay-slot
+
+   // Try stack-lock acquisition.
+   // Transiently install BUSY (0) encoding in the mark word.
+   // if the CAS of 0 into the mark was successful then we execute:
+   //   ST box->dhw  = mark   -- save fetched mark in on-stack basiclock box
+   //   ST obj->mark = box    -- overwrite transient 0 value
+   // This presumes TSO, of course.
+
+   mov(0, Rscratch);
+   or3(Rmark, markOopDesc::unlocked_value, Rmark);
+   assert(mark_addr.disp() == 0, "cas must take a zero displacement");
+   cas_ptr(mark_addr.base(), Rmark, Rscratch);
 // prefetch (mark_addr, Assembler::severalWritesAndPossiblyReads);
-      cmp(Rscratch, Rmark);
-      brx(Assembler::notZero, false, Assembler::pn, Recursive);
-      delayed()->st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
-      if (counters != NULL) {
-        cond_inc(Assembler::equal, (address) counters->fast_path_entry_count_addr(), Rmark, Rscratch);
-      }
-      ba(done);
-      delayed()->st_ptr(Rbox, mark_addr);
-
-      bind(Recursive);
-      // Stack-lock attempt failed - check for recursive stack-lock.
-      // Tests show that we can remove the recursive case with no impact
-      // on refworkload 0.83.  If we need to reduce the size of the code
-      // emitted by compiler_lock_object() the recursive case is perfect
-      // candidate.
-      //
-      // A more extreme idea is to always inflate on stack-lock recursion.
-      // This lets us eliminate the recursive checks in compiler_lock_object
-      // and compiler_unlock_object and the (box->dhw == 0) encoding.
-      // A brief experiment - requiring changes to synchronizer.cpp, interpreter,
-      // and showed a performance *increase*.  In the same experiment I eliminated
-      // the fast-path stack-lock code from the interpreter and always passed
-      // control to the "slow" operators in synchronizer.cpp.
-
-      // RScratch contains the fetched obj->mark value from the failed CAS.
-      sub(Rscratch, STACK_BIAS, Rscratch);
-      sub(Rscratch, SP, Rscratch);
-      assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
-      andcc(Rscratch, 0xfffff003, Rscratch);
-      if (counters != NULL) {
-        // Accounting needs the Rscratch register
-        st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
-        cond_inc(Assembler::equal, (address) counters->fast_path_entry_count_addr(), Rmark, Rscratch);
-        ba_short(done);
-      } else {
-        ba(done);
-        delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
-      }
-
-      bind   (IsInflated);
-
-      // Try to CAS m->owner from null to Self
-      // Invariant: if we acquire the lock then _recursions should be 0.
-      add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
-      mov(G2_thread, Rscratch);
-      cas_ptr(Rmark, G0, Rscratch);
-      andcc(Rscratch, Rscratch, G0);             // set ICCs for done: icc.zf iff success
-      // set icc.zf : 1=success 0=failure
-      // ST box->displaced_header = NonZero.
-      // Any non-zero value suffices:
-      //    markOopDesc::unused_mark(), G2_thread, RBox, RScratch, rsp, etc.
-      st_ptr(Rbox, Rbox, BasicLock::displaced_header_offset_in_bytes());
-      // Intentional fall-through into done
+   cmp(Rscratch, Rmark);
+   brx(Assembler::notZero, false, Assembler::pn, Recursive);
+   delayed()->st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());
+   if (counters != NULL) {
+     cond_inc(Assembler::equal, (address) counters->fast_path_entry_count_addr(), Rmark, Rscratch);
    }
+   ba(done);
+   delayed()->st_ptr(Rbox, mark_addr);
+
+   bind(Recursive);
+   // Stack-lock attempt failed - check for recursive stack-lock.
+   // Tests show that we can remove the recursive case with no impact
+   // on refworkload 0.83.  If we need to reduce the size of the code
+   // emitted by compiler_lock_object() the recursive case is perfect
+   // candidate.
+   //
+   // A more extreme idea is to always inflate on stack-lock recursion.
+   // This lets us eliminate the recursive checks in compiler_lock_object
+   // and compiler_unlock_object and the (box->dhw == 0) encoding.
+   // A brief experiment - requiring changes to synchronizer.cpp, interpreter,
+   // and showed a performance *increase*.  In the same experiment I eliminated
+   // the fast-path stack-lock code from the interpreter and always passed
+   // control to the "slow" operators in synchronizer.cpp.
+
+   // RScratch contains the fetched obj->mark value from the failed CAS.
+   sub(Rscratch, STACK_BIAS, Rscratch);
+   sub(Rscratch, SP, Rscratch);
+   assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
+   andcc(Rscratch, 0xfffff003, Rscratch);
+   if (counters != NULL) {
+     // Accounting needs the Rscratch register
+     st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
+     cond_inc(Assembler::equal, (address) counters->fast_path_entry_count_addr(), Rmark, Rscratch);
+     ba_short(done);
+   } else {
+     ba(done);
+     delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
+   }
+
+   bind   (IsInflated);
+
+   // Try to CAS m->owner from null to Self
+   // Invariant: if we acquire the lock then _recursions should be 0.
+   add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
+   mov(G2_thread, Rscratch);
+   cas_ptr(Rmark, G0, Rscratch);
+   andcc(Rscratch, Rscratch, G0);             // set ICCs for done: icc.zf iff success
+   // set icc.zf : 1=success 0=failure
+   // ST box->displaced_header = NonZero.
+   // Any non-zero value suffices:
+   //    markOopDesc::unused_mark(), G2_thread, RBox, RScratch, rsp, etc.
+   st_ptr(Rbox, Rbox, BasicLock::displaced_header_offset_in_bytes());
+   // Intentional fall-through into done
 
    bind   (done);
 }
@@ -2848,30 +2745,6 @@
 
    Label done ;
 
-   if (EmitSync & 4) {
-     cmp(SP, G0);
-     return ;
-   }
-
-   if (EmitSync & 8) {
-     if (try_bias) {
-        biased_locking_exit(mark_addr, Rscratch, done);
-     }
-
-     // Test first if it is a fast recursive unlock
-     ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
-     br_null_short(Rmark, Assembler::pt, done);
-
-     // Check if it is still a light weight lock, this is is true if we see
-     // the stack address of the basicLock in the markOop of the object
-     assert(mark_addr.disp() == 0, "cas must take a zero displacement");
-     cas_ptr(mark_addr.base(), Rbox, Rmark);
-     ba(done);
-     delayed()->cmp(Rbox, Rmark);
-     bind(done);
-     return ;
-   }
-
    // Beware ... If the aggregate size of the code emitted by CLO and CUO is
    // is too large performance rolls abruptly off a cliff.
    // This could be related to inlining policies, code cache management, or
@@ -2902,105 +2775,39 @@
    // close the resultant (and rare) race by having contended threads in
    // monitorenter periodically poll _owner.
 
-   if (EmitSync & 1024) {
-     // Emit code to check that _owner == Self
-     // We could fold the _owner test into subsequent code more efficiently
-     // than using a stand-alone check, but since _owner checking is off by
-     // default we don't bother. We also might consider predicating the
-     // _owner==Self check on Xcheck:jni or running on a debug build.
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), Rscratch);
-     orcc(Rscratch, G0, G0);
-     brx(Assembler::notZero, false, Assembler::pn, done);
-     delayed()->nop();
-   }
-
-   if (EmitSync & 512) {
-     // classic lock release code absent 1-0 locking
-     //   m->Owner = null;
-     //   membar #storeload
-     //   if (m->cxq|m->EntryList) == null goto Success
-     //   if (m->succ != null) goto Success
-     //   if CAS (&m->Owner,0,Self) != 0 goto Success
-     //   goto SlowPath
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), Rbox);
-     orcc(Rbox, G0, G0);
-     brx(Assembler::notZero, false, Assembler::pn, done);
-     delayed()->nop();
-     st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-     if (os::is_MP()) { membar(StoreLoad); }
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)), Rscratch);
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)), Rbox);
-     orcc(Rbox, Rscratch, G0);
-     brx(Assembler::zero, false, Assembler::pt, done);
-     delayed()->
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
-     andcc(Rscratch, Rscratch, G0);
-     brx(Assembler::notZero, false, Assembler::pt, done);
-     delayed()->andcc(G0, G0, G0);
-     add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
-     mov(G2_thread, Rscratch);
-     cas_ptr(Rmark, G0, Rscratch);
-     cmp(Rscratch, G0);
-     // invert icc.zf and goto done
-     brx(Assembler::notZero, false, Assembler::pt, done);
-     delayed()->cmp(G0, G0);
-     br(Assembler::always, false, Assembler::pt, done);
-     delayed()->cmp(G0, 1);
-   } else {
-     // 1-0 form : avoids CAS and MEMBAR in the common case
-     // Do not bother to ratify that m->Owner == Self.
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), Rbox);
-     orcc(Rbox, G0, G0);
-     brx(Assembler::notZero, false, Assembler::pn, done);
-     delayed()->
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)), Rscratch);
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)), Rbox);
-     orcc(Rbox, Rscratch, G0);
-     if (EmitSync & 16384) {
-       // As an optional optimization, if (EntryList|cxq) != null and _succ is null then
-       // we should transfer control directly to the slow-path.
-       // This test makes the reacquire operation below very infrequent.
-       // The logic is equivalent to :
-       //   if (cxq|EntryList) == null : Owner=null; goto Success
-       //   if succ == null : goto SlowPath
-       //   Owner=null; membar #storeload
-       //   if succ != null : goto Success
-       //   if CAS(&Owner,null,Self) != null goto Success
-       //   goto SlowPath
-       brx(Assembler::zero, true, Assembler::pt, done);
-       delayed()->
-       st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-       ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
-       andcc(Rscratch, Rscratch, G0) ;
-       brx(Assembler::zero, false, Assembler::pt, done);
-       delayed()->orcc(G0, 1, G0);
-       st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-     } else {
-       brx(Assembler::zero, false, Assembler::pt, done);
-       delayed()->
-       st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-     }
-     if (os::is_MP()) { membar(StoreLoad); }
-     // Check that _succ is (or remains) non-zero
-     ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
-     andcc(Rscratch, Rscratch, G0);
-     brx(Assembler::notZero, false, Assembler::pt, done);
-     delayed()->andcc(G0, G0, G0);
-     add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
-     mov(G2_thread, Rscratch);
-     cas_ptr(Rmark, G0, Rscratch);
-     cmp(Rscratch, G0);
-     // invert icc.zf and goto done
-     // A slightly better v8+/v9 idiom would be the following:
-     //   movrnz Rscratch,1,Rscratch
-     //   ba done
-     //   xorcc Rscratch,1,G0
-     // In v8+ mode the idiom would be valid IFF Rscratch was a G or O register
-     brx(Assembler::notZero, false, Assembler::pt, done);
-     delayed()->cmp(G0, G0);
-     br(Assembler::always, false, Assembler::pt, done);
-     delayed()->cmp(G0, 1);
-   }
+   // 1-0 form : avoids CAS and MEMBAR in the common case
+   // Do not bother to ratify that m->Owner == Self.
+   ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), Rbox);
+   orcc(Rbox, G0, G0);
+   brx(Assembler::notZero, false, Assembler::pn, done);
+   delayed()->
+   ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)), Rscratch);
+   ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)), Rbox);
+   orcc(Rbox, Rscratch, G0);
+   brx(Assembler::zero, false, Assembler::pt, done);
+   delayed()->
+   st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+
+   if (os::is_MP()) { membar(StoreLoad); }
+   // Check that _succ is (or remains) non-zero
+   ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
+   andcc(Rscratch, Rscratch, G0);
+   brx(Assembler::notZero, false, Assembler::pt, done);
+   delayed()->andcc(G0, G0, G0);
+   add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
+   mov(G2_thread, Rscratch);
+   cas_ptr(Rmark, G0, Rscratch);
+   cmp(Rscratch, G0);
+   // invert icc.zf and goto done
+   // A slightly better v8+/v9 idiom would be the following:
+   //   movrnz Rscratch,1,Rscratch
+   //   ba done
+   //   xorcc Rscratch,1,G0
+   // In v8+ mode the idiom would be valid IFF Rscratch was a G or O register
+   brx(Assembler::notZero, false, Assembler::pt, done);
+   delayed()->cmp(G0, G0);
+   br(Assembler::always, false, Assembler::pt, done);
+   delayed()->cmp(G0, 1);
 
    bind   (LStacked);
    // Consider: we could replace the expensive CAS in the exit
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1721,227 +1721,160 @@
   if (counters != NULL) {
     atomic_incl(ExternalAddress((address)counters->total_entry_count_addr()), scrReg);
   }
-  if (EmitSync & 1) {
-      // set box->dhw = markOopDesc::unused_mark()
-      // Force all sync thru slow-path: slow_enter() and slow_exit()
-      movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark()));
-      cmpptr (rsp, (int32_t)NULL_WORD);
-  } else {
-    // Possible cases that we'll encounter in fast_lock
-    // ------------------------------------------------
-    // * Inflated
-    //    -- unlocked
-    //    -- Locked
-    //       = by self
-    //       = by other
-    // * biased
-    //    -- by Self
-    //    -- by other
-    // * neutral
-    // * stack-locked
-    //    -- by self
-    //       = sp-proximity test hits
-    //       = sp-proximity test generates false-negative
-    //    -- by other
-    //
-
-    Label IsInflated, DONE_LABEL;
-
-    // it's stack-locked, biased or neutral
-    // TODO: optimize away redundant LDs of obj->mark and improve the markword triage
-    // order to reduce the number of conditional branches in the most common cases.
-    // Beware -- there's a subtle invariant that fetch of the markword
-    // at [FETCH], below, will never observe a biased encoding (*101b).
-    // If this invariant is not held we risk exclusion (safety) failure.
-    if (UseBiasedLocking && !UseOptoBiasInlining) {
-      biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters);
-    }
+
+  // Possible cases that we'll encounter in fast_lock
+  // ------------------------------------------------
+  // * Inflated
+  //    -- unlocked
+  //    -- Locked
+  //       = by self
+  //       = by other
+  // * biased
+  //    -- by Self
+  //    -- by other
+  // * neutral
+  // * stack-locked
+  //    -- by self
+  //       = sp-proximity test hits
+  //       = sp-proximity test generates false-negative
+  //    -- by other
+  //
+
+  Label IsInflated, DONE_LABEL;
+
+  // it's stack-locked, biased or neutral
+  // TODO: optimize away redundant LDs of obj->mark and improve the markword triage
+  // order to reduce the number of conditional branches in the most common cases.
+  // Beware -- there's a subtle invariant that fetch of the markword
+  // at [FETCH], below, will never observe a biased encoding (*101b).
+  // If this invariant is not held we risk exclusion (safety) failure.
+  if (UseBiasedLocking && !UseOptoBiasInlining) {
+    biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters);
+  }
 
 #if INCLUDE_RTM_OPT
-    if (UseRTMForStackLocks && use_rtm) {
-      rtm_stack_locking(objReg, tmpReg, scrReg, cx2Reg,
-                        stack_rtm_counters, method_data, profile_rtm,
-                        DONE_LABEL, IsInflated);
-    }
+  if (UseRTMForStackLocks && use_rtm) {
+    rtm_stack_locking(objReg, tmpReg, scrReg, cx2Reg,
+                      stack_rtm_counters, method_data, profile_rtm,
+                      DONE_LABEL, IsInflated);
+  }
 #endif // INCLUDE_RTM_OPT
 
-    movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));          // [FETCH]
-    testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
-    jccb(Assembler::notZero, IsInflated);
-
-    // Attempt stack-locking ...
-    orptr (tmpReg, markOopDesc::unlocked_value);
-    movptr(Address(boxReg, 0), tmpReg);          // Anticipate successful CAS
-    if (os::is_MP()) {
-      lock();
-    }
-    cmpxchgptr(boxReg, Address(objReg, oopDesc::mark_offset_in_bytes()));      // Updates tmpReg
-    if (counters != NULL) {
-      cond_inc32(Assembler::equal,
-                 ExternalAddress((address)counters->fast_path_entry_count_addr()));
-    }
-    jcc(Assembler::equal, DONE_LABEL);           // Success
-
-    // Recursive locking.
-    // The object is stack-locked: markword contains stack pointer to BasicLock.
-    // Locked by current thread if difference with current SP is less than one page.
-    subptr(tmpReg, rsp);
-    // Next instruction set ZFlag == 1 (Success) if difference is less then one page.
-    andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) );
-    movptr(Address(boxReg, 0), tmpReg);
-    if (counters != NULL) {
-      cond_inc32(Assembler::equal,
-                 ExternalAddress((address)counters->fast_path_entry_count_addr()));
-    }
-    jmp(DONE_LABEL);
-
-    bind(IsInflated);
-    // The object is inflated. tmpReg contains pointer to ObjectMonitor* + markOopDesc::monitor_value
+  movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));          // [FETCH]
+  testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
+  jccb(Assembler::notZero, IsInflated);
+
+  // Attempt stack-locking ...
+  orptr (tmpReg, markOopDesc::unlocked_value);
+  movptr(Address(boxReg, 0), tmpReg);          // Anticipate successful CAS
+  if (os::is_MP()) {
+    lock();
+  }
+  cmpxchgptr(boxReg, Address(objReg, oopDesc::mark_offset_in_bytes()));      // Updates tmpReg
+  if (counters != NULL) {
+    cond_inc32(Assembler::equal,
+               ExternalAddress((address)counters->fast_path_entry_count_addr()));
+  }
+  jcc(Assembler::equal, DONE_LABEL);           // Success
+
+  // Recursive locking.
+  // The object is stack-locked: markword contains stack pointer to BasicLock.
+  // Locked by current thread if difference with current SP is less than one page.
+  subptr(tmpReg, rsp);
+  // Next instruction set ZFlag == 1 (Success) if difference is less then one page.
+  andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) );
+  movptr(Address(boxReg, 0), tmpReg);
+  if (counters != NULL) {
+    cond_inc32(Assembler::equal,
+               ExternalAddress((address)counters->fast_path_entry_count_addr()));
+  }
+  jmp(DONE_LABEL);
+
+  bind(IsInflated);
+  // The object is inflated. tmpReg contains pointer to ObjectMonitor* + markOopDesc::monitor_value
 
 #if INCLUDE_RTM_OPT
-    // Use the same RTM locking code in 32- and 64-bit VM.
-    if (use_rtm) {
-      rtm_inflated_locking(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg,
-                           rtm_counters, method_data, profile_rtm, DONE_LABEL);
-    } else {
+  // Use the same RTM locking code in 32- and 64-bit VM.
+  if (use_rtm) {
+    rtm_inflated_locking(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg,
+                         rtm_counters, method_data, profile_rtm, DONE_LABEL);
+  } else {
 #endif // INCLUDE_RTM_OPT
 
 #ifndef _LP64
-    // The object is inflated.
-
-    // boxReg refers to the on-stack BasicLock in the current frame.
-    // We'd like to write:
-    //   set box->_displaced_header = markOopDesc::unused_mark().  Any non-0 value suffices.
-    // This is convenient but results a ST-before-CAS penalty.  The following CAS suffers
-    // additional latency as we have another ST in the store buffer that must drain.
-
-    if (EmitSync & 8192) {
-       movptr(Address(boxReg, 0), 3);            // results in ST-before-CAS penalty
-       get_thread (scrReg);
-       movptr(boxReg, tmpReg);                    // consider: LEA box, [tmp-2]
-       movptr(tmpReg, NULL_WORD);                 // consider: xor vs mov
-       if (os::is_MP()) {
-         lock();
-       }
-       cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-    } else
-    if ((EmitSync & 128) == 0) {                      // avoid ST-before-CAS
-       // register juggle because we need tmpReg for cmpxchgptr below
-       movptr(scrReg, boxReg);
-       movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
-
-       // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
-       if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
-          // prefetchw [eax + Offset(_owner)-2]
-          prefetchw(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-       }
-
-       if ((EmitSync & 64) == 0) {
-         // Optimistic form: consider XORL tmpReg,tmpReg
-         movptr(tmpReg, NULL_WORD);
-       } else {
-         // Can suffer RTS->RTO upgrades on shared or cold $ lines
-         // Test-And-CAS instead of CAS
-         movptr(tmpReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));   // rax, = m->_owner
-         testptr(tmpReg, tmpReg);                   // Locked ?
-         jccb  (Assembler::notZero, DONE_LABEL);
-       }
-
-       // Appears unlocked - try to swing _owner from null to non-null.
-       // Ideally, I'd manifest "Self" with get_thread and then attempt
-       // to CAS the register containing Self into m->Owner.
-       // But we don't have enough registers, so instead we can either try to CAS
-       // rsp or the address of the box (in scr) into &m->owner.  If the CAS succeeds
-       // we later store "Self" into m->Owner.  Transiently storing a stack address
-       // (rsp or the address of the box) into  m->owner is harmless.
-       // Invariant: tmpReg == 0.  tmpReg is EAX which is the implicit cmpxchg comparand.
-       if (os::is_MP()) {
-         lock();
-       }
-       cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-       movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
-       // If we weren't able to swing _owner from NULL to the BasicLock
-       // then take the slow path.
-       jccb  (Assembler::notZero, DONE_LABEL);
-       // update _owner from BasicLock to thread
-       get_thread (scrReg);                    // beware: clobbers ICCs
-       movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
-       xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
-
-       // If the CAS fails we can either retry or pass control to the slow-path.
-       // We use the latter tactic.
-       // Pass the CAS result in the icc.ZFlag into DONE_LABEL
-       // If the CAS was successful ...
-       //   Self has acquired the lock
-       //   Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
-       // Intentional fall-through into DONE_LABEL ...
-    } else {
-       movptr(Address(boxReg, 0), intptr_t(markOopDesc::unused_mark()));  // results in ST-before-CAS penalty
-       movptr(boxReg, tmpReg);
-
-       // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
-       if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
-          // prefetchw [eax + Offset(_owner)-2]
-          prefetchw(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-       }
-
-       if ((EmitSync & 64) == 0) {
-         // Optimistic form
-         xorptr  (tmpReg, tmpReg);
-       } else {
-         // Can suffer RTS->RTO upgrades on shared or cold $ lines
-         movptr(tmpReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));   // rax, = m->_owner
-         testptr(tmpReg, tmpReg);                   // Locked ?
-         jccb  (Assembler::notZero, DONE_LABEL);
-       }
-
-       // Appears unlocked - try to swing _owner from null to non-null.
-       // Use either "Self" (in scr) or rsp as thread identity in _owner.
-       // Invariant: tmpReg == 0.  tmpReg is EAX which is the implicit cmpxchg comparand.
-       get_thread (scrReg);
-       if (os::is_MP()) {
-         lock();
-       }
-       cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-
-       // If the CAS fails we can either retry or pass control to the slow-path.
-       // We use the latter tactic.
-       // Pass the CAS result in the icc.ZFlag into DONE_LABEL
-       // If the CAS was successful ...
-       //   Self has acquired the lock
-       //   Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
-       // Intentional fall-through into DONE_LABEL ...
-    }
+  // The object is inflated.
+
+  // boxReg refers to the on-stack BasicLock in the current frame.
+  // We'd like to write:
+  //   set box->_displaced_header = markOopDesc::unused_mark().  Any non-0 value suffices.
+  // This is convenient but results a ST-before-CAS penalty.  The following CAS suffers
+  // additional latency as we have another ST in the store buffer that must drain.
+
+  // avoid ST-before-CAS
+  // register juggle because we need tmpReg for cmpxchgptr below
+  movptr(scrReg, boxReg);
+  movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
+
+  // Optimistic form: consider XORL tmpReg,tmpReg
+  movptr(tmpReg, NULL_WORD);
+
+  // Appears unlocked - try to swing _owner from null to non-null.
+  // Ideally, I'd manifest "Self" with get_thread and then attempt
+  // to CAS the register containing Self into m->Owner.
+  // But we don't have enough registers, so instead we can either try to CAS
+  // rsp or the address of the box (in scr) into &m->owner.  If the CAS succeeds
+  // we later store "Self" into m->Owner.  Transiently storing a stack address
+  // (rsp or the address of the box) into  m->owner is harmless.
+  // Invariant: tmpReg == 0.  tmpReg is EAX which is the implicit cmpxchg comparand.
+  if (os::is_MP()) {
+    lock();
+  }
+  cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+  movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
+  // If we weren't able to swing _owner from NULL to the BasicLock
+  // then take the slow path.
+  jccb  (Assembler::notZero, DONE_LABEL);
+  // update _owner from BasicLock to thread
+  get_thread (scrReg);                    // beware: clobbers ICCs
+  movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
+  xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
+
+  // If the CAS fails we can either retry or pass control to the slow-path.
+  // We use the latter tactic.
+  // Pass the CAS result in the icc.ZFlag into DONE_LABEL
+  // If the CAS was successful ...
+  //   Self has acquired the lock
+  //   Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
+  // Intentional fall-through into DONE_LABEL ...
 #else // _LP64
-    // It's inflated
-    movq(scrReg, tmpReg);
-    xorq(tmpReg, tmpReg);
-
-    if (os::is_MP()) {
-      lock();
-    }
-    cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-    // Unconditionally set box->_displaced_header = markOopDesc::unused_mark().
-    // Without cast to int32_t movptr will destroy r10 which is typically obj.
-    movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark()));
-    // Intentional fall-through into DONE_LABEL ...
-    // Propagate ICC.ZF from CAS above into DONE_LABEL.
+  // It's inflated
+  movq(scrReg, tmpReg);
+  xorq(tmpReg, tmpReg);
+
+  if (os::is_MP()) {
+    lock();
+  }
+  cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+  // Unconditionally set box->_displaced_header = markOopDesc::unused_mark().
+  // Without cast to int32_t movptr will destroy r10 which is typically obj.
+  movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark()));
+  // Intentional fall-through into DONE_LABEL ...
+  // Propagate ICC.ZF from CAS above into DONE_LABEL.
 #endif // _LP64
 #if INCLUDE_RTM_OPT
-    } // use_rtm()
+  } // use_rtm()
 #endif
-    // DONE_LABEL is a hot target - we'd really like to place it at the
-    // start of cache line by padding with NOPs.
-    // See the AMD and Intel software optimization manuals for the
-    // most efficient "long" NOP encodings.
-    // Unfortunately none of our alignment mechanisms suffice.
-    bind(DONE_LABEL);
-
-    // At DONE_LABEL the icc ZFlag is set as follows ...
-    // Fast_Unlock uses the same protocol.
-    // ZFlag == 1 -> Success
-    // ZFlag == 0 -> Failure - force control through the slow-path
-  }
+  // DONE_LABEL is a hot target - we'd really like to place it at the
+  // start of cache line by padding with NOPs.
+  // See the AMD and Intel software optimization manuals for the
+  // most efficient "long" NOP encodings.
+  // Unfortunately none of our alignment mechanisms suffice.
+  bind(DONE_LABEL);
+
+  // At DONE_LABEL the icc ZFlag is set as follows ...
+  // Fast_Unlock uses the same protocol.
+  // ZFlag == 1 -> Success
+  // ZFlag == 0 -> Failure - force control through the slow-path
 }
 
 // obj: object to unlock
@@ -1980,293 +1913,179 @@
   assert(boxReg == rax, "");
   assert_different_registers(objReg, boxReg, tmpReg);
 
-  if (EmitSync & 4) {
-    // Disable - inhibit all inlining.  Force control through the slow-path
-    cmpptr (rsp, 0);
-  } else {
-    Label DONE_LABEL, Stacked, CheckSucc;
-
-    // Critically, the biased locking test must have precedence over
-    // and appear before the (box->dhw == 0) recursive stack-lock test.
-    if (UseBiasedLocking && !UseOptoBiasInlining) {
-       biased_locking_exit(objReg, tmpReg, DONE_LABEL);
-    }
+  Label DONE_LABEL, Stacked, CheckSucc;
+
+  // Critically, the biased locking test must have precedence over
+  // and appear before the (box->dhw == 0) recursive stack-lock test.
+  if (UseBiasedLocking && !UseOptoBiasInlining) {
+    biased_locking_exit(objReg, tmpReg, DONE_LABEL);
+  }
 
 #if INCLUDE_RTM_OPT
-    if (UseRTMForStackLocks && use_rtm) {
-      assert(!UseBiasedLocking, "Biased locking is not supported with RTM locking");
-      Label L_regular_unlock;
-      movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));           // fetch markword
-      andptr(tmpReg, markOopDesc::biased_lock_mask_in_place); // look at 3 lock bits
-      cmpptr(tmpReg, markOopDesc::unlocked_value);            // bits = 001 unlocked
-      jccb(Assembler::notEqual, L_regular_unlock);  // if !HLE RegularLock
-      xend();                                       // otherwise end...
-      jmp(DONE_LABEL);                              // ... and we're done
-      bind(L_regular_unlock);
-    }
+  if (UseRTMForStackLocks && use_rtm) {
+    assert(!UseBiasedLocking, "Biased locking is not supported with RTM locking");
+    Label L_regular_unlock;
+    movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));           // fetch markword
+    andptr(tmpReg, markOopDesc::biased_lock_mask_in_place); // look at 3 lock bits
+    cmpptr(tmpReg, markOopDesc::unlocked_value);            // bits = 001 unlocked
+    jccb(Assembler::notEqual, L_regular_unlock);  // if !HLE RegularLock
+    xend();                                       // otherwise end...
+    jmp(DONE_LABEL);                              // ... and we're done
+    bind(L_regular_unlock);
+  }
 #endif
 
-    cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD); // Examine the displaced header
-    jcc   (Assembler::zero, DONE_LABEL);            // 0 indicates recursive stack-lock
-    movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));             // Examine the object's markword
-    testptr(tmpReg, markOopDesc::monitor_value);    // Inflated?
-    jccb  (Assembler::zero, Stacked);
-
-    // It's inflated.
+  cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD); // Examine the displaced header
+  jcc   (Assembler::zero, DONE_LABEL);            // 0 indicates recursive stack-lock
+  movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes()));             // Examine the object's markword
+  testptr(tmpReg, markOopDesc::monitor_value);    // Inflated?
+  jccb  (Assembler::zero, Stacked);
+
+  // It's inflated.
 #if INCLUDE_RTM_OPT
-    if (use_rtm) {
-      Label L_regular_inflated_unlock;
-      int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
-      movptr(boxReg, Address(tmpReg, owner_offset));
-      testptr(boxReg, boxReg);
-      jccb(Assembler::notZero, L_regular_inflated_unlock);
-      xend();
-      jmpb(DONE_LABEL);
-      bind(L_regular_inflated_unlock);
-    }
+  if (use_rtm) {
+    Label L_regular_inflated_unlock;
+    int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
+    movptr(boxReg, Address(tmpReg, owner_offset));
+    testptr(boxReg, boxReg);
+    jccb(Assembler::notZero, L_regular_inflated_unlock);
+    xend();
+    jmpb(DONE_LABEL);
+    bind(L_regular_inflated_unlock);
+  }
 #endif
 
-    // Despite our balanced locking property we still check that m->_owner == Self
-    // as java routines or native JNI code called by this thread might
-    // have released the lock.
-    // Refer to the comments in synchronizer.cpp for how we might encode extra
-    // state in _succ so we can avoid fetching EntryList|cxq.
-    //
-    // I'd like to add more cases in fast_lock() and fast_unlock() --
-    // such as recursive enter and exit -- but we have to be wary of
-    // I$ bloat, T$ effects and BP$ effects.
-    //
-    // If there's no contention try a 1-0 exit.  That is, exit without
-    // a costly MEMBAR or CAS.  See synchronizer.cpp for details on how
-    // we detect and recover from the race that the 1-0 exit admits.
-    //
-    // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier
-    // before it STs null into _owner, releasing the lock.  Updates
-    // to data protected by the critical section must be visible before
-    // we drop the lock (and thus before any other thread could acquire
-    // the lock and observe the fields protected by the lock).
-    // IA32's memory-model is SPO, so STs are ordered with respect to
-    // each other and there's no need for an explicit barrier (fence).
-    // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
+  // Despite our balanced locking property we still check that m->_owner == Self
+  // as java routines or native JNI code called by this thread might
+  // have released the lock.
+  // Refer to the comments in synchronizer.cpp for how we might encode extra
+  // state in _succ so we can avoid fetching EntryList|cxq.
+  //
+  // I'd like to add more cases in fast_lock() and fast_unlock() --
+  // such as recursive enter and exit -- but we have to be wary of
+  // I$ bloat, T$ effects and BP$ effects.
+  //
+  // If there's no contention try a 1-0 exit.  That is, exit without
+  // a costly MEMBAR or CAS.  See synchronizer.cpp for details on how
+  // we detect and recover from the race that the 1-0 exit admits.
+  //
+  // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier
+  // before it STs null into _owner, releasing the lock.  Updates
+  // to data protected by the critical section must be visible before
+  // we drop the lock (and thus before any other thread could acquire
+  // the lock and observe the fields protected by the lock).
+  // IA32's memory-model is SPO, so STs are ordered with respect to
+  // each other and there's no need for an explicit barrier (fence).
+  // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
 #ifndef _LP64
-    get_thread (boxReg);
-    if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
-      // prefetchw [ebx + Offset(_owner)-2]
-      prefetchw(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-    }
-
-    // Note that we could employ various encoding schemes to reduce
-    // the number of loads below (currently 4) to just 2 or 3.
-    // Refer to the comments in synchronizer.cpp.
-    // In practice the chain of fetches doesn't seem to impact performance, however.
-    xorptr(boxReg, boxReg);
-    if ((EmitSync & 65536) == 0 && (EmitSync & 256)) {
-       // Attempt to reduce branch density - AMD's branch predictor.
-       orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
-       orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
-       orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
-       jccb  (Assembler::notZero, DONE_LABEL);
-       movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
-       jmpb  (DONE_LABEL);
-    } else {
-       orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
-       jccb  (Assembler::notZero, DONE_LABEL);
-       movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
-       orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
-       jccb  (Assembler::notZero, CheckSucc);
-       movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
-       jmpb  (DONE_LABEL);
-    }
-
-    // The Following code fragment (EmitSync & 65536) improves the performance of
-    // contended applications and contended synchronization microbenchmarks.
-    // Unfortunately the emission of the code - even though not executed - causes regressions
-    // in scimark and jetstream, evidently because of $ effects.  Replacing the code
-    // with an equal number of never-executed NOPs results in the same regression.
-    // We leave it off by default.
-
-    if ((EmitSync & 65536) != 0) {
-       Label LSuccess, LGoSlowPath ;
-
-       bind  (CheckSucc);
-
-       // Optional pre-test ... it's safe to elide this
-       cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
-       jccb(Assembler::zero, LGoSlowPath);
-
-       // We have a classic Dekker-style idiom:
-       //    ST m->_owner = 0 ; MEMBAR; LD m->_succ
-       // There are a number of ways to implement the barrier:
-       // (1) lock:andl &m->_owner, 0
-       //     is fast, but mask doesn't currently support the "ANDL M,IMM32" form.
-       //     LOCK: ANDL [ebx+Offset(_Owner)-2], 0
-       //     Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8
-       // (2) If supported, an explicit MFENCE is appealing.
-       //     In older IA32 processors MFENCE is slower than lock:add or xchg
-       //     particularly if the write-buffer is full as might be the case if
-       //     if stores closely precede the fence or fence-equivalent instruction.
-       //     See https://blogs.oracle.com/dave/entry/instruction_selection_for_volatile_fences
-       //     as the situation has changed with Nehalem and Shanghai.
-       // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack
-       //     The $lines underlying the top-of-stack should be in M-state.
-       //     The locked add instruction is serializing, of course.
-       // (4) Use xchg, which is serializing
-       //     mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works
-       // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0.
-       //     The integer condition codes will tell us if succ was 0.
-       //     Since _succ and _owner should reside in the same $line and
-       //     we just stored into _owner, it's likely that the $line
-       //     remains in M-state for the lock:orl.
-       //
-       // We currently use (3), although it's likely that switching to (2)
-       // is correct for the future.
-
-       movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
-       if (os::is_MP()) {
-         lock(); addptr(Address(rsp, 0), 0);
-       }
-       // Ratify _succ remains non-null
-       cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), 0);
-       jccb  (Assembler::notZero, LSuccess);
-
-       xorptr(boxReg, boxReg);                  // box is really EAX
-       if (os::is_MP()) { lock(); }
-       cmpxchgptr(rsp, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-       // There's no successor so we tried to regrab the lock with the
-       // placeholder value. If that didn't work, then another thread
-       // grabbed the lock so we're done (and exit was a success).
-       jccb  (Assembler::notEqual, LSuccess);
-       // Since we're low on registers we installed rsp as a placeholding in _owner.
-       // Now install Self over rsp.  This is safe as we're transitioning from
-       // non-null to non=null
-       get_thread (boxReg);
-       movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), boxReg);
-       // Intentional fall-through into LGoSlowPath ...
-
-       bind  (LGoSlowPath);
-       orptr(boxReg, 1);                      // set ICC.ZF=0 to indicate failure
-       jmpb  (DONE_LABEL);
-
-       bind  (LSuccess);
-       xorptr(boxReg, boxReg);                 // set ICC.ZF=1 to indicate success
-       jmpb  (DONE_LABEL);
-    }
-
-    bind (Stacked);
-    // It's not inflated and it's not recursively stack-locked and it's not biased.
-    // It must be stack-locked.
-    // Try to reset the header to displaced header.
-    // The "box" value on the stack is stable, so we can reload
-    // and be assured we observe the same value as above.
-    movptr(tmpReg, Address(boxReg, 0));
-    if (os::is_MP()) {
-      lock();
-    }
-    cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
-    // Intention fall-thru into DONE_LABEL
-
-    // DONE_LABEL is a hot target - we'd really like to place it at the
-    // start of cache line by padding with NOPs.
-    // See the AMD and Intel software optimization manuals for the
-    // most efficient "long" NOP encodings.
-    // Unfortunately none of our alignment mechanisms suffice.
-    if ((EmitSync & 65536) == 0) {
-       bind (CheckSucc);
-    }
+  get_thread (boxReg);
+
+  // Note that we could employ various encoding schemes to reduce
+  // the number of loads below (currently 4) to just 2 or 3.
+  // Refer to the comments in synchronizer.cpp.
+  // In practice the chain of fetches doesn't seem to impact performance, however.
+  xorptr(boxReg, boxReg);
+  orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
+  jccb  (Assembler::notZero, DONE_LABEL);
+  movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
+  orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
+  jccb  (Assembler::notZero, CheckSucc);
+  movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), NULL_WORD);
+  jmpb  (DONE_LABEL);
+
+  bind (Stacked);
+  // It's not inflated and it's not recursively stack-locked and it's not biased.
+  // It must be stack-locked.
+  // Try to reset the header to displaced header.
+  // The "box" value on the stack is stable, so we can reload
+  // and be assured we observe the same value as above.
+  movptr(tmpReg, Address(boxReg, 0));
+  if (os::is_MP()) {
+    lock();
+  }
+  cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
+  // Intention fall-thru into DONE_LABEL
+
+  // DONE_LABEL is a hot target - we'd really like to place it at the
+  // start of cache line by padding with NOPs.
+  // See the AMD and Intel software optimization manuals for the
+  // most efficient "long" NOP encodings.
+  // Unfortunately none of our alignment mechanisms suffice.
+  bind (CheckSucc);
 #else // _LP64
-    // It's inflated
-    if (EmitSync & 1024) {
-      // Emit code to check that _owner == Self
-      // We could fold the _owner test into subsequent code more efficiently
-      // than using a stand-alone check, but since _owner checking is off by
-      // default we don't bother. We also might consider predicating the
-      // _owner==Self check on Xcheck:jni or running on a debug build.
-      movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-      xorptr(boxReg, r15_thread);
-    } else {
-      xorptr(boxReg, boxReg);
-    }
-    orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
-    jccb  (Assembler::notZero, DONE_LABEL);
-    movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
-    orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
-    jccb  (Assembler::notZero, CheckSucc);
-    movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
-    jmpb  (DONE_LABEL);
-
-    if ((EmitSync & 65536) == 0) {
-      // Try to avoid passing control into the slow_path ...
-      Label LSuccess, LGoSlowPath ;
-      bind  (CheckSucc);
-
-      // The following optional optimization can be elided if necessary
-      // Effectively: if (succ == null) goto SlowPath
-      // The code reduces the window for a race, however,
-      // and thus benefits performance.
-      cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
-      jccb  (Assembler::zero, LGoSlowPath);
-
-      xorptr(boxReg, boxReg);
-      if ((EmitSync & 16) && os::is_MP()) {
-        xchgptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-      } else {
-        movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
-        if (os::is_MP()) {
-          // Memory barrier/fence
-          // Dekker pivot point -- fulcrum : ST Owner; MEMBAR; LD Succ
-          // Instead of MFENCE we use a dummy locked add of 0 to the top-of-stack.
-          // This is faster on Nehalem and AMD Shanghai/Barcelona.
-          // See https://blogs.oracle.com/dave/entry/instruction_selection_for_volatile_fences
-          // We might also restructure (ST Owner=0;barrier;LD _Succ) to
-          // (mov box,0; xchgq box, &m->Owner; LD _succ) .
-          lock(); addl(Address(rsp, 0), 0);
-        }
-      }
-      cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
-      jccb  (Assembler::notZero, LSuccess);
-
-      // Rare inopportune interleaving - race.
-      // The successor vanished in the small window above.
-      // The lock is contended -- (cxq|EntryList) != null -- and there's no apparent successor.
-      // We need to ensure progress and succession.
-      // Try to reacquire the lock.
-      // If that fails then the new owner is responsible for succession and this
-      // thread needs to take no further action and can exit via the fast path (success).
-      // If the re-acquire succeeds then pass control into the slow path.
-      // As implemented, this latter mode is horrible because we generated more
-      // coherence traffic on the lock *and* artifically extended the critical section
-      // length while by virtue of passing control into the slow path.
-
-      // box is really RAX -- the following CMPXCHG depends on that binding
-      // cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
-      if (os::is_MP()) { lock(); }
-      cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
-      // There's no successor so we tried to regrab the lock.
-      // If that didn't work, then another thread grabbed the
-      // lock so we're done (and exit was a success).
-      jccb  (Assembler::notEqual, LSuccess);
-      // Intentional fall-through into slow-path
-
-      bind  (LGoSlowPath);
-      orl   (boxReg, 1);                      // set ICC.ZF=0 to indicate failure
-      jmpb  (DONE_LABEL);
-
-      bind  (LSuccess);
-      testl (boxReg, 0);                      // set ICC.ZF=1 to indicate success
-      jmpb  (DONE_LABEL);
-    }
-
-    bind  (Stacked);
-    movptr(tmpReg, Address (boxReg, 0));      // re-fetch
-    if (os::is_MP()) { lock(); }
-    cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
-
-    if (EmitSync & 65536) {
-       bind (CheckSucc);
-    }
+  // It's inflated
+  xorptr(boxReg, boxReg);
+  orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
+  jccb  (Assembler::notZero, DONE_LABEL);
+  movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)));
+  orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)));
+  jccb  (Assembler::notZero, CheckSucc);
+  movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
+  jmpb  (DONE_LABEL);
+
+  // Try to avoid passing control into the slow_path ...
+  Label LSuccess, LGoSlowPath ;
+  bind  (CheckSucc);
+
+  // The following optional optimization can be elided if necessary
+  // Effectively: if (succ == null) goto SlowPath
+  // The code reduces the window for a race, however,
+  // and thus benefits performance.
+  cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
+  jccb  (Assembler::zero, LGoSlowPath);
+
+  xorptr(boxReg, boxReg);
+  movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD);
+  if (os::is_MP()) {
+    // Memory barrier/fence
+    // Dekker pivot point -- fulcrum : ST Owner; MEMBAR; LD Succ
+    // Instead of MFENCE we use a dummy locked add of 0 to the top-of-stack.
+    // This is faster on Nehalem and AMD Shanghai/Barcelona.
+    // See https://blogs.oracle.com/dave/entry/instruction_selection_for_volatile_fences
+    // We might also restructure (ST Owner=0;barrier;LD _Succ) to
+    // (mov box,0; xchgq box, &m->Owner; LD _succ) .
+    lock(); addl(Address(rsp, 0), 0);
+  }
+  cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD);
+  jccb  (Assembler::notZero, LSuccess);
+
+  // Rare inopportune interleaving - race.
+  // The successor vanished in the small window above.
+  // The lock is contended -- (cxq|EntryList) != null -- and there's no apparent successor.
+  // We need to ensure progress and succession.
+  // Try to reacquire the lock.
+  // If that fails then the new owner is responsible for succession and this
+  // thread needs to take no further action and can exit via the fast path (success).
+  // If the re-acquire succeeds then pass control into the slow path.
+  // As implemented, this latter mode is horrible because we generated more
+  // coherence traffic on the lock *and* artifically extended the critical section
+  // length while by virtue of passing control into the slow path.
+
+  // box is really RAX -- the following CMPXCHG depends on that binding
+  // cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
+  if (os::is_MP()) { lock(); }
+  cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
+  // There's no successor so we tried to regrab the lock.
+  // If that didn't work, then another thread grabbed the
+  // lock so we're done (and exit was a success).
+  jccb  (Assembler::notEqual, LSuccess);
+  // Intentional fall-through into slow-path
+
+  bind  (LGoSlowPath);
+  orl   (boxReg, 1);                      // set ICC.ZF=0 to indicate failure
+  jmpb  (DONE_LABEL);
+
+  bind  (LSuccess);
+  testl (boxReg, 0);                      // set ICC.ZF=1 to indicate success
+  jmpb  (DONE_LABEL);
+
+  bind  (Stacked);
+  movptr(tmpReg, Address (boxReg, 0));      // re-fetch
+  if (os::is_MP()) { lock(); }
+  cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
+
 #endif
-    bind(DONE_LABEL);
-  }
+  bind(DONE_LABEL);
 }
 #endif // COMPILER2
 
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -3218,7 +3218,7 @@
 void LIRGenerator::do_ProfileCall(ProfileCall* x) {
   // Need recv in a temporary register so it interferes with the other temporaries
   LIR_Opr recv = LIR_OprFact::illegalOpr;
-  LIR_Opr mdo = new_register(T_OBJECT);
+  LIR_Opr mdo = new_register(T_METADATA);
   // tmp is used to hold the counters on SPARC
   LIR_Opr tmp = new_pointer_register();
 
--- a/src/hotspot/share/ci/ciMethodData.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/ci/ciMethodData.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -187,8 +187,13 @@
   for (uint row = 0; row < row_limit(); row++) {
     Klass* k = data->as_ReceiverTypeData()->receiver(row);
     if (k != NULL) {
-      ciKlass* klass = CURRENT_ENV->get_klass(k);
-      set_receiver(row, klass);
+      if (k->is_loader_alive()) {
+        ciKlass* klass = CURRENT_ENV->get_klass(k);
+        set_receiver(row, klass);
+      } else {
+        // With concurrent class unloading, the MDO could have stale metadata; override it
+        clear_row(row);
+      }
     }
   }
 }
--- a/src/hotspot/share/classfile/classListParser.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classListParser.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -273,9 +273,9 @@
 // This function is used for loading classes for customized class loaders
 // during archive dumping.
 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) {
-#if !(defined(_LP64) && (defined(LINUX)|| defined(SOLARIS)))
-  // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit
-  //
+#if !(defined(_LP64) && (defined(LINUX)|| defined(SOLARIS) || defined(__APPLE__)))
+  // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and
+  // (3) MacOSX/64-bit
   // This #if condition should be in sync with the areCustomLoadersSupportedForCDS
   // method in test/lib/jdk/test/lib/Platform.java.
   error("AppCDS custom class loaders not supported on this platform");
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -157,6 +157,7 @@
   if (!h_class_loader.is_null()) {
     _class_loader = _handles.add(h_class_loader());
     _class_loader_klass = h_class_loader->klass();
+    initialize_name(h_class_loader);
   }
 
   if (!is_unsafe_anonymous) {
@@ -671,6 +672,15 @@
   }
 }
 
+// Let the GC read the holder without keeping it alive.
+oop ClassLoaderData::holder_no_keepalive() const {
+  if (!_holder.is_null()) {  // NULL class_loader
+    return _holder.peek();
+  } else {
+    return NULL;
+  }
+}
+
 // Unloading support
 bool ClassLoaderData::is_alive() const {
   bool alive = keep_alive()         // null class loader and incomplete unsafe anonymous klasses.
@@ -1068,33 +1078,38 @@
 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
 ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsafe_anonymous) {
 
+  assert_lock_strong(ClassLoaderDataGraph_lock);
 
   ClassLoaderData* cld;
-  {
-    NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
-                                       // ClassLoaderData in the loader since the CLD
-                                       // contains oops in _handles that must be walked.
-                                       // GC will find the CLD through the loader after this.
 
-    cld = new ClassLoaderData(loader, is_unsafe_anonymous);
-
-    if (!is_unsafe_anonymous) {
-      // First, Atomically set it
-      ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
-      if (old != NULL) {
-        delete cld;
-        // Returns the data.
-        return old;
-      }
+  // First check if another thread beat us to creating the CLD and installing
+  // it into the loader while we were waiting for the lock.
+  if (!is_unsafe_anonymous && loader.not_null()) {
+    cld = java_lang_ClassLoader::loader_data_acquire(loader());
+    if (cld != NULL) {
+      return cld;
     }
   }
 
-  MutexLocker ml(ClassLoaderDataGraph_lock);
+  // We mustn't GC until we've installed the ClassLoaderData in the Graph since the CLD
+  // contains oops in _handles that must be walked.  GC doesn't walk CLD from the
+  // loader oop in all collections, particularly young collections.
+  NoSafepointVerifier no_safepoints;
 
-  // We won the race, and therefore the task of adding the data to the list of
-  // class loader data
+  cld = new ClassLoaderData(loader, is_unsafe_anonymous);
+
+  // First install the new CLD to the Graph.
   cld->set_next(_head);
   _head = cld;
+
+  // Next associate with the class_loader.
+  if (!is_unsafe_anonymous) {
+    // Use OrderAccess, since readers need to get the loader_data only after
+    // it's added to the Graph
+    java_lang_ClassLoader::release_set_loader_data(loader(), cld);
+  }
+
+  // Lastly log, if requested
   LogTarget(Trace, class, loader, data) lt;
   if (lt.is_enabled()) {
     ResourceMark rm;
@@ -1107,12 +1122,8 @@
 }
 
 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymous) {
+  MutexLocker ml(ClassLoaderDataGraph_lock);
   ClassLoaderData* loader_data = add_to_graph(loader, is_unsafe_anonymous);
-  // Initialize _name and _name_and_id after the loader data is added to the
-  // CLDG because adding the Symbol for _name and _name_and_id might safepoint.
-  if (loader.not_null()) {
-    loader_data->initialize_name(loader);
-  }
   return loader_data;
 }
 
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -307,8 +307,9 @@
   void accumulate_modified_oops()        { if (has_modified_oops()) _accumulated_modified_oops = true; }
   void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
   bool has_accumulated_modified_oops()   { return _accumulated_modified_oops; }
+  oop holder_no_keepalive() const;
+
  private:
-
   void unload();
   bool keep_alive() const       { return _keep_alive > 0; }
 
@@ -336,6 +337,8 @@
   bool claimed() const { return _claimed == 1; }
   bool claim();
 
+  // Computes if the CLD is alive or not. This is safe to call in concurrent
+  // contexts.
   bool is_alive() const;
 
   // Accessors
@@ -377,6 +380,9 @@
   inline oop class_loader() const;
 
   // Returns true if this class loader data is for a loader going away.
+  // Note that this is only safe after the GC has computed if the CLD is
+  // unloading or not. In concurrent contexts where there are no such
+  // guarantees, is_alive() should be used instead.
   bool is_unloading() const     {
     assert(!(is_the_null_class_loader_data() && _unloading), "The null class loader can never be unloaded");
     return _unloading;
--- a/src/hotspot/share/classfile/classLoaderData.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -34,7 +34,7 @@
 
 inline oop ClassLoaderData::class_loader() const {
   assert(!_unloading, "This oop is not available to unloading class loader data");
-  assert(_holder.is_null() || _holder.peek() != NULL , "This class loader data holder must be alive");
+  assert(_holder.is_null() || holder_no_keepalive() != NULL , "This class loader data holder must be alive");
   return _class_loader.resolve();
 }
 
@@ -46,7 +46,7 @@
   if (loader == NULL) {
     return ClassLoaderData::the_null_class_loader_data();
   }
-  return java_lang_ClassLoader::loader_data(loader);
+  return java_lang_ClassLoader::loader_data_acquire(loader);
 }
 
 inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
@@ -60,7 +60,7 @@
   guarantee(loader() != NULL && oopDesc::is_oop(loader()), "Loader must be oop");
   // Gets the class loader data out of the java/lang/ClassLoader object, if non-null
   // it's already in the loader_data, so no need to add
-  ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data(loader());
+  ClassLoaderData* loader_data= java_lang_ClassLoader::loader_data_acquire(loader());
   if (loader_data) {
      return loader_data;
   }
--- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -470,7 +470,7 @@
   void do_cld (ClassLoaderData* cld) {
 
     // We do not display unloading loaders, for now.
-    if (cld->is_unloading()) {
+    if (!cld->is_alive()) {
       return;
     }
 
--- a/src/hotspot/share/classfile/classLoaderStats.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderStats.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -139,7 +139,7 @@
 
 
 void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
-  while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
+  while (cl != NULL && java_lang_ClassLoader::loader_data_acquire(cl) == NULL) {
     // This classloader has not loaded any classes
     ClassLoaderStats** cls_ptr = _stats->get(cl);
     if (cls_ptr == NULL) {
--- a/src/hotspot/share/classfile/compactHashtable.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/compactHashtable.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -282,7 +282,7 @@
   CompactHashtable_OopIterator(OopClosure *cl) : _closure(cl) {}
   inline void do_value(address base_address, u4 offset) const {
     narrowOop v = (narrowOop)offset;
-    oop obj = HeapShared::decode_with_archived_oop_encoding_mode(v);
+    oop obj = HeapShared::decode_from_archive(v);
     _closure->do_oop(&obj);
   }
 };
--- a/src/hotspot/share/classfile/compactHashtable.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/compactHashtable.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -48,7 +48,7 @@
 inline oop CompactHashtable<T, N>::decode_entry(CompactHashtable<oop, char>* const t,
                                                 u4 offset, const char* name, int len) {
   narrowOop v = (narrowOop)offset;
-  oop string = HeapShared::decode_with_archived_oop_encoding_mode(v);
+  oop string = HeapShared::decode_from_archive(v);
   if (java_lang_String::equals(string, (jchar*)name, len)) {
     return string;
   }
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1213,6 +1213,14 @@
 bool java_lang_Class::restore_archived_mirror(Klass *k,
                                               Handle class_loader, Handle module,
                                               Handle protection_domain, TRAPS) {
+  // Postpone restoring archived mirror until java.lang.Class is loaded. Please
+  // see more details in SystemDictionary::resolve_preloaded_classes().
+  if (!SystemDictionary::Class_klass_loaded()) {
+    assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
+    fixup_mirror_list()->push(k);
+    return true;
+  }
+
   oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
 
   if (m == NULL) {
@@ -1225,10 +1233,6 @@
   assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
   Handle mirror(THREAD, m);
 
-  // The java.lang.Class field offsets were archived and reloaded from archive.
-  // No need to put classes on the fixup_mirror_list before java.lang.Class
-  // is loaded.
-
   if (!k->is_array_klass()) {
     // - local static final fields with initial values were initialized at dump time
 
@@ -4023,9 +4027,9 @@
 int  java_lang_ClassLoader::nameAndId_offset = -1;
 int  java_lang_ClassLoader::unnamedModule_offset = -1;
 
-ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
+ClassLoaderData* java_lang_ClassLoader::loader_data_acquire(oop loader) {
   assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
-  return HeapAccess<>::load_at(loader, _loader_data_offset);
+  return HeapAccess<MO_ACQUIRE>::load_at(loader, _loader_data_offset);
 }
 
 ClassLoaderData* java_lang_ClassLoader::loader_data_raw(oop loader) {
@@ -4033,9 +4037,9 @@
   return RawAccess<>::load_at(loader, _loader_data_offset);
 }
 
-ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
+void java_lang_ClassLoader::release_set_loader_data(oop loader, ClassLoaderData* new_data) {
   assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
-  return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
+  HeapAccess<MO_RELEASE>::store_at(loader, _loader_data_offset, new_data);
 }
 
 #define CLASSLOADER_FIELDS_DO(macro) \
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1322,9 +1322,9 @@
   static void compute_offsets();
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
 
-  static ClassLoaderData* loader_data(oop loader);
+  static ClassLoaderData* loader_data_acquire(oop loader);
   static ClassLoaderData* loader_data_raw(oop loader);
-  static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
+  static void release_set_loader_data(oop loader, ClassLoaderData* new_data);
 
   static oop parent(oop loader);
   static oop name(oop loader);
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -2028,6 +2028,22 @@
 #if INCLUDE_CDS
   if (UseSharedSpaces) {
     resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Object_klass), scan, CHECK);
+
+    // It's unsafe to access the archived heap regions before they
+    // are fixed up, so we must do the fixup as early as possible
+    // before the archived java objects are accessed by functions
+    // such as java_lang_Class::restore_archived_mirror and
+    // ConstantPool::restore_unshareable_info (restores the archived
+    // resolved_references array object).
+    //
+    // MetaspaceShared::fixup_mapped_heap_regions() fills the empty
+    // spaces in the archived heap regions and may use
+    // SystemDictionary::Object_klass(), so we can do this only after
+    // Object_klass is resolved. See the above resolve_wk_klasses_through()
+    // call. No mirror objects are accessed/restored in the above call.
+    // Mirrors are restored after java.lang.Class is loaded.
+    MetaspaceShared::fixup_mapped_heap_regions();
+
     // Initialize the constant pool for the Object_class
     Object_klass()->constants()->restore_unshareable_info(CHECK);
     resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
--- a/src/hotspot/share/classfile/verifier.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/verifier.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -130,7 +130,7 @@
   st->print_cr("End class verification for: %s", klassName);
 }
 
-bool Verifier::verify(InstanceKlass* klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
+bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
   HandleMark hm(THREAD);
   ResourceMark rm(THREAD);
 
--- a/src/hotspot/share/classfile/verifier.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/classfile/verifier.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -42,16 +42,11 @@
     NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52,
     DYNAMICCONSTANT_MAJOR_VERSION       = 55
   };
-  typedef enum { ThrowException, NoException } Mode;
 
-  /**
-   * Verify the bytecodes for a class.  If 'throw_exception' is true
-   * then the appropriate VerifyError or ClassFormatError will be thrown.
-   * Otherwise, no exception is thrown and the return indicates the
-   * error.
-   */
+  // Verify the bytecodes for a class.
+  static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
+
   static void log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name, TRAPS);
-  static bool verify(InstanceKlass* klass, Mode mode, bool should_verify_class, TRAPS);
 
   // Return false if the class is loaded by the bootstrap loader,
   // or if defineClass was called requesting skipping verification
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1950,12 +1950,8 @@
 };
 
 size_t G1CollectedHeap::recalculate_used() const {
-  double recalculate_used_start = os::elapsedTime();
-
   SumUsedClosure blk;
   heap_region_iterate(&blk);
-
-  g1_policy()->phase_times()->record_evac_fail_recalc_used_time((os::elapsedTime() - recalculate_used_start) * 1000.0);
   return blk.result();
 }
 
@@ -3013,7 +3009,10 @@
         g1_policy()->phase_times()->record_start_new_cset_time_ms((os::elapsedTime() - start) * 1000.0);
 
         if (evacuation_failed()) {
+          double recalculate_used_start = os::elapsedTime();
           set_used(recalculate_used());
+          g1_policy()->phase_times()->record_evac_fail_recalc_used_time((os::elapsedTime() - recalculate_used_start) * 1000.0);
+
           if (_archive_allocator != NULL) {
             _archive_allocator->clear_used();
           }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1385,11 +1385,7 @@
   void print_cset_rsets() PRODUCT_RETURN;
   void print_all_rsets() PRODUCT_RETURN;
 
-public:
   size_t pending_card_num();
-
-private:
-  size_t _max_heap_capacity;
 };
 
 class G1ParEvacuateFollowersClosure : public VoidClosure {
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -54,8 +54,8 @@
   template <class T>
   inline void handle_non_cset_obj_common(InCSetState const state, T* p, oop const obj);
 public:
-  // This closure needs special handling for InstanceRefKlass.
-  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
+
   void set_region(HeapRegion* from) { _from = from; }
 
   inline void trim_queue_partially();
@@ -98,6 +98,9 @@
   virtual void do_oop(oop* p)          { do_oop_work(p); }
   virtual void do_oop(narrowOop* p)    { do_oop_work(p); }
 
+  // We need to do reference discovery while processing evacuated objects.
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
+
   void set_ref_discoverer(ReferenceDiscoverer* rd) {
     set_ref_discoverer_internal(rd);
   }
@@ -201,8 +204,7 @@
     _worker_i(worker_i) {
   }
 
-  // This closure needs special handling for InstanceRefKlass.
-  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
 
   template <class T> void do_oop_work(T* p);
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
@@ -219,8 +221,8 @@
   template <class T> void do_oop_work(T* p);
   virtual void do_oop(oop* p)       { do_oop_work(p); }
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-  // This closure needs special handling for InstanceRefKlass.
-  virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; }
+
+  virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
 };
 
 #endif // SHARE_VM_GC_G1_G1OOPCLOSURES_HPP
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -183,7 +183,7 @@
 void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
   InstanceKlass::oop_pc_follow_contents(obj, cm);
 
-  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
+  ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data_acquire(obj);
   if (loader_data != NULL) {
     cm->follow_class_loader(loader_data);
   }
--- a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -321,7 +321,7 @@
       __ cmp(lir_cond_equal, base.result(), LIR_OprFact::oopConst(NULL));
       __ branch(lir_cond_equal, T_OBJECT, cont->label());
     }
-    LIR_Opr src_klass = gen->new_register(T_OBJECT);
+    LIR_Opr src_klass = gen->new_register(T_METADATA);
     if (gen_type_check) {
       // We have determined that offset == referent_offset && src != null.
       // if (src->_klass->_reference_type == REF_NONE) -> continue
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -190,6 +190,8 @@
 
   virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const;
 
+  virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; }
+
   // These are general helper methods used by C2
   virtual bool array_copy_requires_gc_barriers(BasicType type) const { return false; }
 
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -466,9 +466,9 @@
 
   bool do_entry(oop const& key, ClassLoaderStats* const& cls) {
     const ClassLoaderData* this_cld = cls->_class_loader != NULL ?
-      java_lang_ClassLoader::loader_data(cls->_class_loader) : (ClassLoaderData*)NULL;
+      java_lang_ClassLoader::loader_data_acquire(cls->_class_loader) : NULL;
     const ClassLoaderData* parent_cld = cls->_parent != NULL ?
-      java_lang_ClassLoader::loader_data(cls->_parent) : (ClassLoaderData*)NULL;
+      java_lang_ClassLoader::loader_data_acquire(cls->_parent) : NULL;
     EventClassLoaderStatistics event;
     event.set_classLoader(this_cld);
     event.set_parentClassLoader(parent_cld);
--- a/src/hotspot/share/memory/filemap.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -854,7 +854,7 @@
   if (with_current_oop_encoding_mode) {
     return (address)CompressedOops::decode_not_null(offset_of_space(spc));
   } else {
-    return (address)HeapShared::decode_with_archived_oop_encoding_mode(offset_of_space(spc));
+    return (address)HeapShared::decode_from_archive(offset_of_space(spc));
   }
 }
 
@@ -880,7 +880,7 @@
     CDSFileMapRegion* si = space_at(i);
     size_t size = si->_used;
     if (size > 0) {
-      address s = start_address_with_current_oop_encoding_mode(si);
+      address s = start_address_as_decoded_with_current_oop_encoding_mode(si);
       address e = s + size;
       if (start > s) {
         start = s;
@@ -972,21 +972,20 @@
   HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift());
 
   CDSFileMapRegion* si = space_at(MetaspaceShared::first_string);
-  address relocated_strings_bottom = start_address_with_archived_oop_encoding_mode(si);
-  if (!is_aligned(relocated_strings_bottom + delta, HeapRegion::GrainBytes)) {
+  address relocated_strings_bottom = start_address_as_decoded_from_archive(si);
+  if (!is_aligned(relocated_strings_bottom, HeapRegion::GrainBytes)) {
     // Align the bottom of the string regions at G1 region boundary. This will avoid
     // the situation where the highest open region and the lowest string region sharing
     // the same G1 region. Otherwise we will fail to map the open regions.
     size_t align = size_t(relocated_strings_bottom) % HeapRegion::GrainBytes;
     delta -= align;
-    assert(is_aligned(relocated_strings_bottom + delta, HeapRegion::GrainBytes), "must be");
-
     log_info(cds)("CDS heap data need to be relocated lower by a further " SIZE_FORMAT
-                  " bytes to be aligned with HeapRegion::GrainBytes", align);
-
+                  " bytes to " INTX_FORMAT " to be aligned with HeapRegion::GrainBytes", align, delta);
     HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift());
     _heap_pointers_need_patching = true;
+    relocated_strings_bottom = start_address_as_decoded_from_archive(si);
   }
+  assert(is_aligned(relocated_strings_bottom, HeapRegion::GrainBytes), "must be");
 
   // First, map string regions as closed archive heap regions.
   // GC does not write into the regions.
@@ -1032,7 +1031,7 @@
     si = space_at(i);
     size_t size = si->_used;
     if (size > 0) {
-      HeapWord* start = (HeapWord*)start_address_with_archived_oop_encoding_mode(si);
+      HeapWord* start = (HeapWord*)start_address_as_decoded_from_archive(si);
       regions[region_num] = MemRegion(start, size / HeapWordSize);
       region_num ++;
       log_info(cds)("Trying to map heap data: region[%d] at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes",
@@ -1242,7 +1241,7 @@
   if (MetaspaceShared::is_heap_region(idx)) {
     assert(DumpSharedSpaces, "The following doesn't work at runtime");
     return si->_used > 0 ?
-          (char*)start_address_with_current_oop_encoding_mode(si) : NULL;
+          (char*)start_address_as_decoded_with_current_oop_encoding_mode(si) : NULL;
   } else {
     return si->_addr._base;
   }
--- a/src/hotspot/share/memory/filemap.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/filemap.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -335,12 +335,12 @@
   }
 
   // The starting address of spc, as calculated with CompressedOop::decode_non_null()
-  address start_address_with_current_oop_encoding_mode(CDSFileMapRegion* spc) {
+  address start_address_as_decoded_with_current_oop_encoding_mode(CDSFileMapRegion* spc) {
     return decode_start_address(spc, true);
   }
 
-  // The starting address of spc, as calculated with HeapShared::decode_with_archived_oop_encoding_mode()
-  address start_address_with_archived_oop_encoding_mode(CDSFileMapRegion* spc) {
+  // The starting address of spc, as calculated with HeapShared::decode_from_archive()
+  address start_address_as_decoded_from_archive(CDSFileMapRegion* spc) {
     return decode_start_address(spc, false);
   }
 
--- a/src/hotspot/share/memory/heapShared.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/heapShared.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -45,8 +45,6 @@
 int HeapShared::_num_archived_subgraph_info_records = 0;
 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;
 
-// Currently there is only one class mirror (ArchivedModuleGraph) with archived
-// sub-graphs.
 KlassSubGraphInfo* HeapShared::find_subgraph_info(Klass* k) {
   KlassSubGraphInfo* info = _subgraph_info_list;
   while (info != NULL) {
@@ -145,6 +143,13 @@
     return;
   }
 
+  if (log_is_enabled(Debug, cds, heap)) {
+    if (!_subgraph_object_klasses->contains(relocated_k)) {
+      ResourceMark rm;
+      log_debug(cds, heap)("Adding klass %s", orig_k->external_name());
+    }
+  }
+
   _subgraph_object_klasses->append_if_missing(relocated_k);
 }
 
@@ -153,7 +158,7 @@
   _k = info->klass();
   _next = NULL;
   _entry_field_records = NULL;
-  _subgraph_klasses = NULL;
+  _subgraph_object_klasses = NULL;
 
   // populate the entry fields
   GrowableArray<juint>* entry_fields = info->subgraph_entry_fields();
@@ -168,20 +173,20 @@
   }
 
   // the Klasses of the objects in the sub-graphs
-  GrowableArray<Klass*>* subgraph_klasses = info->subgraph_object_klasses();
-  if (subgraph_klasses != NULL) {
-    int num_subgraphs_klasses = subgraph_klasses->length();
-    _subgraph_klasses =
+  GrowableArray<Klass*>* subgraph_object_klasses = info->subgraph_object_klasses();
+  if (subgraph_object_klasses != NULL) {
+    int num_subgraphs_klasses = subgraph_object_klasses->length();
+    _subgraph_object_klasses =
       MetaspaceShared::new_ro_array<Klass*>(num_subgraphs_klasses);
     for (int i = 0; i < num_subgraphs_klasses; i++) {
-      Klass* subgraph_k = subgraph_klasses->at(i);
+      Klass* subgraph_k = subgraph_object_klasses->at(i);
       if (log_is_enabled(Info, cds, heap)) {
         ResourceMark rm;
         log_info(cds, heap)(
-          "Archived object klass (%d): %s in %s sub-graphs",
-          i, subgraph_k->external_name(), _k->external_name());
+          "Archived object klass %s (%2d) => %s",
+          _k->external_name(), i, subgraph_k->external_name());
       }
-      _subgraph_klasses->at_put(i, subgraph_k);
+      _subgraph_object_klasses->at_put(i, subgraph_k);
     }
   }
 }
@@ -194,8 +199,7 @@
 // - A list of klasses that need to be loaded/initialized before archived
 //   java object sub-graph can be accessed at runtime.
 //
-// The records are saved in the archive file and reloaded at runtime. Currently
-// there is only one class mirror (ArchivedModuleGraph) with archived sub-graphs.
+// The records are saved in the archive file and reloaded at runtime.
 //
 // Layout of the archived subgraph info records:
 //
@@ -273,9 +277,8 @@
     return; // no subgraph info records
   }
 
-  // Initialize from archived data. Currently only ArchivedModuleGraph
-  // has archived object subgraphs, which is used during VM initialization
-  // time when bootstraping the system modules. No lock is needed.
+  // Initialize from archived data. Currently this is done only
+  // during VM initialization time. No lock is needed.
   Thread* THREAD = Thread::current();
   for (int i = 0; i < _archived_subgraph_info_records->length(); i++) {
     ArchivedKlassSubGraphInfoRecord* record = _archived_subgraph_info_records->adr_at(i);
@@ -284,7 +287,7 @@
       // Found the archived subgraph info record for the requesting klass.
       // Load/link/initialize the klasses of the objects in the subgraph.
       // NULL class loader is used.
-      Array<Klass*>* klasses = record->subgraph_klasses();
+      Array<Klass*>* klasses = record->subgraph_object_klasses();
       if (klasses != NULL) {
         for (i = 0; i < klasses->length(); i++) {
           Klass* obj_k = klasses->at(i);
@@ -339,15 +342,19 @@
 
 class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
   int _level;
+  bool _record_klasses_only;
   KlassSubGraphInfo* _subgraph_info;
   oop _orig_referencing_obj;
   oop _archived_referencing_obj;
+  Thread* _thread;
  public:
-  WalkOopAndArchiveClosure(int level, KlassSubGraphInfo* subgraph_info,
-           oop orig, oop archived) : _level(level),
-                                     _subgraph_info(subgraph_info),
-                                     _orig_referencing_obj(orig),
-                                     _archived_referencing_obj(archived) {}
+  WalkOopAndArchiveClosure(int level, bool record_klasses_only,
+                           KlassSubGraphInfo* subgraph_info,
+                           oop orig, oop archived, TRAPS) :
+    _level(level), _record_klasses_only(record_klasses_only),
+    _subgraph_info(subgraph_info),
+    _orig_referencing_obj(orig), _archived_referencing_obj(archived),
+    _thread(THREAD) {}
   void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
   void do_oop(      oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); }
 
@@ -355,89 +362,105 @@
   template <class T> void do_oop_work(T *p) {
     oop obj = RawAccess<>::oop_load(p);
     if (!CompressedOops::is_null(obj)) {
-      // A java.lang.Class instance can not be included in an archived
-      // object sub-graph.
-      if (java_lang_Class::is_instance(obj)) {
-        log_error(cds, heap)("Unknown java.lang.Class object is in the archived sub-graph\n");
-        vm_exit(1);
+      assert(!MetaspaceShared::is_archive_object(obj),
+             "original objects must not point to archived objects");
+
+      size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char));
+      T* new_p = (T*)(address(_archived_referencing_obj) + field_delta);
+      Thread* THREAD = _thread;
+
+      if (!_record_klasses_only && log_is_enabled(Debug, cds, heap)) {
+        ResourceMark rm;
+        log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size %d %s", _level,
+                             _orig_referencing_obj->klass()->external_name(), field_delta,
+                             p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
+        LogTarget(Trace, cds, heap) log;
+        LogStream out(log);
+        obj->print_on(&out);
       }
 
-      LogTarget(Debug, cds, heap) log;
-      LogStream ls(log);
-      outputStream* out = &ls;
-      {
-        ResourceMark rm;
-        log.print("(%d) %s <--- referenced from:  %s",
-                  _level, obj->klass()->external_name(),
-                  CompressedOops::is_null(_orig_referencing_obj) ?
-                         "" : _orig_referencing_obj->klass()->external_name());
-        obj->print_on(out);
+      oop archived = HeapShared::archive_reachable_objects_from(_level + 1, _subgraph_info, obj, THREAD);
+      assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
+      assert(MetaspaceShared::is_archive_object(archived), "must be");
+
+      if (!_record_klasses_only) {
+        // Update the reference in the archived copy of the referencing object.
+        log_debug(cds, heap)("(%d) updating oop @[" PTR_FORMAT "] " PTR_FORMAT " ==> " PTR_FORMAT,
+                             _level, p2i(new_p), p2i(obj), p2i(archived));
+        RawAccess<IS_NOT_NULL>::oop_store(new_p, archived);
       }
-
-      if (MetaspaceShared::is_archive_object(obj)) {
-        // The current oop is an archived oop, nothing needs to be done
-        log.print("--- object is already archived ---");
-        return;
-      }
-
-      size_t field_delta = pointer_delta(
-        p, _orig_referencing_obj, sizeof(char));
-      T* new_p = (T*)(address(_archived_referencing_obj) + field_delta);
-      oop archived = MetaspaceShared::find_archived_heap_object(obj);
-      if (archived != NULL) {
-        // There is an archived copy existing, update reference to point
-        // to the archived copy
-        RawAccess<IS_NOT_NULL>::oop_store(new_p, archived);
-        log.print(
-          "--- found existing archived copy, store archived " PTR_FORMAT " in " PTR_FORMAT,
-          p2i(archived), p2i(new_p));
-        return;
-      }
-
-      int l = _level + 1;
-      Thread* THREAD = Thread::current();
-      // Archive the current oop before iterating through its references
-      archived = MetaspaceShared::archive_heap_object(obj, THREAD);
-      if (archived == NULL) {
-        ResourceMark rm;
-        LogTarget(Error, cds, heap) log_err;
-        LogStream ls_err(log_err);
-        outputStream* out_err = &ls_err;
-        log_err.print("Failed to archive %s object ("
-                      PTR_FORMAT "), size[" SIZE_FORMAT "] in sub-graph",
-                      obj->klass()->external_name(), p2i(obj), (size_t)obj->size());
-        obj->print_on(out_err);
-        vm_exit(1);
-      }
-      assert(MetaspaceShared::is_archive_object(archived), "must be archived");
-      log.print("=== archiving oop " PTR_FORMAT " ==> " PTR_FORMAT,
-                 p2i(obj), p2i(archived));
-
-      // Following the references in the current oop and archive any
-      // encountered objects during the process
-      WalkOopAndArchiveClosure walker(l, _subgraph_info, obj, archived);
-      obj->oop_iterate(&walker);
-
-      // Update the reference in the archived copy of the referencing object
-      RawAccess<IS_NOT_NULL>::oop_store(new_p, archived);
-      log.print("=== store archived " PTR_FORMAT " in " PTR_FORMAT,
-                p2i(archived), p2i(new_p));
-
-      // Add the klass to the list of classes that need to be loaded before
-      // module system initialization
-      Klass *orig_k = obj->klass();
-      Klass *relocated_k = archived->klass();
-      _subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
     }
   }
 };
 
+// (1) If orig_obj has not been archived yet, archive it.
+// (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
+//     trace all  objects that are reachable from it, and make sure these objects are archived.
+// (3) Record the klasses of all orig_obj and all reachable objects.
+oop HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj, TRAPS) {
+  assert(orig_obj != NULL, "must be");
+  assert(!MetaspaceShared::is_archive_object(orig_obj), "sanity");
+
+  // java.lang.Class instances cannot be included in an archived
+  // object sub-graph.
+  if (java_lang_Class::is_instance(orig_obj)) {
+    log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
+    vm_exit(1);
+  }
+
+  oop archived_obj = MetaspaceShared::find_archived_heap_object(orig_obj);
+  if (java_lang_String::is_instance(orig_obj) && archived_obj != NULL) {
+    // To save time, don't walk strings that are already archived. They just contain
+    // pointers to a type array, whose klass doesn't need to be recorded.
+    return archived_obj;
+  }
+
+  if (has_been_seen_during_subgraph_recording(orig_obj)) {
+    // orig_obj has already been archived and traced. Nothing more to do.
+    return archived_obj;
+  } else {
+    set_has_been_seen_during_subgraph_recording(orig_obj);
+  }
+
+  bool record_klasses_only = (archived_obj != NULL);
+  if (archived_obj == NULL) {
+    ++_num_new_archived_objs;
+    archived_obj = MetaspaceShared::archive_heap_object(orig_obj, THREAD);
+    if (archived_obj == NULL) {
+      // Skip archiving the sub-graph referenced from the current entry field.
+      ResourceMark rm;
+      log_error(cds, heap)(
+        "Cannot archive the sub-graph referenced from %s object ("
+        PTR_FORMAT ") size %d, skipped.",
+        orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize);
+      if (level == 1) {
+        // Don't archive a subgraph root that's too big. For archives static fields, that's OK
+        // as the Java code will take care of initializing this field dynamically.
+        return NULL;
+      } else {
+        // We don't know how to handle an object that has been archived, but some of its reachable
+        // objects cannot be archived. Bail out for now. We might need to fix this in the future if
+        // we have a real use case.
+        vm_exit(1);
+      }
+    }
+  }
+
+  assert(archived_obj != NULL, "must be");
+  Klass *orig_k = orig_obj->klass();
+  Klass *relocated_k = archived_obj->klass();
+  subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
+
+  WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj, archived_obj, THREAD);
+  orig_obj->oop_iterate(&walker);
+  return archived_obj;
+}
+
 //
 // Start from the given static field in a java mirror and archive the
 // complete sub-graph of java heap objects that are reached directly
 // or indirectly from the starting object by following references.
-// Currently, only ArchivedModuleGraph class instance (mirror) has archived
-// object subgraphs. Sub-graph archiving restrictions (current):
+// Sub-graph archiving restrictions (current):
 //
 // - All classes of objects in the archived sub-graph (including the
 //   entry class) must be boot class only.
@@ -461,20 +484,19 @@
 // archive the sub-graph of objects starting from each reference.
 //
 // 4) Updates the pointer in the archived copy of referencing object to
-//    point to the current archived object.
+// point to the current archived object.
 //
 // 5) The Klass of the current java object is added to the list of Klasses
 // for loading and initialzing before any object in the archived graph can
 // be accessed at runtime.
 //
-void HeapShared::archive_reachable_objects_from_static_field(Klass *k,
+void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
+                                                             const char* klass_name,
                                                              int field_offset,
-                                                             BasicType field_type,
+                                                             const char* field_name,
                                                              TRAPS) {
   assert(DumpSharedSpaces, "dump time only");
-  assert(k->is_instance_klass(), "sanity");
-  assert(InstanceKlass::cast(k)->is_shared_boot_class(),
-         "must be boot class");
+  assert(k->is_shared_boot_class(), "must be boot class");
 
   oop m = k->java_mirror();
   oop archived_m = MetaspaceShared::find_archived_heap_object(m);
@@ -482,58 +504,160 @@
     return;
   }
 
-  if (field_type == T_OBJECT || field_type == T_ARRAY) {
-    // obtain k's subGraph Info
-    KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
+  KlassSubGraphInfo* subgraph_info = get_subgraph_info(k);
+  oop f = m->obj_field(field_offset);
 
-    // get the object referenced by the field
-    oop f = m->obj_field(field_offset);
-    if (!CompressedOops::is_null(f)) {
-      LogTarget(Debug, cds, heap) log;
-      LogStream ls(log);
-      outputStream* out = &ls;
-      log.print("Start from: ");
-      f->print_on(out);
+  log_debug(cds, heap)("Start archiving from: %s::%s (" PTR_FORMAT ")", klass_name, field_name, p2i(f));
 
-      // get the archived copy of the field referenced object
-      oop af = MetaspaceShared::archive_heap_object(f, THREAD);
-      if (af == NULL) {
-        // Skip archiving the sub-graph referenced from the current entry field.
-        ResourceMark rm;
-        log_info(cds, heap)(
-          "Cannot archive the sub-graph referenced from %s object ("
-          PTR_FORMAT ") size[" SIZE_FORMAT "], skipped.",
-          f->klass()->external_name(), p2i(f), (size_t)f->size());
-        return;
-      }
-      if (!MetaspaceShared::is_archive_object(f)) {
-        WalkOopAndArchiveClosure walker(1, subgraph_info, f, af);
-        f->oop_iterate(&walker);
-      }
+  if (!CompressedOops::is_null(f)) {
+    if (log_is_enabled(Trace, cds, heap)) {
+      LogTarget(Trace, cds, heap) log;
+      LogStream out(log);
+      f->print_on(&out);
+    }
 
-      // The field value is not preserved in the archived mirror.
+    oop af = archive_reachable_objects_from(1, subgraph_info, f, CHECK);
+
+    if (af == NULL) {
+      log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)",
+                           klass_name, field_name);
+    } else {
+      // Note: the field value is not preserved in the archived mirror.
       // Record the field as a new subGraph entry point. The recorded
       // information is restored from the archive at runtime.
       subgraph_info->add_subgraph_entry_field(field_offset, af);
-      Klass *relocated_k = af->klass();
-      Klass *orig_k = f->klass();
-      subgraph_info->add_subgraph_object_klass(orig_k, relocated_k);
-      ResourceMark rm;
-      log_info(cds, heap)(
-          "Archived the sub-graph referenced from %s object " PTR_FORMAT,
-          f->klass()->external_name(), p2i(f));
-    } else {
-      // The field contains null, we still need to record the entry point,
-      // so it can be restored at runtime.
-      subgraph_info->add_subgraph_entry_field(field_offset, NULL);
+      log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(af));
     }
   } else {
-    ShouldNotReachHere();
+    // The field contains null, we still need to record the entry point,
+    // so it can be restored at runtime.
+    subgraph_info->add_subgraph_entry_field(field_offset, NULL);
   }
 }
 
+#ifndef PRODUCT
+class VerifySharedOopClosure: public BasicOopIterateClosure {
+ private:
+  bool _is_archived;
+
+ public:
+  VerifySharedOopClosure(bool is_archived) : _is_archived(is_archived) {}
+
+  void do_oop(narrowOop *p) { VerifySharedOopClosure::do_oop_work(p); }
+  void do_oop(      oop *p) { VerifySharedOopClosure::do_oop_work(p); }
+
+ protected:
+  template <class T> void do_oop_work(T *p) {
+    oop obj = RawAccess<>::oop_load(p);
+    if (!CompressedOops::is_null(obj)) {
+      HeapShared::verify_reachable_objects_from(obj, _is_archived);
+    }
+  }
+};
+
+void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_offset) {
+  assert(DumpSharedSpaces, "dump time only");
+  assert(k->is_shared_boot_class(), "must be boot class");
+
+  oop m = k->java_mirror();
+  oop archived_m = MetaspaceShared::find_archived_heap_object(m);
+  if (CompressedOops::is_null(archived_m)) {
+    return;
+  }
+  oop f = m->obj_field(field_offset);
+  if (!CompressedOops::is_null(f)) {
+    verify_subgraph_from(f);
+  }
+}
+
+void HeapShared::verify_subgraph_from(oop orig_obj) {
+  oop archived_obj = MetaspaceShared::find_archived_heap_object(orig_obj);
+  if (archived_obj == NULL) {
+    // It's OK for the root of a subgraph to be not archived. See comments in
+    // archive_reachable_objects_from().
+    return;
+  }
+
+  // Verify that all objects reachable from orig_obj are archived.
+  init_seen_objects_table();
+  verify_reachable_objects_from(orig_obj, false);
+  delete_seen_objects_table();
+
+  // Note: we could also verify that all objects reachable from the archived
+  // copy of orig_obj can only point to archived objects, with:
+  //      init_seen_objects_table();
+  //      verify_reachable_objects_from(archived_obj, true);
+  //      init_seen_objects_table();
+  // but that's already done in G1HeapVerifier::verify_archive_regions so we
+  // won't do it here.
+}
+
+void HeapShared::verify_reachable_objects_from(oop obj, bool is_archived) {
+  _num_total_verifications ++;
+  if (!has_been_seen_during_subgraph_recording(obj)) {
+    set_has_been_seen_during_subgraph_recording(obj);
+
+    if (is_archived) {
+      assert(MetaspaceShared::is_archive_object(obj), "must be");
+      assert(MetaspaceShared::find_archived_heap_object(obj) == NULL, "must be");
+    } else {
+      assert(!MetaspaceShared::is_archive_object(obj), "must be");
+      assert(MetaspaceShared::find_archived_heap_object(obj) != NULL, "must be");
+    }
+
+    VerifySharedOopClosure walker(is_archived);
+    obj->oop_iterate(&walker);
+  }
+}
+#endif
+
+HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = NULL;
+int HeapShared::_num_new_walked_objs;
+int HeapShared::_num_new_archived_objs;
+int HeapShared::_num_old_recorded_klasses;
+
+int HeapShared::_num_total_subgraph_recordings = 0;
+int HeapShared::_num_total_walked_objs = 0;
+int HeapShared::_num_total_archived_objs = 0;
+int HeapShared::_num_total_recorded_klasses = 0;
+int HeapShared::_num_total_verifications = 0;
+
+bool HeapShared::has_been_seen_during_subgraph_recording(oop obj) {
+  return _seen_objects_table->get(obj) != NULL;
+}
+
+void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
+  assert(!has_been_seen_during_subgraph_recording(obj), "sanity");
+  _seen_objects_table->put(obj, true);
+  ++ _num_new_walked_objs;
+}
+
+void HeapShared::start_recording_subgraph(InstanceKlass *k, const char* class_name) {
+  log_info(cds, heap)("Start recording subgraph(s) for archived fields in %s", class_name);
+  init_seen_objects_table();
+  _num_new_walked_objs = 0;
+  _num_new_archived_objs = 0;
+  _num_old_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses();
+}
+
+void HeapShared::done_recording_subgraph(InstanceKlass *k, const char* class_name) {
+  int num_new_recorded_klasses = get_subgraph_info(k)->num_subgraph_object_klasses() -
+    _num_old_recorded_klasses;
+  log_info(cds, heap)("Done recording subgraph(s) for archived fields in %s: "
+                      "walked %d objs, archived %d new objs, recorded %d classes",
+                      class_name, _num_new_walked_objs, _num_new_archived_objs,
+                      num_new_recorded_klasses);
+
+  delete_seen_objects_table();
+
+  _num_total_subgraph_recordings ++;
+  _num_total_walked_objs      += _num_new_walked_objs;
+  _num_total_archived_objs    += _num_new_archived_objs;
+  _num_total_recorded_klasses +=  num_new_recorded_klasses;
+}
+
 struct ArchivableStaticFieldInfo {
-  const char* class_name;
+  const char* klass_name;
   const char* field_name;
   InstanceKlass* klass;
   int offset;
@@ -553,39 +677,37 @@
   {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
 };
 
-const static int num_archivable_static_fields = sizeof(archivable_static_fields) / sizeof(ArchivableStaticFieldInfo);
+const static int num_archivable_static_fields =
+  sizeof(archivable_static_fields) / sizeof(ArchivableStaticFieldInfo);
 
 class ArchivableStaticFieldFinder: public FieldClosure {
   InstanceKlass* _ik;
   Symbol* _field_name;
   bool _found;
   int _offset;
-  BasicType _type;
 public:
   ArchivableStaticFieldFinder(InstanceKlass* ik, Symbol* field_name) :
-    _ik(ik), _field_name(field_name), _found(false), _offset(-1), _type(T_ILLEGAL) {}
+    _ik(ik), _field_name(field_name), _found(false), _offset(-1) {}
 
   virtual void do_field(fieldDescriptor* fd) {
     if (fd->name() == _field_name) {
       assert(!_found, "fields cannot be overloaded");
+      assert(fd->field_type() == T_OBJECT || fd->field_type() == T_ARRAY, "can archive only obj or array fields");
       _found = true;
       _offset = fd->offset();
-      _type = fd->field_type();
-      assert(_type == T_OBJECT || _type == T_ARRAY, "can archive only obj or array fields");
     }
   }
   bool found()     { return _found;  }
   int offset()     { return _offset; }
-  BasicType type() { return _type;   }
 };
 
 void HeapShared::init_archivable_static_fields(Thread* THREAD) {
   for (int i = 0; i < num_archivable_static_fields; i++) {
     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
-    TempNewSymbol class_name =  SymbolTable::new_symbol(info->class_name, THREAD);
+    TempNewSymbol klass_name =  SymbolTable::new_symbol(info->klass_name, THREAD);
     TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name, THREAD);
 
-    Klass* k = SystemDictionary::resolve_or_null(class_name, THREAD);
+    Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD);
     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
     InstanceKlass* ik = InstanceKlass::cast(k);
 
@@ -595,15 +717,50 @@
 
     info->klass = ik;
     info->offset = finder.offset();
-    info->type = finder.type();
   }
 }
 
-void HeapShared::archive_module_graph_objects(Thread* THREAD) {
+void HeapShared::archive_static_fields(Thread* THREAD) {
+  // For each class X that has one or more archived fields:
+  // [1] Dump the subgraph of each archived field
+  // [2] Create a list of all the class of the objects that can be reached
+  //     by any of these static fields.
+  //     At runtime, these classes are initialized before X's archived fields
+  //     are restored by HeapShared::initialize_from_archived_subgraph().
+  int i;
+  for (i = 0; i < num_archivable_static_fields; ) {
+    ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
+    const char* klass_name = info->klass_name;
+    start_recording_subgraph(info->klass, klass_name);
+
+    // If you have specified consecutive fields of the same klass in
+    // archivable_static_fields[], these will be archived in the same
+    // {start_recording_subgraph ... done_recording_subgraph} pass to
+    // save time.
+    for (; i < num_archivable_static_fields; i++) {
+      ArchivableStaticFieldInfo* f = &archivable_static_fields[i];
+      if (f->klass_name != klass_name) {
+        break;
+      }
+      archive_reachable_objects_from_static_field(f->klass, f->klass_name,
+                                                  f->offset, f->field_name, CHECK);
+    }
+    done_recording_subgraph(info->klass, klass_name);
+  }
+
+  log_info(cds, heap)("Performed subgraph records = %d times", _num_total_subgraph_recordings);
+  log_info(cds, heap)("Walked %d objects", _num_total_walked_objs);
+  log_info(cds, heap)("Archived %d objects", _num_total_archived_objs);
+  log_info(cds, heap)("Recorded %d klasses", _num_total_recorded_klasses);
+
+
+#ifndef PRODUCT
   for (int i = 0; i < num_archivable_static_fields; i++) {
-    ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
-    archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
+    ArchivableStaticFieldInfo* f = &archivable_static_fields[i];
+    verify_subgraph_from_static_field(f->klass, f->offset);
   }
+  log_info(cds, heap)("Verified %d references", _num_total_verifications);
+#endif
 }
 
 // At dump-time, find the location of all the non-null oop pointers in an archived heap
@@ -677,7 +834,7 @@
     narrowOop* p = _start + offset;
     narrowOop v = *p;
     assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time");
-    oop o = HeapShared::decode_with_archived_oop_encoding_mode(v);
+    oop o = HeapShared::decode_from_archive(v);
     RawAccess<IS_NOT_NULL>::oop_store(p, o);
     return true;
   }
--- a/src/hotspot/share/memory/heapShared.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/heapShared.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -26,12 +26,14 @@
 #define SHARE_VM_MEMORY_HEAPSHARED_HPP
 
 #include "classfile/systemDictionary.hpp"
+#include "memory/allocation.hpp"
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.hpp"
 #include "oops/typeArrayKlass.hpp"
 #include "utilities/bitMap.hpp"
 #include "utilities/growableArray.hpp"
+#include "utilities/resourceHash.hpp"
 
 #if INCLUDE_CDS_JAVA_HEAP
 // A dump time sub-graph info for Klass _k. It includes the entry points
@@ -74,6 +76,10 @@
   }
   void add_subgraph_entry_field(int static_field_offset, oop v);
   void add_subgraph_object_klass(Klass *orig_k, Klass *relocated_k);
+  int num_subgraph_object_klasses() {
+    return _subgraph_object_klasses == NULL ? 0 :
+           _subgraph_object_klasses->length();
+  }
 };
 
 // An archived record of object sub-graphs reachable from static
@@ -89,20 +95,21 @@
 
   // klasses of objects in archived sub-graphs referenced from the entry points
   // (static fields) in the containing class
-  Array<Klass*>* _subgraph_klasses;
+  Array<Klass*>* _subgraph_object_klasses;
  public:
   ArchivedKlassSubGraphInfoRecord() :
-    _next(NULL), _k(NULL), _entry_field_records(NULL), _subgraph_klasses(NULL) {}
+    _next(NULL), _k(NULL), _entry_field_records(NULL), _subgraph_object_klasses(NULL) {}
   void init(KlassSubGraphInfo* info);
   Klass* klass() { return _k; }
   ArchivedKlassSubGraphInfoRecord* next() { return _next; }
   void set_next(ArchivedKlassSubGraphInfoRecord* next) { _next = next; }
   Array<juint>*  entry_field_records() { return _entry_field_records; }
-  Array<Klass*>* subgraph_klasses() { return _subgraph_klasses; }
+  Array<Klass*>* subgraph_object_klasses() { return _subgraph_object_klasses; }
 };
 #endif // INCLUDE_CDS_JAVA_HEAP
 
 class HeapShared: AllStatic {
+  friend class VerifySharedOopClosure;
  private:
 #if INCLUDE_CDS_JAVA_HEAP
   // This is a list of subgraph infos built at dump time while
@@ -117,7 +124,12 @@
   // Archive object sub-graph starting from the given static field
   // in Klass k's mirror.
   static void archive_reachable_objects_from_static_field(
-    Klass* k, int field_ofset, BasicType field_type, TRAPS);
+    InstanceKlass* k, const char* klass_name,
+    int field_offset, const char* field_name, TRAPS);
+  static void verify_subgraph_from_static_field(
+    InstanceKlass* k, int field_offset) PRODUCT_RETURN;
+
+  static void verify_reachable_objects_from(oop obj, bool is_archived) PRODUCT_RETURN;
 
   static KlassSubGraphInfo* find_subgraph_info(Klass *k);
   static KlassSubGraphInfo* get_subgraph_info(Klass *k);
@@ -125,10 +137,53 @@
 
   static size_t build_archived_subgraph_info_records(int num_records);
 
-  // Used by decode_with_archived_oop_encoding_mode
+  // Used by decode_from_archive
   static address _narrow_oop_base;
   static int     _narrow_oop_shift;
 
+  static bool oop_equals(oop const& p1, oop const& p2) {
+    return primitive_equals<oop>(p1, p2);
+  }
+
+  static unsigned oop_hash(oop const& p) {
+    return primitive_hash<address>((address)p);
+  }
+
+  typedef ResourceHashtable<oop, bool,
+      HeapShared::oop_hash,
+      HeapShared::oop_equals,
+      15889, // prime number
+      ResourceObj::C_HEAP> SeenObjectsTable;
+
+  static SeenObjectsTable *_seen_objects_table;
+
+  static void init_seen_objects_table() {
+    assert(_seen_objects_table == NULL, "must be");
+    _seen_objects_table = new (ResourceObj::C_HEAP, mtClass)SeenObjectsTable();
+  }
+  static void delete_seen_objects_table() {
+    assert(_seen_objects_table != NULL, "must be");
+    delete _seen_objects_table;
+    _seen_objects_table = NULL;
+  }
+
+  // Statistics (for one round of start_recording_subgraph ... done_recording_subgraph)
+  static int _num_new_walked_objs;
+  static int _num_new_archived_objs;
+  static int _num_old_recorded_klasses;
+
+  // Statistics (for all archived subgraphs)
+  static int _num_total_subgraph_recordings;
+  static int _num_total_walked_objs;
+  static int _num_total_archived_objs;
+  static int _num_total_recorded_klasses;
+  static int _num_total_verifications;
+
+  static void start_recording_subgraph(InstanceKlass *k, const char* klass_name);
+  static void done_recording_subgraph(InstanceKlass *k, const char* klass_name);
+
+  static bool has_been_seen_during_subgraph_recording(oop obj);
+  static void set_has_been_seen_during_subgraph_recording(oop obj);
 #endif // INCLUDE_CDS_JAVA_HEAP
  public:
   static char* read_archived_subgraph_infos(char* buffer) NOT_CDS_JAVA_HEAP_RETURN_(buffer);
@@ -139,7 +194,7 @@
   // than Universe::narrow_oop_{base,shift} -- see FileMapInfo::map_heap_regions_impl.
   // To decode them, do not use CompressedOops::decode_not_null. Use this
   // function instead.
-  inline static oop decode_with_archived_oop_encoding_mode(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
+  inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
 
   static void init_narrow_oop_decoding(address base, int shift) NOT_CDS_JAVA_HEAP_RETURN;
 
@@ -147,10 +202,12 @@
                                                     size_t oopmap_in_bits) NOT_CDS_JAVA_HEAP_RETURN;
 
   static void init_archivable_static_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
-  static void archive_module_graph_objects(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
+  static void archive_static_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
 
 #if INCLUDE_CDS_JAVA_HEAP
   static ResourceBitMap calculate_oopmap(MemRegion region);
+  static oop archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj, TRAPS);
+  static void verify_subgraph_from(oop orig_obj) PRODUCT_RETURN;
 #endif
 };
 #endif // SHARE_VM_MEMORY_HEAPSHARED_HPP
--- a/src/hotspot/share/memory/heapShared.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/heapShared.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -30,7 +30,7 @@
 
 #if INCLUDE_CDS_JAVA_HEAP
 
-inline oop HeapShared::decode_with_archived_oop_encoding_mode(narrowOop v) {
+inline oop HeapShared::decode_from_archive(narrowOop v) {
   assert(!CompressedOops::is_null(v), "narrow oop value can never be zero");
   oop result = (oop)(void*)((uintptr_t)_narrow_oop_base + ((uintptr_t)v << _narrow_oop_shift));
   assert(check_obj_alignment(result), "address not aligned: " INTPTR_FORMAT, p2i((void*) result));
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -76,6 +76,7 @@
 bool MetaspaceShared::_archive_loading_failed = false;
 bool MetaspaceShared::_remapped_readwrite = false;
 bool MetaspaceShared::_open_archive_heap_region_mapped = false;
+bool MetaspaceShared::_archive_heap_region_fixed = false;
 address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
 size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
 size_t MetaspaceShared::_core_spaces_size = 0;
@@ -1880,7 +1881,7 @@
 
   MetaspaceShared::archive_klass_objects(THREAD);
 
-  HeapShared::archive_module_graph_objects(THREAD);
+  HeapShared::archive_static_fields(THREAD);
 
   G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
                                                    os::vm_allocation_granularity());
@@ -1940,8 +1941,10 @@
 }
 
 oop MetaspaceShared::materialize_archived_object(narrowOop v) {
+  assert(archive_heap_region_fixed(),
+         "must be called after archive heap regions are fixed");
   if (!CompressedOops::is_null(v)) {
-    oop obj = HeapShared::decode_with_archived_oop_encoding_mode(v);
+    oop obj = HeapShared::decode_from_archive(v);
     return G1CollectedHeap::heap()->materialize_archived_object(obj);
   }
   return NULL;
@@ -1970,6 +1973,7 @@
 void MetaspaceShared::fixup_mapped_heap_regions() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
   mapinfo->fixup_mapped_heap_regions();
+  set_archive_heap_region_fixed();
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
 
@@ -2017,7 +2021,7 @@
              "Archived heap object is not allowed");
       assert(MetaspaceShared::open_archive_heap_region_mapped(),
              "Open archive heap region is not mapped");
-      *p = HeapShared::decode_with_archived_oop_encoding_mode(o);
+      *p = HeapShared::decode_from_archive(o);
     }
   }
 
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -59,6 +59,7 @@
   static bool _archive_loading_failed;
   static bool _remapped_readwrite;
   static bool _open_archive_heap_region_mapped;
+  static bool _archive_heap_region_fixed;
   static address _cds_i2i_entry_code_buffers;
   static size_t  _cds_i2i_entry_code_buffers_size;
   static size_t  _core_spaces_size;
@@ -114,6 +115,14 @@
   static oop archive_heap_object(oop obj, Thread* THREAD);
   static oop materialize_archived_object(narrowOop v);
   static void archive_klass_objects(Thread* THREAD);
+
+  static void set_archive_heap_region_fixed() {
+    _archive_heap_region_fixed = true;
+  }
+
+  static bool archive_heap_region_fixed() {
+    return _archive_heap_region_fixed;
+  }
 #endif
 
   static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
--- a/src/hotspot/share/memory/universe.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/memory/universe.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -332,7 +332,6 @@
              SystemDictionary::Cloneable_klass(), "u3");
       assert(_the_array_interfaces_array->at(1) ==
              SystemDictionary::Serializable_klass(), "u3");
-      MetaspaceShared::fixup_mapped_heap_regions();
     } else
 #endif
     {
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -643,7 +643,7 @@
   if (!is_not_initialized()) return;  // note: not equivalent to is_initialized()
 
   ClassState old_state = init_state();
-  link_class_impl(true, THREAD);
+  link_class_impl(THREAD);
   if (HAS_PENDING_EXCEPTION) {
     CLEAR_PENDING_EXCEPTION;
     // Abort if linking the class throws an exception.
@@ -681,11 +681,9 @@
 }
 
 
-bool InstanceKlass::verify_code(bool throw_verifyerror, TRAPS) {
+bool InstanceKlass::verify_code(TRAPS) {
   // 1) Verify the bytecodes
-  Verifier::Mode mode =
-    throw_verifyerror ? Verifier::ThrowException : Verifier::NoException;
-  return Verifier::verify(this, mode, should_verify_class(), THREAD);
+  return Verifier::verify(this, should_verify_class(), THREAD);
 }
 
 
@@ -700,7 +698,7 @@
 void InstanceKlass::link_class(TRAPS) {
   assert(is_loaded(), "must be loaded");
   if (!is_linked()) {
-    link_class_impl(true, CHECK);
+    link_class_impl(CHECK);
   }
 }
 
@@ -709,12 +707,12 @@
 bool InstanceKlass::link_class_or_fail(TRAPS) {
   assert(is_loaded(), "must be loaded");
   if (!is_linked()) {
-    link_class_impl(false, CHECK_false);
+    link_class_impl(CHECK_false);
   }
   return is_linked();
 }
 
-bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
+bool InstanceKlass::link_class_impl(TRAPS) {
   if (DumpSharedSpaces && is_in_error_state()) {
     // This is for CDS dumping phase only -- we use the in_error_state to indicate that
     // the class has failed verification. Throwing the NoClassDefFoundError here is just
@@ -756,7 +754,7 @@
     }
 
     InstanceKlass* ik_super = InstanceKlass::cast(super_klass);
-    ik_super->link_class_impl(throw_verifyerror, CHECK_false);
+    ik_super->link_class_impl(CHECK_false);
   }
 
   // link all interfaces implemented by this class before linking this class
@@ -764,7 +762,7 @@
   int num_interfaces = interfaces->length();
   for (int index = 0; index < num_interfaces; index++) {
     InstanceKlass* interk = interfaces->at(index);
-    interk->link_class_impl(throw_verifyerror, CHECK_false);
+    interk->link_class_impl(CHECK_false);
   }
 
   // in case the class is linked in the process of linking its superclasses
@@ -794,7 +792,7 @@
     if (!is_linked()) {
       if (!is_rewritten()) {
         {
-          bool verify_ok = verify_code(throw_verifyerror, THREAD);
+          bool verify_ok = verify_code(THREAD);
           if (!verify_ok) {
             return false;
           }
--- a/src/hotspot/share/oops/instanceKlass.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1285,8 +1285,8 @@
 private:
   void fence_and_clear_init_lock();
 
-  bool link_class_impl                           (bool throw_verifyerror, TRAPS);
-  bool verify_code                               (bool throw_verifyerror, TRAPS);
+  bool link_class_impl                           (TRAPS);
+  bool verify_code                               (TRAPS);
   void initialize_impl                           (TRAPS);
   void initialize_super_interfaces               (TRAPS);
   void eager_initialize_impl                     ();
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -98,12 +98,14 @@
 
 template <typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {
+  assert(closure->ref_discoverer() == NULL, "ReferenceDiscoverer should not be set");
   do_referent<T>(obj, closure, contains);
   do_discovered<T>(obj, closure, contains);
 }
 
 template <typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::oop_oop_iterate_fields_except_referent(oop obj, OopClosureType* closure, Contains& contains) {
+  assert(closure->ref_discoverer() == NULL, "ReferenceDiscoverer should not be set");
   do_discovered<T>(obj, closure, contains);
 }
 
--- a/src/hotspot/share/oops/klass.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/oops/klass.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -656,8 +656,9 @@
   virtual MetaspaceObj::Type type() const { return ClassType; }
 
   // Iff the class loader (or mirror for unsafe anonymous classes) is alive the
-  // Klass is considered alive.  Has already been marked as unloading.
-  bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }
+  // Klass is considered alive. This is safe to call before the CLD is marked as
+  // unloading, and hence during concurrent class unloading.
+  bool is_loader_alive() const { return class_loader_data()->is_alive(); }
 
   // Load the klass's holder as a phantom. This is useful when a weak Klass
   // pointer has been "peeked" and then must be kept alive before it may
--- a/src/hotspot/share/opto/graphKit.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/graphKit.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1698,6 +1698,14 @@
   return _barrier_set->clone(this, src, dst, size, is_array);
 }
 
+Node* GraphKit::access_resolve(Node* n, DecoratorSet decorators) {
+  // Use stronger ACCESS_WRITE|ACCESS_READ by default.
+  if ((decorators & (ACCESS_READ | ACCESS_WRITE)) == 0) {
+    decorators |= ACCESS_READ | ACCESS_WRITE;
+  }
+  return _barrier_set->resolve(this, n, decorators);
+}
+
 //-------------------------array_element_address-------------------------
 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
                                       const TypeInt* sizetype, Node* ctrl) {
@@ -3233,6 +3241,8 @@
 
   assert(dead_locals_are_killed(), "should kill locals before sync. point");
 
+  obj = access_resolve(obj, ACCESS_READ | ACCESS_WRITE);
+
   // Box the stack location
   Node* box = _gvn.transform(new BoxLockNode(next_monitor()));
   Node* mem = reset_memory();
@@ -3950,6 +3960,8 @@
    *   dst[i_char++] = (char)(src[i_byte] & 0xff);
    * }
    */
+  src = access_resolve(src, ACCESS_READ);
+  dst = access_resolve(dst, ACCESS_WRITE);
   add_predicate();
   RegionNode* head = new RegionNode(3);
   head->init_req(1, control());
--- a/src/hotspot/share/opto/graphKit.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/graphKit.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -637,6 +637,8 @@
 
   void access_clone(Node* ctl, Node* src, Node* dst, Node* size, bool is_array);
 
+  Node* access_resolve(Node* n, DecoratorSet decorators);
+
   // Return addressing for an array element.
   Node* array_element_address(Node* ary, Node* idx, BasicType elembt,
                               // Optional constraint on the array size:
--- a/src/hotspot/share/opto/library_call.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/library_call.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1103,6 +1103,9 @@
   arg1 = must_be_not_null(arg1, true);
   arg2 = must_be_not_null(arg2, true);
 
+  arg1 = access_resolve(arg1, ACCESS_READ);
+  arg2 = access_resolve(arg2, ACCESS_READ);
+
   // Get start addr and length of first argument
   Node* arg1_start  = array_element_address(arg1, intcon(0), T_BYTE);
   Node* arg1_cnt    = load_array_length(arg1);
@@ -1130,6 +1133,9 @@
     arg1 = must_be_not_null(arg1, true);
     arg2 = must_be_not_null(arg2, true);
 
+    arg1 = access_resolve(arg1, ACCESS_READ);
+    arg2 = access_resolve(arg2, ACCESS_READ);
+
     // Get start addr and length of first argument
     Node* arg1_start  = array_element_address(arg1, intcon(0), T_BYTE);
     Node* arg1_cnt    = load_array_length(arg1);
@@ -1170,6 +1176,9 @@
   Node* arg1 = argument(0);
   Node* arg2 = argument(1);
 
+  arg1 = access_resolve(arg1, ACCESS_READ);
+  arg2 = access_resolve(arg2, ACCESS_READ);
+
   const TypeAryPtr* mtype = (ae == StrIntrinsicNode::UU) ? TypeAryPtr::CHARS : TypeAryPtr::BYTES;
   set_result(_gvn.transform(new AryEqNode(control(), memory(mtype), arg1, arg2, ae)));
   clear_upper_avx();
@@ -1196,6 +1205,7 @@
   if (stopped()) {
     return true;
   }
+  ba = access_resolve(ba, ACCESS_READ);
   Node* ba_start = array_element_address(ba, offset, T_BYTE);
   Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
   set_result(_gvn.transform(result));
@@ -1266,6 +1276,9 @@
   src = must_be_not_null(src, true);
   tgt = must_be_not_null(tgt, true);
 
+  src = access_resolve(src, ACCESS_READ);
+  tgt = access_resolve(tgt, ACCESS_READ);
+
   // Get start addr and length of source string
   Node* src_start = array_element_address(src, intcon(0), T_BYTE);
   Node* src_count = load_array_length(src);
@@ -1313,6 +1326,9 @@
   src = must_be_not_null(src, true);
   tgt = must_be_not_null(tgt, true);
 
+  src = access_resolve(src, ACCESS_READ);
+  tgt = access_resolve(tgt, ACCESS_READ);
+
   // Multiply byte array index by 2 if String is UTF16 encoded
   Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
   src_count = _gvn.transform(new SubINode(src_count, from_index));
@@ -1399,6 +1415,7 @@
   Node* max         = argument(3);
 
   src = must_be_not_null(src, true);
+  src = access_resolve(src, ACCESS_READ);
 
   Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
   Node* src_start = array_element_address(src, src_offset, T_BYTE);
@@ -1489,6 +1506,9 @@
     return true;
   }
 
+  src = access_resolve(src, ACCESS_READ);
+  dst = access_resolve(dst, ACCESS_WRITE);
+
   Node* src_start = array_element_address(src, src_offset, src_elem);
   Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
   // 'src_start' points to src array + scaled offset
@@ -1579,6 +1599,7 @@
     AllocateArrayNode* alloc = tightly_coupled_allocation(newcopy, NULL);
 
     // Calculate starting addresses.
+    value = access_resolve(value, ACCESS_READ);
     Node* src_start = array_element_address(value, offset, T_CHAR);
     Node* dst_start = basic_plus_adr(newcopy, arrayOopDesc::base_offset_in_bytes(T_BYTE));
 
@@ -1662,6 +1683,9 @@
   }
 
   if (!stopped()) {
+    src = access_resolve(src, ACCESS_READ);
+    dst = access_resolve(dst, ACCESS_READ);
+
     // Calculate starting addresses.
     Node* src_start = array_element_address(src, src_begin, T_BYTE);
     Node* dst_start = array_element_address(dst, dst_begin, T_CHAR);
@@ -1730,6 +1754,7 @@
   }
 
   value = must_be_not_null(value, true);
+  value = access_resolve(value, is_store ? ACCESS_WRITE : ACCESS_READ);
 
   Node* adr = array_element_address(value, index, T_CHAR);
   if (adr->is_top()) {
@@ -3661,6 +3686,8 @@
       Node* orig_tail = _gvn.transform(new SubINode(orig_length, start));
       Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
 
+      original = access_resolve(original, ACCESS_READ);
+
       // Generate a direct call to the right arraycopy function(s).
       // We know the copy is disjoint but we might not know if the
       // oop stores need checking.
@@ -4303,6 +4330,7 @@
         if (is_obja != NULL) {
           PreserveJVMState pjvms2(this);
           set_control(is_obja);
+          obj = access_resolve(obj, ACCESS_READ);
           // Generate a direct call to the right arraycopy function(s).
           Node* alloc = tightly_coupled_allocation(alloc_obj, NULL);
           ArrayCopyNode* ac = ArrayCopyNode::make(this, true, obj, intcon(0), alloc_obj, intcon(0), obj_length, alloc != NULL, false);
@@ -4779,7 +4807,10 @@
     return true;
   }
 
-  ArrayCopyNode* ac = ArrayCopyNode::make(this, true, src, src_offset, dest, dest_offset, length, alloc != NULL, negative_length_guard_generated,
+  Node* new_src = access_resolve(src, ACCESS_READ);
+  Node* new_dest = access_resolve(dest, ACCESS_WRITE);
+
+  ArrayCopyNode* ac = ArrayCopyNode::make(this, true, new_src, src_offset, new_dest, dest_offset, length, alloc != NULL, negative_length_guard_generated,
                                           // Create LoadRange and LoadKlass nodes for use during macro expansion here
                                           // so the compiler has a chance to eliminate them: during macro expansion,
                                           // we have to set their control (CastPP nodes are eliminated).
@@ -4892,6 +4923,9 @@
   src = must_be_not_null(src, true);
   dst = must_be_not_null(dst, true);
 
+  src = access_resolve(src, ACCESS_READ);
+  dst = access_resolve(dst, ACCESS_WRITE);
+
   const Type* src_type = src->Value(&_gvn);
   const Type* dst_type = dst->Value(&_gvn);
   const TypeAryPtr* top_src = src_type->isa_aryptr();
@@ -4947,6 +4981,10 @@
   x = must_be_not_null(x, true);
   y = must_be_not_null(y, true);
 
+  x = access_resolve(x, ACCESS_READ);
+  y = access_resolve(y, ACCESS_READ);
+  z = access_resolve(z, ACCESS_WRITE);
+
   const Type* x_type = x->Value(&_gvn);
   const Type* y_type = y->Value(&_gvn);
   const TypeAryPtr* top_x = x_type->isa_aryptr();
@@ -5055,6 +5093,9 @@
   x = must_be_not_null(x, true);
   z = must_be_not_null(z, true);
 
+  x = access_resolve(x, ACCESS_READ);
+  z = access_resolve(z, ACCESS_WRITE);
+
   const Type* x_type = x->Value(&_gvn);
   const Type* z_type = z->Value(&_gvn);
   const TypeAryPtr* top_x = x_type->isa_aryptr();
@@ -5104,6 +5145,9 @@
 
   out = must_be_not_null(out, true);
 
+  in = access_resolve(in, ACCESS_READ);
+  out = access_resolve(out, ACCESS_WRITE);
+
   const Type* out_type = out->Value(&_gvn);
   const Type* in_type = in->Value(&_gvn);
   const TypeAryPtr* top_out = out_type->isa_aryptr();
@@ -5153,6 +5197,11 @@
   Node* inv  = argument(4);
   Node* m    = argument(6);
 
+  a = access_resolve(a, ACCESS_READ);
+  b = access_resolve(b, ACCESS_READ);
+  n = access_resolve(n, ACCESS_READ);
+  m = access_resolve(m, ACCESS_WRITE);
+
   const Type* a_type = a->Value(&_gvn);
   const TypeAryPtr* top_a = a_type->isa_aryptr();
   const Type* b_type = b->Value(&_gvn);
@@ -5212,6 +5261,10 @@
   Node* inv  = argument(3);
   Node* m    = argument(5);
 
+  a = access_resolve(a, ACCESS_READ);
+  n = access_resolve(n, ACCESS_READ);
+  m = access_resolve(m, ACCESS_WRITE);
+
   const Type* a_type = a->Value(&_gvn);
   const TypeAryPtr* top_a = a_type->isa_aryptr();
   const Type* n_type = a->Value(&_gvn);
@@ -5357,6 +5410,7 @@
 
   // 'src_start' points to src array + scaled offset
   src = must_be_not_null(src, true);
+  src = access_resolve(src, ACCESS_READ);
   Node* src_start = array_element_address(src, offset, src_elem);
 
   // We assume that range check is done by caller.
@@ -5446,11 +5500,13 @@
 
   // 'src_start' points to src array + scaled offset
   src = must_be_not_null(src, true);
+  src = access_resolve(src, ACCESS_READ);
   Node* src_start = array_element_address(src, offset, src_elem);
 
   // static final int[] byteTable in class CRC32C
   Node* table = get_table_from_crc32c_class(callee()->holder());
   table = must_be_not_null(table, true);
+  table = access_resolve(table, ACCESS_READ);
   Node* table_start = array_element_address(table, intcon(0), T_INT);
 
   // We assume that range check is done by caller.
@@ -5495,6 +5551,7 @@
   // static final int[] byteTable in class CRC32C
   Node* table = get_table_from_crc32c_class(callee()->holder());
   table = must_be_not_null(table, true);
+  table = access_resolve(table, ACCESS_READ);
   Node* table_start = array_element_address(table, intcon(0), T_INT);
 
   // Call the stub.
@@ -5538,6 +5595,7 @@
   }
 
   // 'src_start' points to src array + scaled offset
+  src = access_resolve(src, ACCESS_READ);
   Node* src_start = array_element_address(src, offset, src_elem);
 
   // We assume that range check is done by caller.
@@ -5741,6 +5799,9 @@
   src = must_be_not_null(src, true);
   dest = must_be_not_null(dest, true);
 
+  src = access_resolve(src, ACCESS_READ);
+  dest = access_resolve(dest, ACCESS_WRITE);
+
   // (1) src and dest are arrays.
   const Type* src_type = src->Value(&_gvn);
   const Type* dest_type = dest->Value(&_gvn);
@@ -5814,6 +5875,9 @@
   src = must_be_not_null(src, false);
   dest = must_be_not_null(dest, false);
 
+  src = access_resolve(src, ACCESS_READ);
+  dest = access_resolve(dest, ACCESS_WRITE);
+
   // (1) src and dest are arrays.
   const Type* src_type = src->Value(&_gvn);
   const Type* dest_type = dest->Value(&_gvn);
@@ -5859,6 +5923,7 @@
   // similarly, get the start address of the r vector
   Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false);
   if (objRvec == NULL) return false;
+  objRvec = access_resolve(objRvec, ACCESS_WRITE);
   Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
 
   Node* cbcCrypt;
@@ -5907,6 +5972,10 @@
   Node* dest = argument(4);
   Node* dest_offset = argument(5);
 
+  src = access_resolve(src, ACCESS_READ);
+  dest = access_resolve(dest, ACCESS_WRITE);
+  counterMode_object = access_resolve(counterMode_object, ACCESS_WRITE);
+
   // (1) src and dest are arrays.
   const Type* src_type = src->Value(&_gvn);
   const Type* dest_type = dest->Value(&_gvn);
@@ -5947,10 +6016,12 @@
   // similarly, get the start address of the r vector
   Node* obj_counter = load_field_from_object(counterMode_object, "counter", "[B", /*is_exact*/ false);
   if (obj_counter == NULL) return false;
+  obj_counter = access_resolve(obj_counter, ACCESS_WRITE);
   Node* cnt_start = array_element_address(obj_counter, intcon(0), T_BYTE);
 
   Node* saved_encCounter = load_field_from_object(counterMode_object, "encryptedCounter", "[B", /*is_exact*/ false);
   if (saved_encCounter == NULL) return false;
+  saved_encCounter = access_resolve(saved_encCounter, ACCESS_WRITE);
   Node* saved_encCounter_start = array_element_address(saved_encCounter, intcon(0), T_BYTE);
   Node* used = field_address_from_object(counterMode_object, "used", "I", /*is_exact*/ false);
 
@@ -5991,6 +6062,7 @@
   if (objAESCryptKey == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the K array
+  objAESCryptKey = access_resolve(objAESCryptKey, ACCESS_READ);
   Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
   return k_start;
 }
@@ -6002,6 +6074,7 @@
   if (objAESCryptKey == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the lastKey array
+  objAESCryptKey = access_resolve(objAESCryptKey, ACCESS_READ);
   Node* original_k_start = array_element_address(objAESCryptKey, intcon(0), T_BYTE);
   return original_k_start;
 }
@@ -6132,6 +6205,10 @@
   subkeyH = must_be_not_null(subkeyH, true);
   data = must_be_not_null(data, true);
 
+  state = access_resolve(state, ACCESS_WRITE);
+  subkeyH = access_resolve(subkeyH, ACCESS_READ);
+  data = access_resolve(data, ACCESS_READ);
+
   Node* state_start  = array_element_address(state, intcon(0), T_LONG);
   assert(state_start, "state is NULL");
   Node* subkeyH_start  = array_element_address(subkeyH, intcon(0), T_LONG);
@@ -6206,6 +6283,7 @@
   }
   // 'src_start' points to src array + offset
   src = must_be_not_null(src, true);
+  src = access_resolve(src, ACCESS_READ);
   Node* src_start = array_element_address(src, ofs, src_elem);
   Node* state = NULL;
   address stubAddr;
@@ -6273,6 +6351,7 @@
   }
   // 'src_start' points to src array + offset
   src = must_be_not_null(src, false);
+  src = access_resolve(src, ACCESS_READ);
   Node* src_start = array_element_address(src, ofs, src_elem);
 
   const char* klass_SHA_name = NULL;
@@ -6355,6 +6434,7 @@
   if (sha_state == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the state array
+  sha_state = access_resolve(sha_state, ACCESS_WRITE);
   Node* state = array_element_address(sha_state, intcon(0), T_INT);
   return state;
 }
@@ -6366,6 +6446,7 @@
   if (sha_state == NULL) return (Node *) NULL;
 
   // now have the array, need to get the start address of the state array
+  sha_state = access_resolve(sha_state, ACCESS_WRITE);
   Node* state = array_element_address(sha_state, intcon(0), T_LONG);
   return state;
 }
--- a/src/hotspot/share/opto/phaseX.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/phaseX.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1889,13 +1889,23 @@
       } else if( n->is_Region() ) { // Unreachable region
         // Note: nn == C->top()
         n->set_req(0, NULL);        // Cut selfreference
-        // Eagerly remove dead phis to avoid phis copies creation.
-        for (DUIterator i = n->outs(); n->has_out(i); i++) {
-          Node* m = n->out(i);
-          if( m->is_Phi() ) {
-            assert(type(m) == Type::TOP, "Unreachable region should not have live phis.");
-            replace_node(m, nn);
-            --i; // deleted this phi; rescan starting with next position
+        bool progress = true;
+        uint max = n->outcnt();
+        DUIterator i;
+        while (progress) {
+          progress = false;
+          // Eagerly remove dead phis to avoid phis copies creation.
+          for (i = n->outs(); n->has_out(i); i++) {
+            Node* m = n->out(i);
+            if (m->is_Phi()) {
+              assert(type(m) == Type::TOP, "Unreachable region should not have live phis.");
+              replace_node(m, nn);
+              if (max != n->outcnt()) {
+                progress = true;
+                i = n->refresh_out_pos(i);
+                max = n->outcnt();
+              }
+            }
           }
         }
       }
--- a/src/hotspot/share/opto/stringopts.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/stringopts.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1212,6 +1212,7 @@
     kit.set_control(loop);
     Node* sizeTable = fetch_static_field(kit, size_table_field);
 
+    sizeTable = kit.access_resolve(sizeTable, ACCESS_READ);
     Node* value = kit.load_array_element(NULL, sizeTable, index, TypeAryPtr::INTS);
     C->record_for_igvn(value);
     Node* limit = __ CmpI(phi, value);
@@ -1547,6 +1548,7 @@
 // Compress copy contents of the byte/char String str into dst_array starting at index start.
 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* dst_array, Node* dst_coder, Node* start) {
   Node* src_array = kit.load_String_value(kit.control(), str);
+  src_array = kit.access_resolve(src_array, ACCESS_READ);
 
   IdealKit ideal(&kit, true, true);
   IdealVariable count(ideal); __ declarations_done();
--- a/src/hotspot/share/opto/subnode.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/opto/subnode.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1348,6 +1348,15 @@
   return NULL;
 }
 
+static bool is_counted_loop_cmp(Node *cmp) {
+  Node *n = cmp->in(1)->in(1);
+  return n != NULL &&
+         n->is_Phi() &&
+         n->in(0) != NULL &&
+         n->in(0)->is_CountedLoop() &&
+         n->in(0)->as_CountedLoop()->phi() == n;
+}
+
 //------------------------------Ideal------------------------------------------
 Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   // Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
@@ -1406,7 +1415,7 @@
   // Change ((x & m) u<= m) or ((m & x) u<= m) to always true
   // Same with ((x & m) u< m+1) and ((m & x) u< m+1)
   if (cop == Op_CmpU &&
-      cmp1->Opcode() == Op_AndI) {
+      cmp1_op == Op_AndI) {
     Node* bound = NULL;
     if (_test._test == BoolTest::le) {
       bound = cmp2;
@@ -1424,7 +1433,7 @@
   // This is the off-by-one variant of the above
   if (cop == Op_CmpU &&
       _test._test == BoolTest::lt &&
-      cmp1->Opcode() == Op_AndI) {
+      cmp1_op == Op_AndI) {
     Node* l = cmp1->in(1);
     Node* r = cmp1->in(2);
     for (int repeat = 0; repeat < 2; repeat++) {
@@ -1445,13 +1454,24 @@
     }
   }
 
+  // Change x u< 1 or x u<= 0 to x == 0
+  if (cop == Op_CmpU &&
+      cmp1_op != Op_LoadRange &&
+      ((_test._test == BoolTest::lt &&
+        cmp2->find_int_con(-1) == 1) ||
+       (_test._test == BoolTest::le &&
+        cmp2->find_int_con(-1) == 0))) {
+    Node* ncmp = phase->transform(new CmpINode(cmp1, phase->intcon(0)));
+    return new BoolNode(ncmp, BoolTest::eq);
+  }
+
   // Change (arraylength <= 0) or (arraylength == 0)
   //   into (arraylength u<= 0)
   // Also change (arraylength != 0) into (arraylength u> 0)
   // The latter version matches the code pattern generated for
   // array range checks, which will more likely be optimized later.
   if (cop == Op_CmpI &&
-      cmp1->Opcode() == Op_LoadRange &&
+      cmp1_op == Op_LoadRange &&
       cmp2->find_int_con(-1) == 0) {
     if (_test._test == BoolTest::le || _test._test == BoolTest::eq) {
       Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
@@ -1481,17 +1501,32 @@
   // due to possible integer overflow.
   if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
         (cop == Op_CmpI) &&
-        (cmp1->Opcode() == Op_SubI) &&
+        (cmp1_op == Op_SubI) &&
         ( cmp2_type == TypeInt::ZERO ) ) {
     Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),cmp1->in(2)));
     return new BoolNode( ncmp, _test._test );
   }
 
+  // Same as above but with and AddI of a constant
+  if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
+      cop == Op_CmpI &&
+      cmp1_op == Op_AddI &&
+      cmp1->in(2) != NULL &&
+      phase->type(cmp1->in(2))->isa_int() &&
+      phase->type(cmp1->in(2))->is_int()->is_con() &&
+      cmp2_type == TypeInt::ZERO &&
+      !is_counted_loop_cmp(cmp) // modifying the exit test of a counted loop messes the counted loop shape
+      ) {
+    const TypeInt* cmp1_in2 = phase->type(cmp1->in(2))->is_int();
+    Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),phase->intcon(-cmp1_in2->_hi)));
+    return new BoolNode( ncmp, _test._test );
+  }
+
   // Change (-A vs 0) into (A vs 0) by commuting the test.  Disallow in the
   // most general case because negating 0x80000000 does nothing.  Needed for
   // the CmpF3/SubI/CmpI idiom.
   if( cop == Op_CmpI &&
-      cmp1->Opcode() == Op_SubI &&
+      cmp1_op == Op_SubI &&
       cmp2_type == TypeInt::ZERO &&
       phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
       phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
--- a/src/hotspot/share/prims/jvmtiEnter.xsl	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiEnter.xsl	Thu Sep 13 10:54:11 2018 -0700
@@ -405,7 +405,7 @@
     <xsl:otherwise> 
       <xsl:choose>
         <xsl:when test="count(@phase)=0 or contains(@phase,'live') or contains(@phase,'start')">
-	  <xsl:text>if (this_thread == NULL || (!this_thread->is_Java_thread() &amp;&amp; !this_thread->is_VM_thread())) {</xsl:text>
+	  <xsl:text>if (this_thread == NULL || (!this_thread->is_Java_thread() &amp;&amp; !this_thread->is_Named_thread())) {</xsl:text>
         </xsl:when>
         <xsl:otherwise>
           <xsl:text>if (!this_thread->is_Java_thread()) {</xsl:text> 
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -129,7 +129,7 @@
     // requested, so only need to walk this loader's ClassLoaderData
     // dictionary, or the NULL ClassLoaderData dictionary for bootstrap loader.
     if (loader != NULL) {
-      ClassLoaderData* data = java_lang_ClassLoader::loader_data(loader);
+      ClassLoaderData* data = java_lang_ClassLoader::loader_data_acquire(loader);
       // ClassLoader may not be used yet for loading.
       if (data != NULL && data->dictionary() != NULL) {
         data->dictionary()->all_entries_do(&closure);
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -264,7 +264,6 @@
 
 // Any JavaThread will enter here with state _thread_blocked
 int JvmtiRawMonitor::raw_enter(TRAPS) {
-  TEVENT (raw_enter) ;
   void * Contended ;
 
   // don't enter raw monitor if thread is being externally suspended, it will
@@ -341,7 +340,6 @@
 // Used mainly for JVMTI raw monitor implementation
 // Also used for JvmtiRawMonitor::wait().
 int JvmtiRawMonitor::raw_exit(TRAPS) {
-  TEVENT (raw_exit) ;
   if (THREAD != _owner) {
     return OM_ILLEGAL_MONITOR_STATE;
   }
@@ -360,7 +358,6 @@
 // All JavaThreads will enter here with state _thread_blocked
 
 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
-  TEVENT (raw_wait) ;
   if (THREAD != _owner) {
     return OM_ILLEGAL_MONITOR_STATE;
   }
@@ -406,7 +403,6 @@
 }
 
 int JvmtiRawMonitor::raw_notify(TRAPS) {
-  TEVENT (raw_notify) ;
   if (THREAD != _owner) {
     return OM_ILLEGAL_MONITOR_STATE;
   }
@@ -415,7 +411,6 @@
 }
 
 int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
-  TEVENT (raw_notifyAll) ;
   if (THREAD != _owner) {
     return OM_ILLEGAL_MONITOR_STATE;
   }
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -699,7 +699,6 @@
   // Check whether the class NestHost attribute has been changed.
   Thread* thread = Thread::current();
   ResourceMark rm(thread);
-  JvmtiThreadState *state = JvmtiThreadState::state_for((JavaThread*)thread);
   u2 the_nest_host_idx = the_class->nest_host_index();
   u2 scr_nest_host_idx = scratch_class->nest_host_index();
 
@@ -1232,8 +1231,7 @@
       // verifier. Please, refer to jvmtiThreadState.hpp for the detailed
       // description.
       RedefineVerifyMark rvm(the_class, scratch_class, state);
-      Verifier::verify(
-        scratch_class, Verifier::ThrowException, true, THREAD);
+      Verifier::verify(scratch_class, true, THREAD);
     }
 
     if (HAS_PENDING_EXCEPTION) {
@@ -1264,7 +1262,7 @@
       // verify what we have done during constant pool merging
       {
         RedefineVerifyMark rvm(the_class, scratch_class, state);
-        Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD);
+        Verifier::verify(scratch_class, true, THREAD);
       }
 
       if (HAS_PENDING_EXCEPTION) {
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -2875,14 +2875,26 @@
       ConstantPool* pool = ik->constants();
       for (int i = 1; i < pool->length(); i++) {
         constantTag tag = pool->tag_at(i).value();
-        if (tag.is_string() || tag.is_klass()) {
+        if (tag.is_string() || tag.is_klass() || tag.is_unresolved_klass()) {
           oop entry;
           if (tag.is_string()) {
             entry = pool->resolved_string_at(i);
             // If the entry is non-null it is resolved.
-            if (entry == NULL) continue;
+            if (entry == NULL) {
+              continue;
+            }
+          } else if (tag.is_klass()) {
+            entry = pool->resolved_klass_at(i)->java_mirror();
           } else {
-            entry = pool->resolved_klass_at(i)->java_mirror();
+            // Code generated by JIT and AOT compilers might not resolve constant
+            // pool entries.  Treat them as resolved if they are loaded.
+            assert(tag.is_unresolved_klass(), "must be");
+            constantPoolHandle cp(Thread::current(), pool);
+            Klass* klass = ConstantPool::klass_at_if_loaded(cp, i);
+            if (klass == NULL) {
+              continue;
+            }
+            entry = klass->java_mirror();
           }
           if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
             return false;
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/prims/whitebox.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -1504,7 +1504,7 @@
 
   oop class_loader_oop = JNIHandles::resolve(class_loader);
   ClassLoaderData* cld = class_loader_oop != NULL
-      ? java_lang_ClassLoader::loader_data(class_loader_oop)
+      ? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
       : ClassLoaderData::the_null_class_loader_data();
 
   void* metadata = MetadataFactory::new_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
@@ -1515,7 +1515,7 @@
 WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
   oop class_loader_oop = JNIHandles::resolve(class_loader);
   ClassLoaderData* cld = class_loader_oop != NULL
-      ? java_lang_ClassLoader::loader_data(class_loader_oop)
+      ? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
       : ClassLoaderData::the_null_class_loader_data();
 
   MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -574,6 +574,9 @@
   { "PrintSafepointStatisticsCount", JDK_Version::jdk(11),     JDK_Version::jdk(12), JDK_Version::jdk(13) },
   { "TransmitErrorReport",           JDK_Version::undefined(), JDK_Version::jdk(12), JDK_Version::jdk(13) },
   { "ErrorReportServer",             JDK_Version::undefined(), JDK_Version::jdk(12), JDK_Version::jdk(13) },
+  { "EmitSync",                      JDK_Version::undefined(), JDK_Version::jdk(12), JDK_Version::jdk(13) },
+  { "SyncVerbose",                   JDK_Version::undefined(), JDK_Version::jdk(12), JDK_Version::jdk(13) },
+  { "SyncFlags",                     JDK_Version::undefined(), JDK_Version::jdk(12), JDK_Version::jdk(13) },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -3977,7 +3980,7 @@
     }
   }
 #ifdef COMPILER2
-  if (!UseBiasedLocking || EmitSync != 0) {
+  if (!UseBiasedLocking) {
     UseOptoBiasInlining = false;
   }
 #endif
--- a/src/hotspot/share/runtime/globals.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/globals.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -830,10 +830,6 @@
   experimental(ccstr, SyncKnobs, NULL,                                      \
                "(Unstable) Various monitor synchronization tunables")       \
                                                                             \
-  experimental(intx, EmitSync, 0,                                           \
-               "(Unsafe, Unstable) "                                        \
-               "Control emission of inline sync fast-path code")            \
-                                                                            \
   product(intx, MonitorBound, 0, "Bound Monitor population")                \
           range(0, max_jint)                                                \
                                                                             \
@@ -845,11 +841,6 @@
                 "The check is performed on GuaranteedSafepointInterval.")   \
                 range(0, 100)                                               \
                                                                             \
-  experimental(intx, SyncFlags, 0, "(Unsafe, Unstable) "                    \
-               "Experimental Sync flags")                                   \
-                                                                            \
-  experimental(intx, SyncVerbose, 0, "(Unstable)")                          \
-                                                                            \
   experimental(intx, hashCode, 5,                                           \
                "(Unstable) select hashCode generation algorithm")           \
                                                                             \
--- a/src/hotspot/share/runtime/java.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/java.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -333,7 +333,7 @@
     klassVtable::print_statistics();
     klassItable::print_statistics();
   }
-  if (VerifyOops) {
+  if (VerifyOops && Verbose) {
     tty->print_cr("+VerifyOops count: %d", StubRoutines::verify_oop_count());
   }
 
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -529,7 +529,7 @@
   // timer scalability issues we see on some platforms as we'd only have one thread
   // -- the checker -- parked on a timer.
 
-  if ((SyncFlags & 16) == 0 && nxt == NULL && _EntryList == NULL) {
+  if (nxt == NULL && _EntryList == NULL) {
     // Try to assume the role of responsible thread for the monitor.
     // CONSIDER:  ST vs CAS vs { if (Responsible==null) Responsible=Self }
     Atomic::replace_if_null(Self, &_Responsible);
@@ -546,7 +546,6 @@
   // to defer the state transitions until absolutely necessary,
   // and in doing so avoid some transitions ...
 
-  TEVENT(Inflated enter - Contention);
   int nWakeups = 0;
   int recheckInterval = 1;
 
@@ -555,13 +554,8 @@
     if (TryLock(Self) > 0) break;
     assert(_owner != Self, "invariant");
 
-    if ((SyncFlags & 2) && _Responsible == NULL) {
-      Atomic::replace_if_null(Self, &_Responsible);
-    }
-
     // park self
-    if (_Responsible == Self || (SyncFlags & 1)) {
-      TEVENT(Inflated enter - park TIMED);
+    if (_Responsible == Self) {
       Self->_ParkEvent->park((jlong) recheckInterval);
       // Increase the recheckInterval, but clamp the value.
       recheckInterval *= 8;
@@ -569,7 +563,6 @@
         recheckInterval = MAX_RECHECK_INTERVAL;
       }
     } else {
-      TEVENT(Inflated enter - park UNTIMED);
       Self->_ParkEvent->park();
     }
 
@@ -580,7 +573,7 @@
     // Note that the counter is not protected by a lock or updated by atomics.
     // That is by design - we trade "lossy" counters which are exposed to
     // races during updates for a lower probe effect.
-    TEVENT(Inflated enter - Futile wakeup);
+
     // This PerfData object can be used in parallel with a safepoint.
     // See the work around in PerfDataManager::destroy().
     OM_PERFDATA_OP(FutileWakeups, inc());
@@ -675,9 +668,6 @@
   // monitorexit.  Recall too, that in 1-0 mode monitorexit does not necessarily
   // execute a serializing instruction.
 
-  if (SyncFlags & 8) {
-    OrderAccess::fence();
-  }
   return;
 }
 
@@ -707,8 +697,6 @@
     if (TryLock(Self) > 0) break;
     if (TrySpin(Self) > 0) break;
 
-    TEVENT(Wait Reentry - parking);
-
     // State transition wrappers around park() ...
     // ReenterI() wisely defers state transitions until
     // it's clear we must park the thread.
@@ -719,11 +707,7 @@
       // cleared by handle_special_suspend_equivalent_condition()
       // or java_suspend_self()
       jt->set_suspend_equivalent();
-      if (SyncFlags & 1) {
-        Self->_ParkEvent->park((jlong)MAX_RECHECK_INTERVAL);
-      } else {
-        Self->_ParkEvent->park();
-      }
+      Self->_ParkEvent->park();
 
       // were we externally suspended while we were waiting?
       for (;;) {
@@ -744,7 +728,6 @@
     // Note that the counter is not protected by a lock or updated by atomics.
     // That is by design - we trade "lossy" counters which are exposed to
     // races during updates for a lower probe effect.
-    TEVENT(Wait Reentry - futile wakeup);
     ++nWakeups;
 
     // Assuming this is not a spurious wakeup we'll normally
@@ -795,7 +778,6 @@
     if (SelfNode == _EntryList) _EntryList = nxt;
     assert(nxt == NULL || nxt->TState == ObjectWaiter::TS_ENTER, "invariant");
     assert(prv == NULL || prv->TState == ObjectWaiter::TS_ENTER, "invariant");
-    TEVENT(Unlink from EntryList);
   } else {
     assert(SelfNode->TState == ObjectWaiter::TS_CXQ, "invariant");
     // Inopportune interleaving -- Self is still on the cxq.
@@ -834,7 +816,6 @@
       assert(q->_next == p, "invariant");
       q->_next = p->_next;
     }
-    TEVENT(Unlink from cxq);
   }
 
 #ifdef ASSERT
@@ -923,7 +904,6 @@
       // way we should encounter this situation is in the presence of
       // unbalanced JNI locking. TODO: CheckJNICalls.
       // See also: CR4414101
-      TEVENT(Exit - Throw IMSX);
       assert(false, "Non-balanced monitor enter/exit! Likely JNI locking");
       return;
     }
@@ -931,15 +911,12 @@
 
   if (_recursions != 0) {
     _recursions--;        // this is simple recursive enter
-    TEVENT(Inflated exit - recursive);
     return;
   }
 
   // Invariant: after setting Responsible=null an thread must execute
   // a MEMBAR or other serializing instruction before fetching EntryList|cxq.
-  if ((SyncFlags & 4) == 0) {
-    _Responsible = NULL;
-  }
+  _Responsible = NULL;
 
 #if INCLUDE_JFR
   // get the owner's thread id for the MonitorEnter event
@@ -968,10 +945,8 @@
       OrderAccess::release_store(&_owner, (void*)NULL);   // drop the lock
       OrderAccess::storeload();                        // See if we need to wake a successor
       if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
-        TEVENT(Inflated exit - simple egress);
         return;
       }
-      TEVENT(Inflated exit - complex egress);
       // Other threads are blocked trying to acquire the lock.
 
       // Normally the exiting thread is responsible for ensuring succession,
@@ -1013,14 +988,12 @@
       if (!Atomic::replace_if_null(THREAD, &_owner)) {
         return;
       }
-      TEVENT(Exit - Reacquired);
     } else {
       if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
         OrderAccess::release_store(&_owner, (void*)NULL);   // drop the lock
         OrderAccess::storeload();
         // Ratify the previously observed values.
         if (_cxq == NULL || _succ != NULL) {
-          TEVENT(Inflated exit - simple egress);
           return;
         }
 
@@ -1036,12 +1009,8 @@
         //     we could simply unpark() the lead thread and return
         //     without having set _succ.
         if (!Atomic::replace_if_null(THREAD, &_owner)) {
-          TEVENT(Inflated exit - reacquired succeeded);
           return;
         }
-        TEVENT(Inflated exit - reacquired failed);
-      } else {
-        TEVENT(Inflated exit - complex egress);
       }
     }
 
@@ -1168,7 +1137,6 @@
       if (u == w) break;
       w = u;
     }
-    TEVENT(Inflated exit - drain cxq into EntryList);
 
     assert(w != NULL, "invariant");
     assert(_EntryList == NULL, "invariant");
@@ -1272,7 +1240,6 @@
     if (2 == Mode) OrderAccess::storeload();
     if (!jSelf->is_external_suspend()) return false;
     // We raced a suspension -- fall thru into the slow path
-    TEVENT(ExitSuspendEquivalent - raced);
     jSelf->set_suspend_equivalent();
   }
   return jSelf->handle_special_suspend_equivalent_condition();
@@ -1300,10 +1267,6 @@
   OrderAccess::release_store(&_owner, (void*)NULL);
   OrderAccess::fence();                               // ST _owner vs LD in unpark()
 
-  if (SafepointMechanism::poll(Self)) {
-    TEVENT(unpark before SAFEPOINT);
-  }
-
   DTRACE_MONITOR_PROBE(contended__exit, this, object(), Self);
   Trigger->unpark();
 
@@ -1372,7 +1335,6 @@
         _owner = THREAD;  /* Convert from basiclock addr to Thread addr */  \
         _recursions = 0;                                                    \
       } else {                                                              \
-        TEVENT(Throw IMSX);                                                 \
         THROW(vmSymbols::java_lang_IllegalMonitorStateException());         \
       }                                                                     \
     }                                                                       \
@@ -1382,7 +1344,6 @@
 // TODO-FIXME: remove check_slow() -- it's likely dead.
 
 void ObjectMonitor::check_slow(TRAPS) {
-  TEVENT(check_slow - throw IMSX);
   assert(THREAD != _owner && !THREAD->is_lock_owned((address) _owner), "must not be owner");
   THROW_MSG(vmSymbols::java_lang_IllegalMonitorStateException(), "current thread not owner");
 }
@@ -1444,13 +1405,10 @@
     if (event.should_commit()) {
       post_monitor_wait_event(&event, this, 0, millis, false);
     }
-    TEVENT(Wait - Throw IEX);
     THROW(vmSymbols::java_lang_InterruptedException());
     return;
   }
 
-  TEVENT(Wait);
-
   assert(Self->_Stalled == 0, "invariant");
   Self->_Stalled = intptr_t(this);
   jt->set_current_waiting_monitor(this);
@@ -1474,9 +1432,8 @@
   AddWaiter(&node);
   Thread::SpinRelease(&_WaitSetLock);
 
-  if ((SyncFlags & 4) == 0) {
-    _Responsible = NULL;
-  }
+  _Responsible = NULL;
+
   intptr_t save = _recursions; // record the old recursion count
   _waiters++;                  // increment the number of waiters
   _recursions = 0;             // set the recursion level to be 1
@@ -1622,16 +1579,11 @@
   assert(_succ != Self, "invariant");
   assert(((oop)(object()))->mark() == markOopDesc::encode(this), "invariant");
 
-  if (SyncFlags & 32) {
-    OrderAccess::fence();
-  }
-
   // check if the notification happened
   if (!WasNotified) {
     // no, it could be timeout or Thread.interrupt() or both
     // check for interrupt event, otherwise it is timeout
     if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
-      TEVENT(Wait - throw IEX from epilog);
       THROW(vmSymbols::java_lang_InterruptedException());
     }
   }
@@ -1652,7 +1604,6 @@
   Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
   ObjectWaiter * iterator = DequeueWaiter();
   if (iterator != NULL) {
-    TEVENT(Notify1 - Transfer);
     guarantee(iterator->TState == ObjectWaiter::TS_WAIT, "invariant");
     guarantee(iterator->_notified == 0, "invariant");
     // Disposition - what might we do with iterator ?
@@ -1759,14 +1710,11 @@
 // Note: We can also detect many such problems with a "minimum wait".
 // When the "minimum wait" is set to a small non-zero timeout value
 // and the program does not hang whereas it did absent "minimum wait",
-// that suggests a lost wakeup bug. The '-XX:SyncFlags=1' option uses
-// a "minimum wait" for all park() operations; see the recheckInterval
-// variable and MAX_RECHECK_INTERVAL.
+// that suggests a lost wakeup bug.
 
 void ObjectMonitor::notify(TRAPS) {
   CHECK_OWNER();
   if (_WaitSet == NULL) {
-    TEVENT(Empty-Notify);
     return;
   }
   DTRACE_MONITOR_PROBE(notify, this, object(), THREAD);
@@ -1785,7 +1733,6 @@
 void ObjectMonitor::notifyAll(TRAPS) {
   CHECK_OWNER();
   if (_WaitSet == NULL) {
-    TEVENT(Empty-NotifyAll);
     return;
   }
 
@@ -1912,14 +1859,12 @@
 
   if (Knob_SuccRestrict && _succ != NULL) return 0;
   if (Knob_OState && NotRunnable (Self, (Thread *) _owner)) {
-    TEVENT(Spin abort - notrunnable [TOP]);
     return 0;
   }
 
   int MaxSpin = Knob_MaxSpinners;
   if (MaxSpin >= 0) {
     if (_Spinner > MaxSpin) {
-      TEVENT(Spin abort -- too many spinners);
       return 0;
     }
     // Slightly racy, but benign ...
@@ -1956,7 +1901,6 @@
     // We periodically check to see if there's a safepoint pending.
     if ((ctr & 0xFF) == 0) {
       if (SafepointMechanism::poll(Self)) {
-        TEVENT(Spin: safepoint);
         goto Abort;           // abrupt spin egress
       }
       if (Knob_UsePause & 1) SpinPause();
@@ -2029,7 +1973,6 @@
       // * exit spin without prejudice.
       // * Since CAS is high-latency, retry again immediately.
       prv = ox;
-      TEVENT(Spin: cas failed);
       if (caspty == -2) break;
       if (caspty == -1) goto Abort;
       ctr -= caspty;
@@ -2038,7 +1981,6 @@
 
     // Did lock ownership change hands ?
     if (ox != prv && prv != NULL) {
-      TEVENT(spin: Owner changed)
       if (oxpty == -2) break;
       if (oxpty == -1) goto Abort;
       ctr -= oxpty;
@@ -2050,7 +1992,6 @@
     // Spinning while the owner is OFFPROC is idiocy.
     // Consider: ctr -= RunnablePenalty ;
     if (Knob_OState && NotRunnable (Self, ox)) {
-      TEVENT(Spin abort - notrunnable);
       goto Abort;
     }
     if (sss && _succ == NULL) _succ = Self;
@@ -2059,7 +2000,6 @@
   // Spin failed with prejudice -- reduce _SpinDuration.
   // TODO: Use an AIMD-like policy to adjust _SpinDuration.
   // AIMD is globally stable.
-  TEVENT(Spin failure);
   {
     int x = _SpinDuration;
     if (x > 0) {
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Thu Sep 13 10:54:11 2018 -0700
@@ -321,21 +321,4 @@
   bool      ExitSuspendEquivalent(JavaThread * Self);
 };
 
-#undef TEVENT
-#define TEVENT(nom) { if (SyncVerbose) FEVENT(nom); }
-
-#define FEVENT(nom)                             \
-  {                                             \
-    static volatile int ctr = 0;                \
-    int v = ++ctr;                              \
-    if ((v & (v - 1)) == 0) {                   \
-      tty->print_cr("INFO: " #nom " : %d", v);  \
-      tty->flush();                             \
-    }                                           \
-  }
-
-#undef  TEVENT
-#define TEVENT(nom) {;}
-
-
 #endif // SHARE_VM_RUNTIME_OBJECTMONITOR_HPP
--- a/src/hotspot/share/runtime/synchronizer.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -320,7 +320,6 @@
     // swing the displaced header from the BasicLock back to the mark.
     assert(dhw->is_neutral(), "invariant");
     if (object->cas_set_mark(dhw, mark) == mark) {
-      TEVENT(fast_exit: release stack-lock);
       return;
     }
   }
@@ -345,7 +344,6 @@
     // be visible <= the ST performed by the CAS.
     lock->set_displaced_header(mark);
     if (mark == obj()->cas_set_mark((markOop) lock, mark)) {
-      TEVENT(slow_enter: release stacklock);
       return;
     }
     // Fall through to inflate() ...
@@ -388,7 +386,6 @@
 //  5) lock lock2
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
-  TEVENT(complete_exit);
   if (UseBiasedLocking) {
     BiasedLocking::revoke_and_rebias(obj, false, THREAD);
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
@@ -403,7 +400,6 @@
 
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
-  TEVENT(reenter);
   if (UseBiasedLocking) {
     BiasedLocking::revoke_and_rebias(obj, false, THREAD);
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
@@ -420,7 +416,6 @@
 // NOTE: must use heavy weight monitor to handle jni monitor enter
 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
   // the current locking is from JNI instead of Java code
-  TEVENT(jni_enter);
   if (UseBiasedLocking) {
     BiasedLocking::revoke_and_rebias(obj, false, THREAD);
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
@@ -432,7 +427,6 @@
 
 // NOTE: must use heavy weight monitor to handle jni monitor exit
 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
-  TEVENT(jni_exit);
   if (UseBiasedLocking) {
     Handle h_obj(THREAD, obj);
     BiasedLocking::revoke_and_rebias(h_obj, false, THREAD);
@@ -460,8 +454,6 @@
   _obj = obj;
 
   if (_dolock) {
-    TEVENT(ObjectLocker);
-
     ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);
   }
 }
@@ -482,7 +474,6 @@
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
-    TEVENT(wait - throw IAX);
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
   }
   ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
@@ -505,7 +496,6 @@
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
-    TEVENT(wait - throw IAX);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
   }
   ObjectSynchronizer::inflate(THREAD,
@@ -608,7 +598,6 @@
     if (its > 10000 || !os::is_MP()) {
       if (its & 1) {
         os::naked_yield();
-        TEVENT(Inflate: INFLATING - yield);
       } else {
         // Note that the following code attenuates the livelock problem but is not
         // a complete remedy.  A more complete solution would require that the inflating
@@ -641,7 +630,6 @@
           }
         }
         Thread::muxRelease(gInflationLocks + ix);
-        TEVENT(Inflate: INFLATING - yield/park);
       }
     } else {
       SpinPause();       // SMP-polite spinning
@@ -703,7 +691,6 @@
   value &= markOopDesc::hash_mask;
   if (value == 0) value = 0xBAD;
   assert(value != markOopDesc::no_hash, "invariant");
-  TEVENT(hashCode: GENERATE);
   return value;
 }
 
@@ -1154,7 +1141,6 @@
       Thread::muxRelease(&gListLock);
       Self->omFreeProvision += 1 + (Self->omFreeProvision/2);
       if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE;
-      TEVENT(omFirst - reprovision);
 
       const int mx = MonitorBound;
       if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) {
@@ -1232,7 +1218,6 @@
     temp[_BLOCKSIZE - 1].FreeNext = gFreeList;
     gFreeList = temp + 1;
     Thread::muxRelease(&gListLock);
-    TEVENT(Allocate block of monitors);
   }
 }
 
@@ -1317,7 +1302,6 @@
       guarantee(s->object() == NULL, "invariant");
       guarantee(!s->is_busy(), "invariant");
       s->set_owner(NULL);   // redundant but good hygiene
-      TEVENT(omFlush - Move one);
     }
     guarantee(tail != NULL && list != NULL, "invariant");
   }
@@ -1357,7 +1341,6 @@
   }
 
   Thread::muxRelease(&gListLock);
-  TEVENT(omFlush);
 }
 
 static void post_monitor_inflate_event(EventJavaMonitorInflate* event,
@@ -1422,7 +1405,6 @@
     // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish.
     // We could always eliminate polling by parking the thread on some auxiliary list.
     if (mark == markOopDesc::INFLATING()) {
-      TEVENT(Inflate: spin while INFLATING);
       ReadStableMark(object);
       continue;
     }
@@ -1515,7 +1497,6 @@
       // Hopefully the performance counters are allocated on distinct cache lines
       // to avoid false sharing on MP systems ...
       OM_PERFDATA_OP(Inflations, inc());
-      TEVENT(Inflate: overwrite stacklock);
       if (log_is_enabled(Debug, monitorinflation)) {
         if (object->is_instance()) {
           ResourceMark rm;
@@ -1566,7 +1547,6 @@
     // Hopefully the performance counters are allocated on distinct
     // cache lines to avoid false sharing on MP systems ...
     OM_PERFDATA_OP(Inflations, inc());
-    TEVENT(Inflate: overwrite neutral);
     if (log_is_enabled(Debug, monitorinflation)) {
       if (object->is_instance()) {
         ResourceMark rm;
@@ -1633,7 +1613,6 @@
     // Deflate the monitor if it is no longer being used
     // It's idle - scavenge and return to the global free list
     // plain old deflation ...
-    TEVENT(deflate_idle_monitors - scavenge1);
     if (log_is_enabled(Debug, monitorinflation)) {
       if (obj->is_instance()) {
         ResourceMark rm;
@@ -1719,7 +1698,6 @@
   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
   ObjectMonitor * freeTailp = NULL;
 
-  TEVENT(deflate_idle_monitors);
   // Prevent omFlush from changing mids in Thread dtor's during deflation
   // And in case the vm thread is acquiring a lock during a safepoint
   // See e.g. 6320749
--- a/src/hotspot/share/runtime/thread.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/thread.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -4736,7 +4736,6 @@
   }
 
   // Slow-path : We've encountered contention -- Spin/Yield/Block strategy.
-  TEVENT(SpinAcquire - ctx);
   int ctr = 0;
   int Yields = 0;
   for (;;) {
@@ -4831,7 +4830,6 @@
     return;
   }
 
-  TEVENT(muxAcquire - Contention);
   ParkEvent * const Self = Thread::current()->_MuxEvent;
   assert((intptr_t(Self) & LOCKBIT) == 0, "invariant");
   for (;;) {
@@ -4877,7 +4875,6 @@
     return;
   }
 
-  TEVENT(muxAcquire - Contention);
   ParkEvent * ReleaseAfter = NULL;
   if (ev == NULL) {
     ev = ReleaseAfter = ParkEvent::Allocate(NULL);
--- a/src/hotspot/share/runtime/threadHeapSampler.cpp	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/hotspot/share/runtime/threadHeapSampler.cpp	Thu Sep 13 10:54:11 2018 -0700
@@ -104,8 +104,10 @@
 }
 
 void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) {
-  if (get_sampling_interval() == 1) {
-    _bytes_until_sample = 1;
+  // Explicitly test if the sampling interval is 0, return 0 to sample every
+  // allocation.
+  if (get_sampling_interval() == 0) {
+    _bytes_until_sample = 0;
     return;
   }
 
--- a/src/java.base/share/classes/java/lang/ModuleLayer.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/lang/ModuleLayer.java	Thu Sep 13 10:54:11 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -790,8 +790,7 @@
             // push in reverse order
             for (int i = layer.parents.size() - 1; i >= 0; i--) {
                 ModuleLayer parent = layer.parents.get(i);
-                if (!visited.contains(parent)) {
-                    visited.add(parent);
+                if (visited.add(parent)) {
                     stack.push(parent);
                 }
             }
--- a/src/java.base/share/classes/java/lang/String.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/lang/String.java	Thu Sep 13 10:54:11 2018 -0700
@@ -40,12 +40,15 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.vm.annotation.Stable;
 
+import static java.util.function.Predicate.not;
+
 /**
  * The {@code String} class represents character strings. All
  * string literals in Java programs, such as {@code "abc"}, are
@@ -2755,12 +2758,9 @@
         return indexOfNonWhitespace() == length();
     }
 
-    private int indexOfNonWhitespace() {
-        if (isLatin1()) {
-            return StringLatin1.indexOfNonWhitespace(value);
-        } else {
-            return StringUTF16.indexOfNonWhitespace(value);
-        }
+    private Stream<String> lines(int maxLeading, int maxTrailing) {
+        return isLatin1() ? StringLatin1.lines(value, maxLeading, maxTrailing)
+                          : StringUTF16.lines(value, maxLeading, maxTrailing);
     }
 
     /**
@@ -2794,8 +2794,181 @@
      * @since 11
      */
     public Stream<String> lines() {
-        return isLatin1() ? StringLatin1.lines(value)
-                          : StringUTF16.lines(value);
+        return lines(0, 0);
+    }
+
+    /**
+     * Adjusts the indentation of each line of this string based on the value of
+     * {@code n}, and normalizes line termination characters.
+     * <p>
+     * This string is conceptually separated into lines using
+     * {@link String#lines()}. Each line is then adjusted as described below
+     * and then suffixed with a line feed {@code "\n"} (U+000A). The resulting
+     * lines are then concatenated and returned.
+     * <p>
+     * If {@code n > 0} then {@code n} spaces (U+0020) are inserted at the
+     * beginning of each line. {@link String#isBlank() Blank lines} are
+     * unaffected.
+     * <p>
+     * If {@code n < 0} then up to {@code n}
+     * {@link Character#isWhitespace(int) white space characters} are removed
+     * from the beginning of each line. If a given line does not contain
+     * sufficient white space then all leading
+     * {@link Character#isWhitespace(int) white space characters} are removed.
+     * Each white space character is treated as a single character. In
+     * particular, the tab character {@code "\t"} (U+0009) is considered a
+     * single character; it is not expanded.
+     * <p>
+     * If {@code n == 0} then the line remains unchanged. However, line
+     * terminators are still normalized.
+     * <p>
+     *
+     * @param n  number of leading
+     *           {@link Character#isWhitespace(int) white space characters}
+     *           to add or remove
+     *
+     * @return string with indentation adjusted and line endings normalized
+     *
+     * @see String#lines()
+     * @see String#isBlank()
+     * @see Character#isWhitespace(int)
+     *
+     * @since 12
+     */
+    public String indent(int n) {
+        return isEmpty() ? "" :  indent(n, false);
+    }
+
+    private String indent(int n, boolean removeBlanks) {
+        Stream<String> stream = removeBlanks ? lines(Integer.MAX_VALUE, Integer.MAX_VALUE)
+                                             : lines();
+        if (n > 0) {
+            final String spaces = " ".repeat(n);
+            stream = stream.map(s -> s.isBlank() ? s : spaces + s);
+        } else if (n == Integer.MIN_VALUE) {
+            stream = stream.map(s -> s.stripLeading());
+        } else if (n < 0) {
+            stream = stream.map(s -> s.substring(Math.min(-n, s.indexOfNonWhitespace())));
+        }
+        return stream.collect(Collectors.joining("\n", "", "\n"));
+    }
+
+    private int indexOfNonWhitespace() {
+        return isLatin1() ? StringLatin1.indexOfNonWhitespace(value)
+                          : StringUTF16.indexOfNonWhitespace(value);
+    }
+
+    private int lastIndexOfNonWhitespace() {
+        return isLatin1() ? StringLatin1.lastIndexOfNonWhitespace(value)
+                          : StringUTF16.lastIndexOfNonWhitespace(value);
+    }
+
+    /**
+     * Removes vertical and horizontal white space margins from around the
+     * essential body of a multi-line string, while preserving relative
+     * indentation.
+     * <p>
+     * This string is first conceptually separated into lines as if by
+     * {@link String#lines()}.
+     * <p>
+     * Then, the <i>minimum indentation</i> (min) is determined as follows. For
+     * each non-blank line (as defined by {@link String#isBlank()}), the
+     * leading {@link Character#isWhitespace(int) white space} characters are
+     * counted. The <i>min</i> value is the smallest of these counts.
+     * <p>
+     * For each non-blank line, <i>min</i> leading white space characters are
+     * removed. Each white space character is treated as a single character. In
+     * particular, the tab character {@code "\t"} (U+0009) is considered a
+     * single character; it is not expanded.
+     * <p>
+     * Leading and trailing blank lines, if any, are removed. Trailing spaces are
+     * preserved.
+     * <p>
+     * Each line is suffixed with a line feed character {@code "\n"} (U+000A).
+     * <p>
+     * Finally, the lines are concatenated into a single string and returned.
+     *
+     * @apiNote
+     * This method's primary purpose is to shift a block of lines as far as
+     * possible to the left, while preserving relative indentation. Lines
+     * that were indented the least will thus have no leading white space.
+     *
+     * Example:
+     * <blockquote><pre>
+     * `
+     *      This is the first line
+     *          This is the second line
+     * `.align();
+     *
+     * returns
+     * This is the first line
+     *     This is the second line
+     * </pre></blockquote>
+     *
+     * @return string with margins removed and line terminators normalized
+     *
+     * @see String#lines()
+     * @see String#isBlank()
+     * @see String#indent(int)
+     * @see Character#isWhitespace(int)
+     *
+     * @since 12
+     */
+    public String align() {
+        return align(0);
+    }
+
+    /**
+     * Removes vertical and horizontal white space margins from around the
+     * essential body of a multi-line string, while preserving relative
+     * indentation and with optional indentation adjustment.
+     * <p>
+     * Invoking this method is equivalent to:
+     * <blockquote>
+     *  {@code this.align().indent(n)}
+     * </blockquote>
+     *
+     * @apiNote
+     * Examples:
+     * <blockquote><pre>
+     * `
+     *      This is the first line
+     *          This is the second line
+     * `.align(0);
+     *
+     * returns
+     * This is the first line
+     *     This is the second line
+     *
+     *
+     * `
+     *    This is the first line
+     *       This is the second line
+     * `.align(4);
+     * returns
+     *     This is the first line
+     *         This is the second line
+     * </pre></blockquote>
+     *
+     * @param n  number of leading white space characters
+     *           to add or remove
+     *
+     * @return string with margins removed, indentation adjusted and
+     *         line terminators normalized
+     *
+     * @see String#align()
+     *
+     * @since 12
+     */
+    public String align(int n) {
+        if (isEmpty()) {
+            return "";
+        }
+        int outdent = lines().filter(not(String::isBlank))
+                             .mapToInt(String::indexOfNonWhitespace)
+                             .min()
+                             .orElse(0);
+        return indent(n - outdent, true);
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/StringLatin1.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/lang/StringLatin1.java	Thu Sep 13 10:54:11 2018 -0700
@@ -545,7 +545,7 @@
         int length = value.length;
         int left = 0;
         while (left < length) {
-            char ch = (char)(value[left] & 0xff);
+            char ch = getChar(value, left);
             if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
                 break;
             }
@@ -558,7 +558,7 @@
         int length = value.length;
         int right = length;
         while (0 < right) {
-            char ch = (char)(value[right - 1] & 0xff);
+            char ch = getChar(value, right - 1);
             if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
                 break;
             }
@@ -573,7 +573,8 @@
             return "";
         }
         int right = lastIndexOfNonWhitespace(value);
-        return ((left > 0) || (right < value.length)) ? newString(value, left, right - left) : null;
+        boolean ifChanged = (left > 0) || (right < value.length);
+        return ifChanged ? newString(value, left, right - left) : null;
     }
 
     public static String stripLeading(byte[] value) {
@@ -597,11 +598,7 @@
         private int index;        // current index, modified on advance/split
         private final int fence;  // one past last index
 
-        LinesSpliterator(byte[] value) {
-            this(value, 0, value.length);
-        }
-
-        LinesSpliterator(byte[] value, int start, int length) {
+        private LinesSpliterator(byte[] value, int start, int length) {
             this.value = value;
             this.index = start;
             this.fence = start + length;
@@ -609,7 +606,7 @@
 
         private int indexOfLineSeparator(int start) {
             for (int current = start; current < fence; current++) {
-                byte ch = value[current];
+                char ch = getChar(value, current);
                 if (ch == '\n' || ch == '\r') {
                     return current;
                 }
@@ -619,9 +616,9 @@
 
         private int skipLineSeparator(int start) {
             if (start < fence) {
-                if (value[start] == '\r') {
+                if (getChar(value, start) == '\r') {
                     int next = start + 1;
-                    if (next < fence && value[next] == '\n') {
+                    if (next < fence && getChar(value, next) == '\n') {
                         return next + 1;
                     }
                 }
@@ -680,10 +677,80 @@
         public int characteristics() {
             return Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL;
         }
+
+        static LinesSpliterator spliterator(byte[] value) {
+            return new LinesSpliterator(value, 0, value.length);
+        }
+
+        static LinesSpliterator spliterator(byte[] value, int leading, int trailing) {
+            int length = value.length;
+            int left = 0;
+            int index;
+            for (int l = 0; l < leading; l++) {
+                index = skipBlankForward(value, left, length);
+                if (index == left) {
+                    break;
+                }
+                left = index;
+            }
+            int right = length;
+            for (int t = 0; t < trailing; t++) {
+                index = skipBlankBackward(value, left, right);
+                if (index == right) {
+                    break;
+                }
+                right = index;
+            }
+            return new LinesSpliterator(value, left, right - left);
+        }
+
+        private static int skipBlankForward(byte[] value, int start, int length) {
+            int index = start;
+            while (index < length) {
+                char ch = getChar(value, index++);
+                if (ch == '\n') {
+                    return index;
+                }
+                if (ch == '\r') {
+                    if (index < length && getChar(value, index) == '\n') {
+                        return index + 1;
+                    }
+                    return index;
+                }
+                if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                    return start;
+                }
+            }
+            return length;
+        }
+
+        private static int skipBlankBackward(byte[] value, int start, int fence) {
+            int index = fence;
+            if (start < index && getChar(value, index - 1) == '\n') {
+                index--;
+            }
+            if (start < index && getChar(value, index - 1) == '\r') {
+                index--;
+            }
+            while (start < index) {
+                char ch = getChar(value, --index);
+                if (ch == '\r' || ch == '\n') {
+                    return index + 1;
+                }
+                if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                    return fence;
+                }
+            }
+            return start;
+        }
     }
 
-    static Stream<String> lines(byte[] value) {
-        return StreamSupport.stream(new LinesSpliterator(value), false);
+    static Stream<String> lines(byte[] value, int leading, int trailing) {
+        if (leading == 0 && trailing == 0) {
+            return StreamSupport.stream(LinesSpliterator.spliterator(value), false);
+        } else {
+            return StreamSupport.stream(LinesSpliterator.spliterator(value, leading, trailing), false);
+        }
     }
 
     public static void putChar(byte[] val, int index, int c) {
--- a/src/java.base/share/classes/java/lang/StringUTF16.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/lang/StringUTF16.java	Thu Sep 13 10:54:11 2018 -0700
@@ -859,7 +859,6 @@
             null;
     }
 
-
     public static int indexOfNonWhitespace(byte[] value) {
         int length = value.length >> 1;
         int left = 0;
@@ -874,7 +873,7 @@
     }
 
     public static int lastIndexOfNonWhitespace(byte[] value) {
-        int length = value.length >> 1;
+        int length = value.length >>> 1;
         int right = length;
         while (0 < right) {
             int codepoint = codePointBefore(value, right);
@@ -887,17 +886,18 @@
     }
 
     public static String strip(byte[] value) {
-        int length = value.length >> 1;
+        int length = value.length >>> 1;
         int left = indexOfNonWhitespace(value);
         if (left == length) {
             return "";
         }
         int right = lastIndexOfNonWhitespace(value);
-        return ((left > 0) || (right < length)) ? newString(value, left, right - left) : null;
+        boolean ifChanged = (left > 0) || (right < length);
+        return ifChanged ? newString(value, left, right - left) : null;
     }
 
     public static String stripLeading(byte[] value) {
-        int length = value.length >> 1;
+        int length = value.length >>> 1;
         int left = indexOfNonWhitespace(value);
         if (left == length) {
             return "";
@@ -906,7 +906,7 @@
     }
 
     public static String stripTrailing(byte[] value) {
-        int length = value.length >> 1;
+        int length = value.length >>> 1;
         int right = lastIndexOfNonWhitespace(value);
         if (right == 0) {
             return "";
@@ -919,11 +919,7 @@
         private int index;        // current index, modified on advance/split
         private final int fence;  // one past last index
 
-        LinesSpliterator(byte[] value) {
-            this(value, 0, value.length >>> 1);
-        }
-
-        LinesSpliterator(byte[] value, int start, int length) {
+        private LinesSpliterator(byte[] value, int start, int length) {
             this.value = value;
             this.index = start;
             this.fence = start + length;
@@ -1002,10 +998,80 @@
         public int characteristics() {
             return Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL;
         }
+
+        static LinesSpliterator spliterator(byte[] value) {
+            return new LinesSpliterator(value, 0, value.length >>> 1);
+        }
+
+        static LinesSpliterator spliterator(byte[] value, int leading, int trailing) {
+            int length = value.length >>> 1;
+            int left = 0;
+            int index;
+            for (int l = 0; l < leading; l++) {
+                index = skipBlankForward(value, left, length);
+                if (index == left) {
+                    break;
+                }
+                left = index;
+            }
+            int right = length;
+            for (int t = 0; t < trailing; t++) {
+                index = skipBlankBackward(value, left, right);
+                if (index == right) {
+                    break;
+                }
+                right = index;
+            }
+            return new LinesSpliterator(value, left, right - left);
+        }
+
+        private static int skipBlankForward(byte[] value, int start, int length) {
+            int index = start;
+            while (index < length) {
+                char ch = getChar(value, index++);
+                if (ch == '\n') {
+                    return index;
+                }
+                if (ch == '\r') {
+                    if (index < length && getChar(value, index) == '\n') {
+                        return index + 1;
+                    }
+                    return index;
+                }
+                if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                    return start;
+                }
+            }
+            return length;
+        }
+
+        private static int skipBlankBackward(byte[] value, int start, int fence) {
+            int index = fence;
+            if (start < index && getChar(value, index - 1) == '\n') {
+                index--;
+            }
+            if (start < index && getChar(value, index - 1) == '\r') {
+                index--;
+            }
+            while (start < index) {
+                char ch = getChar(value, --index);
+                if (ch == '\r' || ch == '\n') {
+                    return index + 1;
+                }
+                if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                    return fence;
+                }
+            }
+            return start;
+        }
     }
 
-    static Stream<String> lines(byte[] value) {
-        return StreamSupport.stream(new LinesSpliterator(value), false);
+    static Stream<String> lines(byte[] value, int leading, int trailing) {
+        if (leading == 0 && trailing == 0) {
+            return StreamSupport.stream(LinesSpliterator.spliterator(value), false);
+        } else {
+            return StreamSupport.stream(LinesSpliterator.spliterator(value, leading, trailing), false);
+        }
     }
 
     private static void putChars(byte[] val, int index, char[] str, int off, int end) {
--- a/src/java.base/share/classes/java/lang/module/Configuration.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/lang/module/Configuration.java	Thu Sep 13 10:54:11 2018 -0700
@@ -601,8 +601,7 @@
                 // push in reverse order
                 for (int i = layer.parents.size() - 1; i >= 0; i--) {
                     Configuration parent = layer.parents.get(i);
-                    if (!visited.contains(parent)) {
-                        visited.add(parent);
+                    if (visited.add(parent)) {
                         stack.push(parent);
                     }
                 }
--- a/src/java.base/share/classes/java/net/CookieManager.java	Wed Sep 12 11:51:39 2018 +0530
+++ b/src/java.base/share/classes/java/net/CookieManager.java	Thu Sep 13 10:54:11 2018 -0700
@@ -241,7 +241,7 @@
         }
 
         // apply sort rule (RFC 2965 sec. 3.3.4)
-        List<String> cookieHeader = sortByPath(cookies);
+        List<String> cookieHeader = sortByPathAndAge(cookies);
 
         return Map.of("Cookie", cookieHeader);
     }
@@ -402,11 +402,12 @@
 
 
     /*
-     * sort cookies with respect to their path: those with more specific Path attributes
-     * precede those with less specific, as defined in RFC 2965 sec. 3.3.4
+     * sort cookies with respect to their path and age: those with more longer Path attributes
+     * precede those with shorter, as defined in RFC 6265. Cookies with the same length
+     * path are distinguished by creation time (older first). Method made PP to enable testing.
      */
-    private List<String> sortByPath(List<HttpCookie> cookies) {
-        Collections.sort(cookies, new CookiePathComparator());
+    static List<String> sortByPathAndAge(List<HttpCookie> cookies) {
+        Collections.sort(cookies, new CookieComparator());
 
         List<String> cookieHeader = new java.util.ArrayList<>();
         for (HttpCookie cookie : cookies) {
@@ -424,22 +425,36 @@
     }
 
 
-    static class CookiePathComparator implements Comparator<HttpCookie> {
+    // Comparator compares the length of the path. Longer paths should precede shorter ones.
+    // As per rfc6265 cookies with equal path lengths sort on creation time.
+
+    static class CookieComparator implements Comparator<HttpCookie> {
         public int compare(HttpCookie c1, HttpCookie c2) {
             if (c1 == c2) return 0;
             if (c1 == null) return -1;