changeset 50149:d93ae85b18c1

Merge
author prr
date Tue, 15 May 2018 10:13:52 -0700
parents 9822dd521c15 1dc98fa30b14
children 1ff7fb9125f8
files make/CreateJmods.gmk src/hotspot/share/runtime/advancedThresholdPolicy.cpp src/hotspot/share/runtime/advancedThresholdPolicy.hpp test/hotspot/jtreg/compiler/tiered/TransitionsTestExecutor.java test/jdk/ProblemList.txt test/jdk/TEST.groups
diffstat 242 files changed, 5077 insertions(+), 2350 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue May 15 18:03:31 2018 +0530
+++ b/.hgignore	Tue May 15 10:13:52 2018 -0700
@@ -13,3 +13,4 @@
 NashornProfile.txt
 .*/JTreport/.*
 .*/JTwork/.*
+.*/.git/.*
--- a/.hgtags	Tue May 15 18:03:31 2018 +0530
+++ b/.hgtags	Tue May 15 10:13:52 2018 -0700
@@ -484,3 +484,4 @@
 69d7398038c54774d9395b6810e0cca335edc02c jdk-11+10
 e1e60f75cd39312a7f59d2a4f91d624e5aecc95e jdk-11+11
 3ab6ba9f94a9045a526d645af26c933235371d6f jdk-11+12
+758deedaae8406ae60147486107a54e9864aa7b0 jdk-11+13
--- a/make/CreateJmods.gmk	Tue May 15 18:03:31 2018 +0530
+++ b/make/CreateJmods.gmk	Tue May 15 10:13:52 2018 -0700
@@ -121,11 +121,21 @@
   ifeq ($(OPENJDK_TARGET_OS), windows)
     # Only java.base needs to include the MSVC*_DLLs. Make sure no other module
     # tries to include them (typically imported ones).
-    ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCR_DLL))), )
-      JMOD_FLAGS += --exclude '$(notdir $(MSVCR_DLL))'
+    ifneq ($(MSVCR_DLL), )
+      ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCR_DLL))), )
+        JMOD_FLAGS += --exclude '$(notdir $(MSVCR_DLL))'
+      endif
     endif
-    ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCP_DLL))), )
-      JMOD_FLAGS += --exclude '$(notdir $(MSVCP_DLL))'
+    ifneq ($(MSVCP_DLL), )
+      ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCP_DLL))), )
+        JMOD_FLAGS += --exclude '$(notdir $(MSVCP_DLL))'
+      endif
+    endif
+    ifneq ($(UCRT_DLL_DIR), )
+      UCRT_DLL_FILES := $(notdir $(wildcard $(UCRT_DLL_DIR)/*.dll))
+      ifneq ($(wildcard $(LIBS_DIR)/$(firstword $(UCRT_DLL_FILES))), )
+        JMOD_FLAGS += $(patsubst %, --exclude '%', $(UCRT_DLL_FILES))
+      endif
     endif
   endif
 endif
--- a/make/autoconf/basics.m4	Tue May 15 18:03:31 2018 +0530
+++ b/make/autoconf/basics.m4	Tue May 15 10:13:52 2018 -0700
@@ -671,6 +671,8 @@
       BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_MSVCR_DLL])
       # Corresponds to --with-msvcp-dll
       BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_MSVCP_DLL])
+      # Corresponds to --with-ucrt-dll-dir
+      BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_UCRT_DLL_DIR])
     fi
 
     AC_MSG_CHECKING([for devkit])
--- a/make/autoconf/hotspot.m4	Tue May 15 18:03:31 2018 +0530
+++ b/make/autoconf/hotspot.m4	Tue May 15 10:13:52 2018 -0700
@@ -206,7 +206,7 @@
 
   if test "x$ENABLE_AOT" = "xtrue"; then
     # Only enable AOT on X64 platforms.
-    if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
+    if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
       if test -e "${TOPDIR}/src/jdk.aot"; then
         if test -e "${TOPDIR}/src/jdk.internal.vm.compiler"; then
           ENABLE_AOT="true"
--- a/make/autoconf/spec.gmk.in	Tue May 15 18:03:31 2018 +0530
+++ b/make/autoconf/spec.gmk.in	Tue May 15 10:13:52 2018 -0700
@@ -736,6 +736,7 @@
 LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@
 MSVCR_DLL:=@MSVCR_DLL@
 MSVCP_DLL:=@MSVCP_DLL@
+UCRT_DLL_DIR:=@UCRT_DLL_DIR@
 STLPORT_LIB:=@STLPORT_LIB@
 
 ####################################################
--- a/make/autoconf/toolchain_windows.m4	Tue May 15 18:03:31 2018 +0530
+++ b/make/autoconf/toolchain_windows.m4	Tue May 15 10:13:52 2018 -0700
@@ -76,6 +76,7 @@
 VS_MSVCR_2017=vcruntime140.dll
 VS_MSVCP_2017=msvcp140.dll
 VS_ENVVAR_2017="VS150COMNTOOLS"
+VS_USE_UCRT_2017="true"
 VS_VS_INSTALLDIR_2017="Microsoft Visual Studio/2017"
 VS_EDITIONS_2017="BuildTools Community Professional Enterprise"
 VS_SDK_INSTALLDIR_2017=
@@ -264,6 +265,7 @@
     eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}"
     eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}"
     eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}"
+    eval USE_UCRT="\${VS_USE_UCRT_${VS_VERSION}}"
     eval PLATFORM_TOOLSET="\${VS_VS_PLATFORM_NAME_${VS_VERSION}}"
     VS_PATH="$TOOLCHAIN_PATH:$PATH"
 
@@ -309,6 +311,7 @@
       eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}"
       eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}"
       eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}"
+      eval USE_UCRT="\${VS_USE_UCRT_${VS_VERSION}}"
       # The rest of the variables are already evaled while probing
       AC_MSG_NOTICE([Found $VS_DESCRIPTION])
       break
@@ -432,8 +435,11 @@
       VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED -e 's/\\\\*;* *$//'`
       VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\*;* *$//'`
       VCINSTALLDIR=`$ECHO "$VCINSTALLDIR" | $SED 's/\\\\* *$//'`
-      WindowsSDKDir=`$ECHO "$WindowsSDKDir" | $SED 's/\\\\* *$//'`
+      WindowsSdkDir=`$ECHO "$WindowsSdkDir" | $SED 's/\\\\* *$//'`
       WINDOWSSDKDIR=`$ECHO "$WINDOWSSDKDIR" | $SED 's/\\\\* *$//'`
+      if test -z "$WINDOWSSDKDIR"; then
+        WINDOWSSDKDIR="$WindowsSdkDir"
+      fi
       # Remove any paths containing # (typically F#) as that messes up make. This
       # is needed if visual studio was installed with F# support.
       VS_PATH=`$ECHO "$VS_PATH" | $SED 's/[[^:#]]*#[^:]*://g'`
@@ -539,7 +545,7 @@
   if test "x$MSVC_DLL" = x; then
     if test "x$VCINSTALLDIR" != x; then
       CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR"
-      BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VC_INSTALL_DIR)
+      BASIC_FIXUP_PATH(CYGWIN_VC_INSTALL_DIR)
       if test "$VS_VERSION" -lt 2017; then
         # Probe: Using well-known location from Visual Studio 12.0 and older
         if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
@@ -673,4 +679,41 @@
     fi
     AC_SUBST(MSVCP_DLL)
   fi
+
+  AC_ARG_WITH(ucrt-dll-dir, [AS_HELP_STRING([--with-ucrt-dll-dir],
+      [path to Microsoft Windows Kit UCRT DLL dir (Windows only) @<:@probed@:>@])])
+
+  if test "x$USE_UCRT" = "xtrue"; then
+    AC_MSG_CHECKING([for UCRT DLL dir])
+    if test "x$with_ucrt_dll_dir" != x; then
+      if test -z "$(ls -d "$with_ucrt_dll_dir/*.dll" 2> /dev/null)"; then
+        AC_MSG_RESULT([no])
+        AC_MSG_ERROR([Could not find any dlls in $with_ucrt_dll_dir])
+      else
+        AC_MSG_RESULT([$with_ucrt_dll_dir])
+        UCRT_DLL_DIR="$with_ucrt_dll_dir"
+        BASIC_FIXUP_PATH([UCRT_DLL_DIR])
+      fi
+    elif test "x$DEVKIT_UCRT_DLL_DIR" != "x"; then
+      UCRT_DLL_DIR="$DEVKIT_UCRT_DLL_DIR"
+      AC_MSG_RESULT($UCRT_DLL_DIR)
+    else
+      CYGWIN_WINDOWSSDKDIR="${WINDOWSSDKDIR}"
+      BASIC_FIXUP_PATH([CYGWIN_WINDOWSSDKDIR])
+      dll_subdir=$OPENJDK_TARGET_CPU
+      if test "x$dll_subdir" = "xx86_64"; then
+        dll_subdir="x64"
+      fi
+      UCRT_DLL_DIR="$CYGWIN_WINDOWSSDKDIR/Redist/ucrt/DLLs/$dll_subdir"
+      if test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then
+        AC_MSG_RESULT([no])
+        AC_MSG_ERROR([Could not find any dlls in $UCRT_DLL_DIR])
+      else
+        AC_MSG_RESULT($UCRT_DLL_DIR)
+      fi
+    fi
+  else
+    UCRT_DLL_DIR=
+  fi
+  AC_SUBST(UCRT_DLL_DIR)
 ])
--- a/make/copy/Copy-java.base.gmk	Tue May 15 18:03:31 2018 +0530
+++ b/make/copy/Copy-java.base.gmk	Tue May 15 10:13:52 2018 -0700
@@ -65,6 +65,17 @@
       MACRO := copy-and-chmod))
 
   TARGETS += $(COPY_MSVCR) $(COPY_MSVCP)
+
+  ifneq ($(UCRT_DLL_DIR), )
+    $(eval $(call SetupCopyFiles, COPY_UCRT_DLLS, \
+        DEST := $(LIB_DST_DIR), \
+        SRC := $(UCRT_DLL_DIR), \
+        FILES := $(wildcard $(UCRT_DLL_DIR)/*.dll), \
+        MACRO := copy-and-chmod, \
+    ))
+
+    TARGETS += $(COPY_UCRT_DLLS)
+  endif
 endif
 
 ################################################################################
@@ -117,23 +128,23 @@
 	$(RM) $(@)
         # Now check for other permutations
         ifeq ($(call check-jvm-variant, server), true)
-	  $(PRINTF) "-server KNOWN\n">>$(@)
-	  $(PRINTF) "-client ALIASED_TO -server\n">>$(@)
+	  $(PRINTF) -- "-server KNOWN\n">>$(@)
+	  $(PRINTF) -- "-client ALIASED_TO -server\n">>$(@)
           ifeq ($(call check-jvm-variant, minimal), true)
-	    $(PRINTF) "-minimal KNOWN\n">>$(@)
+	    $(PRINTF) -- "-minimal KNOWN\n">>$(@)
           endif
         else
           ifeq ($(call check-jvm-variant, client), true)
-	    $(PRINTF) "-client KNOWN\n">>$(@)
-	    $(PRINTF) "-server ALIASED_TO -client\n">>$(@)
+	    $(PRINTF) -- "-client KNOWN\n">>$(@)
+	    $(PRINTF) -- "-server ALIASED_TO -client\n">>$(@)
             ifeq ($(call check-jvm-variant, minimal), true)
-	      $(PRINTF) "-minimal KNOWN\n">>$(@)
+	      $(PRINTF) -- "-minimal KNOWN\n">>$(@)
             endif
           else
             ifeq ($(call check-jvm-variant, minimal), true)
-	      $(PRINTF) "-minimal KNOWN\n">>$(@)
-	      $(PRINTF) "-server ALIASED_TO -minimal\n">>$(@)
-	      $(PRINTF) "-client ALIASED_TO -minimal\n">>$(@)
+	      $(PRINTF) -- "-minimal KNOWN\n">>$(@)
+	      $(PRINTF) -- "-server ALIASED_TO -minimal\n">>$(@)
+	      $(PRINTF) -- "-client ALIASED_TO -minimal\n">>$(@)
             endif
           endif
         endif
--- a/make/devkit/createWindowsDevkit2017.sh	Tue May 15 18:03:31 2018 +0530
+++ b/make/devkit/createWindowsDevkit2017.sh	Tue May 15 10:13:52 2018 -0700
@@ -130,6 +130,8 @@
     cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
     cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/
     cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/
+    mkdir -p $DEVKIT_ROOT/$SDK_VERSION/Redist
+    cp -r "$SDK_INSTALL_DIR/Redist/ucrt" $DEVKIT_ROOT/$SDK_VERSION/Redist/
     mkdir -p $DEVKIT_ROOT/$SDK_VERSION/include
     cp -r "$SDK_INSTALL_DIR/include/$SDK_FULL_VERSION/"* $DEVKIT_ROOT/$SDK_VERSION/include/
 fi
@@ -152,12 +154,14 @@
 echo-info "DEVKIT_VS_LIB_x86=\"\$DEVKIT_ROOT/VC/lib/x86;\$DEVKIT_ROOT/VC/atlmfc/lib/x86;\$DEVKIT_ROOT/$SDK_VERSION/lib/x86\""
 echo-info "DEVKIT_MSVCR_DLL_x86=\"\$DEVKIT_ROOT/VC/redist/x86/$MSVCR_DLL\""
 echo-info "DEVKIT_MSVCP_DLL_x86=\"\$DEVKIT_ROOT/VC/redist/x86/$MSVCP_DLL\""
+echo-info "DEVKIT_UCRT_DLL_DIR_x86=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x86\""
 echo-info ""
 echo-info "DEVKIT_TOOLCHAIN_PATH_x86_64=\"\$DEVKIT_ROOT/VC/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x86\""
 echo-info "DEVKIT_VS_INCLUDE_x86_64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\""
 echo-info "DEVKIT_VS_LIB_x86_64=\"\$DEVKIT_ROOT/VC/lib/x64;\$DEVKIT_ROOT/VC/atlmfc/lib/x64;\$DEVKIT_ROOT/$SDK_VERSION/lib/x64\""
 echo-info "DEVKIT_MSVCR_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL\""
 echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\""
+echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\""
 
 ################################################################################
 # Copy this script
--- a/make/hotspot/lib/JvmFeatures.gmk	Tue May 15 18:03:31 2018 +0530
+++ b/make/hotspot/lib/JvmFeatures.gmk	Tue May 15 10:13:52 2018 -0700
@@ -128,8 +128,9 @@
 ifneq ($(call check-jvm-feature, aot), true)
   JVM_CFLAGS_FEATURES += -DINCLUDE_AOT=0
   JVM_EXCLUDE_FILES += \
-      compiledIC_aot_x86_64.cpp compilerRuntime.cpp \
-      aotCodeHeap.cpp aotCompiledMethod.cpp aotLoader.cpp compiledIC_aot.cpp
+      compiledIC_aot_x86_64.cpp compiledIC_aot_aarch64.cpp      \
+      compilerRuntime.cpp aotCodeHeap.cpp aotCompiledMethod.cpp \
+      aotLoader.cpp compiledIC_aot.cpp
 endif
 
 ifneq ($(call check-jvm-feature, cmsgc), true)
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Tue May 15 18:03:31 2018 +0530
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Tue May 15 10:13:52 2018 -0700
@@ -109,6 +109,7 @@
     private static final String[] AVAILABLE_TZIDS = TimeZone.getAvailableIDs();
     private static String zoneNameTempFile;
     private static String tzDataDir;
+    private static final Map<String, String> canonicalTZMap = new HashMap<>();
 
     static enum DraftType {
         UNCONFIRMED,
@@ -439,6 +440,15 @@
         // Parse timezone
         handlerTimeZone = new TimeZoneParseHandler();
         parseLDMLFile(new File(TIMEZONE_SOURCE_FILE), handlerTimeZone);
+
+        // canonical tz name map
+        // alias -> primary
+        handlerTimeZone.getData().forEach((k, v) -> {
+            String[] ids = ((String)v).split("\\s");
+            for (int i = 1; i < ids.length; i++) {
+                canonicalTZMap.put(ids[i], ids[0]);
+            }
+        });
     }
 
     private static void parseLDMLFile(File srcfile, AbstractLDMLHandler handler) throws Exception {
@@ -658,7 +668,27 @@
                     handlerMetaZones.get(tzid) == null ||
                     handlerMetaZones.get(tzid) != null &&
                     map.get(METAZONE_ID_PREFIX + handlerMetaZones.get(tzid)) == null) {
-                    // First, check the CLDR meta key
+
+                    // First, check the alias
+                    String canonID = canonicalTZMap.get(tzid);
+                    if (canonID != null && !tzid.equals(canonID)) {
+                        Object value = map.get(TIMEZONE_ID_PREFIX + canonID);
+                        if (value != null) {
+                            names.put(tzid, value);
+                            return;
+                        } else {
+                            String meta = handlerMetaZones.get(canonID);
+                            if (meta != null) {
+                                value = map.get(METAZONE_ID_PREFIX + meta);
+                                if (value != null) {
+                                    names.put(tzid, meta);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+
+                    // Check the CLDR meta key
                     Optional<Map.Entry<String, String>> cldrMeta =
                         handlerMetaZones.getData().entrySet().stream()
                             .filter(me ->
@@ -666,7 +696,7 @@
                                     (String[])map.get(METAZONE_ID_PREFIX + me.getValue())))
                             .findAny();
                     cldrMeta.ifPresentOrElse(meta -> names.put(tzid, meta.getValue()), () -> {
-                        // check the JRE meta key, add if there is not.
+                        // Check the JRE meta key, add if there is not.
                         Optional<Map.Entry<String[], String>> jreMeta =
                             jreMetaMap.entrySet().stream()
                                 .filter(jm -> Arrays.deepEquals(data, jm.getKey()))
@@ -1024,16 +1054,9 @@
     }
 
     private static Stream<String> zidMapEntry() {
-        Map<String, String> canonMap = new HashMap<>();
-        handlerTimeZone.getData().entrySet().stream()
-            .forEach(e -> {
-                String[] ids = ((String)e.getValue()).split("\\s");
-                for (int i = 1; i < ids.length; i++) {
-                    canonMap.put(ids[i], ids[0]);
-                }});
         return ZoneId.getAvailableZoneIds().stream()
                 .map(id -> {
-                    String canonId = canonMap.getOrDefault(id, id);
+                    String canonId = canonicalTZMap.getOrDefault(id, id);
                     String meta = handlerMetaZones.get(canonId);
                     String zone001 = handlerMetaZones.zidMap().get(meta);
                     return zone001 == null ? "" :
--- a/make/langtools/build.properties	Tue May 15 18:03:31 2018 +0530
+++ b/make/langtools/build.properties	Tue May 15 10:13:52 2018 -0700
@@ -24,9 +24,7 @@
 #
 
 #javac configuration for "normal build" (these will be passed to the bootstrap compiler):
-javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options,-exports -Werror -g:source,lines,vars
-javac.source = 9
-javac.target = 9
+javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-exports -Werror -g:source,lines,vars
 
 #version used to compile build tools
 javac.build.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
--- a/make/langtools/build.xml	Tue May 15 18:03:31 2018 +0530
+++ b/make/langtools/build.xml	Tue May 15 10:13:52 2018 -0700
@@ -232,7 +232,6 @@
         <pathconvert pathsep=" " property="source.files" refid="source.fileset"/>
         <echo file="${build.dir}/sources.txt">${source.files}</echo>
         <exec executable="${langtools.jdk.home}/bin/javac" failonerror="true">
-            <arg line="-source ${javac.source} -target ${javac.target}" />
             <arg value="-d" />
             <arg value="${build.modules}" />
             <arg line="${javac.opts}" />
--- a/make/launcher/Launcher-jdk.aot.gmk	Tue May 15 18:03:31 2018 +0530
+++ b/make/launcher/Launcher-jdk.aot.gmk	Tue May 15 10:13:52 2018 -0700
@@ -41,6 +41,7 @@
     , \
     JAVA_ARGS := --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
         --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.amd64=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
+        --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
         --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.sparc=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
         --add-exports=jdk.internal.vm.ci/jdk.vm.ci.meta=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
         --add-exports=jdk.internal.vm.ci/jdk.vm.ci.runtime=$(call CommaList, jdk.internal.vm.compiler  jdk.aot) \
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Tue May 15 10:13:52 2018 -0700
@@ -2410,7 +2410,8 @@
 #define INSN(NAME, opcode)                                              \
   void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
     starti;                                                             \
-    f(0, 31), f(0b001110, 29, 24), f(0, 21), f(0b001110, 15, 10);       \
+    f(0, 31), f(0b001110, 29, 24), f(0, 21), f(0, 15);                  \
+    f(opcode, 14, 12), f(0b10, 11, 10);                                 \
     rf(Vm, 16), rf(Vn, 5), rf(Vd, 0);                                   \
     f(T & 1, 30), f(T >> 1, 23, 22);                                    \
   }
--- a/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c1_CodeStubs_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -48,11 +48,14 @@
   __ b(_continuation);
 }
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception)
-  : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
-  , _index(index)
-{
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
+
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
   assert(info != NULL, "must have info");
   _info = new CodeEmitInfo(info);
 }
@@ -69,14 +72,16 @@
   }
 
   if (_index->is_cpu_register()) {
-    __ mov(rscratch1, _index->as_register());
+    __ mov(r22, _index->as_register());
   } else {
-    __ mov(rscratch1, _index->as_jint());
+    __ mov(r22, _index->as_jint());
   }
   Runtime1::StubID stub_id;
   if (_throw_index_out_of_bounds_exception) {
     stub_id = Runtime1::throw_index_exception_id;
   } else {
+    assert(_array != NULL, "sanity");
+    __ mov(r23, _array->as_pointer_register());
     stub_id = Runtime1::throw_range_check_failed_id;
   }
   __ far_call(RuntimeAddress(Runtime1::entry_for(stub_id)), NULL, rscratch2);
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2807,7 +2807,8 @@
 }
 
 
-void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) {
+void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(patch_code == lir_patch_none, "Patch code not supported");
   __ lea(dest->as_register_lo(), as_Address(addr->as_address_ptr()));
 }
 
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -323,7 +323,7 @@
 
 
 // target: the entry point of the method that creates and posts the exception oop
-// has_argument: true if the exception needs an argument (passed in rscratch1)
+// has_argument: true if the exception needs arguments (passed in r22 and r23)
 
 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
   // make a frame and preserve the caller's caller-save registers
@@ -332,7 +332,7 @@
   if (!has_argument) {
     call_offset = __ call_RT(noreg, noreg, target);
   } else {
-    call_offset = __ call_RT(noreg, noreg, target, rscratch1);
+    call_offset = __ call_RT(noreg, noreg, target, r22, r23);
   }
   OopMapSet* oop_maps = new OopMapSet();
   oop_maps->add_gc_map(call_offset, oop_map);
--- a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,8 +56,17 @@
   }
   // static stub relocation stores the instruction address of the call
   __ relocate(static_stub_Relocation::spec(mark));
-  // static stub relocation also tags the Method* in the code-stream.
+
+#if INCLUDE_AOT
+  // Don't create a Metadata reloc if we're generating immutable PIC.
+  if (cbuf.immutable_PIC()) {
+    __ movptr(rmethod, 0);
+  } else {
+    __ mov_metadata(rmethod, (Metadata*)NULL);
+  }
+#else
   __ mov_metadata(rmethod, (Metadata*)NULL);
+#endif
   __ movptr(rscratch1, 0);
   __ br(rscratch1);
 
@@ -83,6 +92,61 @@
   return 4; // 3 in emit_to_interp_stub + 1 in emit_call
 }
 
+#if INCLUDE_AOT
+#define __ _masm.
+void CompiledStaticCall::emit_to_aot_stub(CodeBuffer &cbuf, address mark) {
+  if (!UseAOT) {
+    return;
+  }
+  // Stub is fixed up when the corresponding call is converted from
+  // calling compiled code to calling aot code.
+  // mov r, imm64_aot_code_address
+  // jmp r
+
+  if (mark == NULL) {
+    mark = cbuf.insts_mark();  // Get mark within main instrs section.
+  }
+
+  // Note that the code buffer's insts_mark is always relative to insts.
+  // That's why we must use the macroassembler to generate a stub.
+  MacroAssembler _masm(&cbuf);
+
+  address base =
+  __ start_a_stub(to_aot_stub_size());
+  guarantee(base != NULL, "out of space");
+
+  // Static stub relocation stores the instruction address of the call.
+  __ relocate(static_stub_Relocation::spec(mark, true /* is_aot */));
+  // Load destination AOT code address.
+  __ movptr(rscratch1, 0);  // address is zapped till fixup time.
+  // This is recognized as unresolved by relocs/nativeinst/ic code.
+  __ br(rscratch1);
+
+  assert(__ pc() - base <= to_aot_stub_size(), "wrong stub size");
+
+  // Update current stubs pointer and restore insts_end.
+  __ end_a_stub();
+}
+#undef __
+
+int CompiledStaticCall::to_aot_stub_size() {
+  if (UseAOT) {
+    return 5 * 4;  // movz; movk; movk; movk; br
+  } else {
+    return 0;
+  }
+}
+
+// Relocation entries for call stub, compiled java to aot.
+int CompiledStaticCall::reloc_to_aot_stub() {
+  if (UseAOT) {
+    return 5 * 4;  // movz; movk; movk; movk; br
+  } else {
+    return 0;
+  }
+}
+#endif // INCLUDE_AOT
+
 void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) {
   address stub = find_stub(false /* is_aot */);
   guarantee(stub != NULL, "stub not found");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/cpu/aarch64/compiledIC_aot_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "aot/compiledIC_aot.hpp"
+#include "code/codeCache.hpp"
+#include "memory/resourceArea.hpp"
+
+void CompiledDirectStaticCall::set_to_far(const methodHandle& callee, address entry) {
+  if (TraceICs) {
+    ResourceMark rm;
+    tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_far %s",
+                  p2i(instruction_address()),
+                  callee->name_and_sig_as_C_string());
+  }
+
+  set_destination_mt_safe(entry);
+}
+
+void CompiledPltStaticCall::set_to_interpreted(const methodHandle& callee, address entry) {
+  address stub = find_stub();
+  guarantee(stub != NULL, "stub not found");
+  if (TraceICs) {
+    ResourceMark rm;
+    tty->print_cr("CompiledPltStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
+                  p2i(instruction_address()),
+                  callee->name_and_sig_as_C_string());
+  }
+
+  // Creation also verifies the object.
+  NativeLoadGot* method_loader = nativeLoadGot_at(stub);
+  NativeGotJump* jump          = nativeGotJump_at(method_loader->next_instruction_address());
+
+  intptr_t data = method_loader->data();
+  address destination = jump->destination();
+  assert(data == 0 || data == (intptr_t)callee(),
+         "a) MT-unsafe modification of inline cache");
+  assert(destination == (address)Universe::non_oop_word()
+         || destination == entry,
+         "b) MT-unsafe modification of inline cache");
+
+  // Update stub.
+  method_loader->set_data((intptr_t)callee());
+  jump->set_jump_destination(entry);
+
+  // Update jump to call.
+  set_destination_mt_safe(stub);
+}
+
+#ifdef NEVER_CALLED
+void CompiledPltStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
+  assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
+  // Reset stub.
+  address stub = static_stub->addr();
+  assert(stub != NULL, "stub not found");
+  // Creation also verifies the object.
+  NativeLoadGot* method_loader = nativeLoadGot_at(stub);
+  NativeGotJump* jump          = nativeGotJump_at(method_loader->next_instruction_address());
+  method_loader->set_data(0);
+  jump->set_jump_destination((address)-1);
+}
+#endif
+
+#ifndef PRODUCT
+void CompiledPltStaticCall::verify() {
+  // Verify call.
+  _call->verify();
+
+#ifdef ASSERT
+  CodeBlob *cb = CodeCache::find_blob_unsafe((address) _call);
+  assert(cb && cb->is_aot(), "CompiledPltStaticCall can only be used on AOTCompiledMethod");
+#endif
+
+  // Verify stub.
+  address stub = find_stub();
+  assert(stub != NULL, "no stub found for static call");
+  // Creation also verifies the object.
+  NativeLoadGot*     method_loader = nativeLoadGot_at(stub);
+  NativeGotJump*     jump          = nativeGotJump_at(method_loader->next_instruction_address());
+  // Verify state.
+  assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
+}
+#endif // !PRODUCT
--- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -116,7 +116,7 @@
 
   // Do we need to load the previous value?
   if (obj != noreg) {
-    __ load_heap_oop(pre_val, Address(obj, 0));
+    __ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW);
   }
 
   // Is the previous value null?
@@ -294,7 +294,7 @@
                        false /* expand_call */);
 
   if (val == noreg) {
-    __ store_heap_oop_null(Address(r3, 0));
+    BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), noreg, noreg, noreg);
   } else {
     // G1 barrier needs uncompressed oop for region cross check.
     Register new_val = val;
@@ -302,7 +302,7 @@
       new_val = rscratch2;
       __ mov(new_val, val);
     }
-    __ store_heap_oop(Address(r3, 0), val);
+    BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), val, noreg, noreg);
     g1_write_barrier_post(masm,
                           r3 /* store_adr */,
                           new_val /* new_val */,
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -35,11 +35,21 @@
 
   bool on_heap = (decorators & IN_HEAP) != 0;
   bool on_root = (decorators & IN_ROOT) != 0;
+  bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
   switch (type) {
   case T_OBJECT:
   case T_ARRAY: {
     if (on_heap) {
-      __ load_heap_oop(dst, src);
+      if (UseCompressedOops) {
+        __ ldrw(dst, src);
+        if (oop_not_null) {
+          __ decode_heap_oop_not_null(dst);
+        } else {
+          __ decode_heap_oop(dst);
+        }
+      } else {
+        __ ldr(dst, src);
+      }
     } else {
       assert(on_root, "why else?");
       __ ldr(dst, src);
@@ -57,8 +67,17 @@
   switch (type) {
   case T_OBJECT:
   case T_ARRAY: {
+    val = val == noreg ? zr : val;
     if (on_heap) {
-      __ store_heap_oop(dst, val);
+      if (UseCompressedOops) {
+        assert(!dst.uses(val), "not enough registers");
+        if (val != zr) {
+          __ encode_heap_oop(val);
+        }
+        __ strw(val, dst);
+      } else {
+        __ str(val, dst);
+      }
     } else {
       assert(on_root, "why else?");
       __ str(val, dst);
--- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -90,13 +90,14 @@
 
 void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                                 Address dst, Register val, Register tmp1, Register tmp2) {
+  bool in_heap = (decorators & IN_HEAP) != 0;
   bool on_array = (decorators & IN_HEAP_ARRAY) != 0;
   bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
   bool precise = on_array || on_anonymous;
-  if (val == noreg) {
-    __ store_heap_oop_null(dst);
-  } else {
-    __ store_heap_oop(dst, val);
+
+  bool needs_post_barrier = val != noreg && in_heap;
+  BarrierSetAssembler::store_at(masm, decorators, type, dst, val, noreg, noreg);
+  if (needs_post_barrier) {
     // flatten object address if needed
     if (!precise || (dst.index() == noreg && dst.offset() == 0)) {
       store_check(masm, dst.base(), dst);
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -278,8 +278,7 @@
   resolve_oop_handle(result, tmp);
   // Add in the index
   add(result, result, index);
-  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, /*tmp_thread*/ noreg);
+  load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
 }
 
 void InterpreterMacroAssembler::load_resolved_klass_at_offset(
--- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -35,6 +35,9 @@
     return pc_offset + NativeCall::instruction_size;
   } else if (inst->is_general_jump()) {
     return pc_offset + NativeGeneralJump::instruction_size;
+  } else if (NativeInstruction::is_adrp_at((address)inst)) {
+    // adrp; add; blr
+    return pc_offset + 3 * NativeInstruction::instruction_size;
   } else {
     JVMCI_ERROR_0("unsupported type of instruction for call site");
   }
@@ -81,7 +84,8 @@
 void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
   address pc = _instructions->start() + pc_offset;
   NativeInstruction* inst = nativeInstruction_at(pc);
-  if (inst->is_adr_aligned() || inst->is_ldr_literal()) {
+  if (inst->is_adr_aligned() || inst->is_ldr_literal()
+      || (NativeInstruction::maybe_cpool_ref(pc))) {
     address dest = _constants->start() + data_offset;
     _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS));
     TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);
@@ -104,6 +108,10 @@
     NativeGeneralJump* jump = nativeGeneralJump_at(pc);
     jump->set_jump_destination((address) foreign_call_destination);
     _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
+  } else if (NativeInstruction::is_adrp_at((address)inst)) {
+    // adrp; add; blr
+    MacroAssembler::pd_patch_instruction_size((address)inst,
+                                              (address)foreign_call_destination);
   } else {
     JVMCI_ERROR("unknown call or jump instruction at " PTR_FORMAT, p2i(pc));
   }
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -3975,41 +3975,48 @@
   movk(dst, nk & 0xffff);
 }
 
-void MacroAssembler::load_heap_oop(Register dst, Address src)
-{
-  if (UseCompressedOops) {
-    ldrw(dst, src);
-    decode_heap_oop(dst);
+void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
+                                    Register dst, Address src,
+                                    Register tmp1, Register thread_tmp) {
+  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  bool as_raw = (decorators & AS_RAW) != 0;
+  if (as_raw) {
+    bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
   } else {
-    ldr(dst, src);
+    bs->load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
   }
 }
 
-void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
-{
-  if (UseCompressedOops) {
-    ldrw(dst, src);
-    decode_heap_oop_not_null(dst);
+void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
+                                     Address dst, Register src,
+                                     Register tmp1, Register thread_tmp) {
+  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  bool as_raw = (decorators & AS_RAW) != 0;
+  if (as_raw) {
+    bs->BarrierSetAssembler::store_at(this, decorators, type, dst, src, tmp1, thread_tmp);
   } else {
-    ldr(dst, src);
+    bs->store_at(this, decorators, type, dst, src, tmp1, thread_tmp);
   }
 }
 
-void MacroAssembler::store_heap_oop(Address dst, Register src) {
-  if (UseCompressedOops) {
-    assert(!dst.uses(src), "not enough registers");
-    encode_heap_oop(src);
-    strw(src, dst);
-  } else
-    str(src, dst);
+void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
+                                   Register thread_tmp, DecoratorSet decorators) {
+  access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
+}
+
+void MacroAssembler::load_heap_oop_not_null(Register dst, Address src, Register tmp1,
+                                            Register thread_tmp, DecoratorSet decorators) {
+  access_load_at(T_OBJECT, IN_HEAP | OOP_NOT_NULL | decorators, dst, src, tmp1, thread_tmp);
+}
+
+void MacroAssembler::store_heap_oop(Address dst, Register src, Register tmp1,
+                                    Register thread_tmp, DecoratorSet decorators) {
+  access_store_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
 }
 
 // Used for storing NULLs.
 void MacroAssembler::store_heap_oop_null(Address dst) {
-  if (UseCompressedOops) {
-    strw(zr, dst);
-  } else
-    str(zr, dst);
+  access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg);
 }
 
 Address MacroAssembler::allocate_metadata_address(Metadata* obj) {
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Tue May 15 10:13:52 2018 -0700
@@ -789,10 +789,19 @@
   void resolve_oop_handle(Register result, Register tmp = r5);
   void load_mirror(Register dst, Register method, Register tmp = r5);
 
-  void load_heap_oop(Register dst, Address src);
+  void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
+                      Register tmp1, Register tmp_thread);
 
-  void load_heap_oop_not_null(Register dst, Address src);
-  void store_heap_oop(Address dst, Register src);
+  void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
+                       Register tmp1, Register tmp_thread);
+
+  void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
+                     Register thread_tmp = noreg, DecoratorSet decorators = 0);
+
+  void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
+                              Register thread_tmp = noreg, DecoratorSet decorators = 0);
+  void store_heap_oop(Address dst, Register src, Register tmp1 = noreg,
+                      Register tmp_thread = noreg, DecoratorSet decorators = 0);
 
   // currently unimplemented
   // Used for storing NULL. All other oop constants should be
--- a/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/methodHandles_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -135,11 +135,11 @@
 
   // Load the invoker, as MH -> MH.form -> LF.vmentry
   __ verify_oop(recv);
-  __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
+  __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
   __ verify_oop(method_temp);
-  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
+  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
   __ verify_oop(method_temp);
-  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
+  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
   __ verify_oop(method_temp);
   __ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
 
@@ -311,7 +311,7 @@
       if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
         Label L_ok;
         Register temp2_defc = temp2;
-        __ load_heap_oop(temp2_defc, member_clazz);
+        __ load_heap_oop(temp2_defc, member_clazz, temp3);
         load_klass_from_Class(_masm, temp2_defc);
         __ verify_klass_ptr(temp2_defc);
         __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -36,7 +36,120 @@
 #include "c1/c1_Runtime1.hpp"
 #endif
 
-void NativeCall::verify() { ; }
+void NativeCall::verify() {
+  assert(NativeCall::is_call_at((address)this), "unexpected code at call site");
+}
+
+void NativeInstruction::wrote(int offset) {
+  ICache::invalidate_word(addr_at(offset));
+}
+
+void NativeLoadGot::report_and_fail() const {
+  tty->print_cr("Addr: " INTPTR_FORMAT, p2i(instruction_address()));
+  fatal("not a indirect rip mov to rbx");
+}
+
+void NativeLoadGot::verify() const {
+  assert(is_adrp_at((address)this), "must be adrp");
+}
+
+address NativeLoadGot::got_address() const {
+  return MacroAssembler::target_addr_for_insn((address)this);
+}
+
+intptr_t NativeLoadGot::data() const {
+  return *(intptr_t *) got_address();
+}
+
+address NativePltCall::destination() const {
+  NativeGotJump* jump = nativeGotJump_at(plt_jump());
+  return *(address*)MacroAssembler::target_addr_for_insn((address)jump);
+}
+
+address NativePltCall::plt_entry() const {
+  return MacroAssembler::target_addr_for_insn((address)this);
+}
+
+address NativePltCall::plt_jump() const {
+  address entry = plt_entry();
+  // Virtual PLT code has move instruction first
+  if (((NativeGotJump*)entry)->is_GotJump()) {
+    return entry;
+  } else {
+    return nativeLoadGot_at(entry)->next_instruction_address();
+  }
+}
+
+address NativePltCall::plt_load_got() const {
+  address entry = plt_entry();
+  if (!((NativeGotJump*)entry)->is_GotJump()) {
+    // Virtual PLT code has move instruction first
+    return entry;
+  } else {
+    // Static PLT code has move instruction second (from c2i stub)
+    return nativeGotJump_at(entry)->next_instruction_address();
+  }
+}
+
+address NativePltCall::plt_c2i_stub() const {
+  address entry = plt_load_got();
+  // This method should be called only for static calls which has C2I stub.
+  NativeLoadGot* load = nativeLoadGot_at(entry);
+  return entry;
+}
+
+address NativePltCall::plt_resolve_call() const {
+  NativeGotJump* jump = nativeGotJump_at(plt_jump());
+  address entry = jump->next_instruction_address();
+  if (((NativeGotJump*)entry)->is_GotJump()) {
+    return entry;
+  } else {
+    // c2i stub 2 instructions
+    entry = nativeLoadGot_at(entry)->next_instruction_address();
+    return nativeGotJump_at(entry)->next_instruction_address();
+  }
+}
+
+void NativePltCall::reset_to_plt_resolve_call() {
+  set_destination_mt_safe(plt_resolve_call());
+}
+
+void NativePltCall::set_destination_mt_safe(address dest) {
+  // rewriting the value in the GOT, it should always be aligned
+  NativeGotJump* jump = nativeGotJump_at(plt_jump());
+  address* got = (address *) jump->got_address();
+  *got = dest;
+}
+
+void NativePltCall::set_stub_to_clean() {
+  NativeLoadGot* method_loader = nativeLoadGot_at(plt_c2i_stub());
+  NativeGotJump* jump          = nativeGotJump_at(method_loader->next_instruction_address());
+  method_loader->set_data(0);
+  jump->set_jump_destination((address)-1);
+}
+
+void NativePltCall::verify() const {
+  assert(NativeCall::is_call_at((address)this), "unexpected code at call site");
+}
+
+address NativeGotJump::got_address() const {
+  return MacroAssembler::target_addr_for_insn((address)this);
+}
+
+address NativeGotJump::destination() const {
+  address *got_entry = (address *) got_address();
+  return *got_entry;
+}
+
+bool NativeGotJump::is_GotJump() const {
+  NativeInstruction *insn =
+    nativeInstruction_at(addr_at(3 * NativeInstruction::instruction_size));
+  return insn->encoding() == 0xd61f0200; // br x16
+}
+
+void NativeGotJump::verify() const {
+  assert(is_adrp_at((address)this), "must be adrp");
+}
 
 address NativeCall::destination() const {
   address addr = (address)this;
@@ -71,6 +184,7 @@
   ResourceMark rm;
   int code_size = NativeInstruction::instruction_size;
   address addr_call = addr_at(0);
+  bool reachable = Assembler::reachable_from_branch_at(addr_call, dest);
   assert(NativeCall::is_call_at(addr_call), "unexpected code at call site");
 
   // Patch the constant in the call's trampoline stub.
@@ -81,7 +195,7 @@
   }
 
   // Patch the call.
-  if (Assembler::reachable_from_branch_at(addr_call, dest)) {
+  if (reachable) {
     set_destination(dest);
   } else {
     assert (trampoline_stub_addr != NULL, "we need a trampoline");
@@ -103,9 +217,11 @@
       is_NativeCallTrampolineStub_at(bl_destination))
     return bl_destination;
 
-  // If the codeBlob is not a nmethod, this is because we get here from the
-  // CodeBlob constructor, which is called within the nmethod constructor.
-  return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code);
+  if (code->is_nmethod()) {
+    return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code);
+  }
+
+  return NULL;
 }
 
 // Inserts a native call instruction at a given pc
@@ -340,9 +456,16 @@
 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
 
   assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
-  assert(nativeInstruction_at(verified_entry)->is_jump_or_nop()
-         || nativeInstruction_at(verified_entry)->is_sigill_zombie_not_entrant(),
-         "Aarch64 cannot replace non-jump with jump");
+
+#ifdef ASSERT
+  // This may be the temporary nmethod generated while we're AOT
+  // compiling.  Such an nmethod doesn't begin with a NOP but with an ADRP.
+  if (! (CalculateClassFingerprint && UseAOT && is_adrp_at(verified_entry))) {
+    assert(nativeInstruction_at(verified_entry)->is_jump_or_nop()
+           || nativeInstruction_at(verified_entry)->is_sigill_zombie_not_entrant(),
+           "Aarch64 cannot replace non-jump with jump");
+  }
+#endif
 
   // Patch this nmethod atomically.
   if (Assembler::reachable_from_branch_at(verified_entry, dest)) {
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2108, Red Hat Inc. 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
@@ -95,6 +95,8 @@
   void set_ptr_at (int offset, address  ptr)  { *(address*) addr_at(offset) = ptr; }
   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o; }
 
+  void wrote(int offset);
+
  public:
 
   // unit test stuff
@@ -148,6 +150,46 @@
   return (NativeInstruction*)address;
 }
 
+class NativePltCall: public NativeInstruction {
+public:
+  enum Arm_specific_constants {
+    instruction_size           =    4,
+    instruction_offset         =    0,
+    displacement_offset        =    1,
+    return_address_offset      =    4
+  };
+  address instruction_address() const { return addr_at(instruction_offset); }
+  address next_instruction_address() const { return addr_at(return_address_offset); }
+  address displacement_address() const { return addr_at(displacement_offset); }
+  int displacement() const { return (jint) int_at(displacement_offset); }
+  address return_address() const { return addr_at(return_address_offset); }
+  address destination() const;
+  address plt_entry() const;
+  address plt_jump() const;
+  address plt_load_got() const;
+  address plt_resolve_call() const;
+  address plt_c2i_stub() const;
+  void set_stub_to_clean();
+
+  void  reset_to_plt_resolve_call();
+  void  set_destination_mt_safe(address dest);
+
+  void verify() const;
+};
+
+inline NativePltCall* nativePltCall_at(address address) {
+  NativePltCall* call = (NativePltCall*) address;
+#ifdef ASSERT
+  call->verify();
+#endif
+  return call;
+}
+
+inline NativePltCall* nativePltCall_before(address addr) {
+  address at = addr - NativePltCall::instruction_size;
+  return nativePltCall_at(at);
+}
+
 inline NativeCall* nativeCall_at(address address);
 // The NativeCall is an abstraction for accessing/manipulating native
 // call instructions (used to manipulate inline caches, primitive &
@@ -169,7 +211,7 @@
   address return_address() const            { return addr_at(return_address_offset); }
   address destination() const;
 
-  void  set_destination(address dest)       {
+  void set_destination(address dest)        {
     int offset = dest - instruction_address();
     unsigned int insn = 0b100101 << 26;
     assert((offset & 3) == 0, "should be");
@@ -191,6 +233,12 @@
     return is_call_at(return_address - NativeCall::return_address_offset);
   }
 
+#if INCLUDE_AOT
+  static bool is_far_call(address instr, address target) {
+    return !Assembler::reachable_from_branch_at(instr, target);
+  }
+#endif
+
   // MT-safe patching of a call instruction.
   static void insert(address code_pos, address entry);
 
@@ -381,6 +429,39 @@
   static void test() {}
 };
 
+//   adrp    x16, #page
+//   add     x16, x16, #offset
+//   ldr     x16, [x16]
+class NativeLoadGot: public NativeInstruction {
+public:
+  enum AArch64_specific_constants {
+    instruction_length = 4 * NativeInstruction::instruction_size,
+    offset_offset = 0,
+  };
+
+  address instruction_address() const { return addr_at(0); }
+  address return_address() const { return addr_at(instruction_length); }
+  address got_address() const;
+  address next_instruction_address() const { return return_address(); }
+  intptr_t data() const;
+  void set_data(intptr_t data) {
+    intptr_t *addr = (intptr_t *) got_address();
+    *addr = data;
+  }
+
+  void verify() const;
+private:
+  void report_and_fail() const;
+};
+
+inline NativeLoadGot* nativeLoadGot_at(address addr) {
+  NativeLoadGot* load = (NativeLoadGot*) addr;
+#ifdef ASSERT
+  load->verify();
+#endif
+  return load;
+}
+
 class NativeJump: public NativeInstruction {
  public:
   enum AArch64_specific_constants {
@@ -441,6 +522,31 @@
   return jump;
 }
 
+class NativeGotJump: public NativeInstruction {
+public:
+  enum AArch64_specific_constants {
+    instruction_size = 4 * NativeInstruction::instruction_size,
+  };
+
+  void verify() const;
+  address instruction_address() const { return addr_at(0); }
+  address destination() const;
+  address return_address() const { return addr_at(instruction_size); }
+  address got_address() const;
+  address next_instruction_address() const { return addr_at(instruction_size); }
+  bool is_GotJump() const;
+
+  void set_jump_destination(address dest)  {
+    address* got = (address *)got_address();
+    *got = dest;
+  }
+};
+
+inline NativeGotJump* nativeGotJump_at(address addr) {
+  NativeGotJump* jump = (NativeGotJump*)(addr);
+  return jump;
+}
+
 class NativePopReg : public NativeInstruction {
  public:
   // Insert a pop instruction
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2018, Red Hat Inc. 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
@@ -560,7 +560,7 @@
   __ ldr(rscratch1, Address(rmethod, in_bytes(Method::from_compiled_offset())));
 
 #if INCLUDE_JVMCI
-  if (EnableJVMCI) {
+  if (EnableJVMCI || UseAOT) {
     // check if this call should be routed towards a specific entry point
     __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
     Label no_alternative_target;
@@ -2278,7 +2278,7 @@
   // Setup code generation tools
   int pad = 0;
 #if INCLUDE_JVMCI
-  if (EnableJVMCI) {
+  if (EnableJVMCI || UseAOT) {
     pad += 512; // Increase the buffer size when compiling for JVMCI
   }
 #endif
@@ -2360,7 +2360,7 @@
   int implicit_exception_uncommon_trap_offset = 0;
   int uncommon_trap_offset = 0;
 
-  if (EnableJVMCI) {
+  if (EnableJVMCI || UseAOT) {
     implicit_exception_uncommon_trap_offset = __ pc() - start;
 
     __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
@@ -2486,7 +2486,7 @@
   __ reset_last_Java_frame(false);
 
 #if INCLUDE_JVMCI
-  if (EnableJVMCI) {
+  if (EnableJVMCI || UseAOT) {
     __ bind(after_fetch_unroll_info_call);
   }
 #endif
@@ -2644,7 +2644,7 @@
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
 #if INCLUDE_JVMCI
-  if (EnableJVMCI) {
+  if (EnableJVMCI || UseAOT) {
     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
   }
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1816,13 +1816,13 @@
     __ align(OptoLoopAlignment);
 
     __ BIND(L_store_element);
-    __ store_heap_oop(__ post(to, UseCompressedOops ? 4 : 8), copied_oop);  // store the oop
+    __ store_heap_oop(__ post(to, UseCompressedOops ? 4 : 8), copied_oop, noreg, noreg, AS_RAW);  // store the oop
     __ sub(count, count, 1);
     __ cbz(count, L_do_card_marks);
 
     // ======== loop entry is here ========
     __ BIND(L_load_element);
-    __ load_heap_oop(copied_oop, __ post(from, UseCompressedOops ? 4 : 8)); // load the oop
+    __ load_heap_oop(copied_oop, __ post(from, UseCompressedOops ? 4 : 8), noreg, noreg, AS_RAW); // load the oop
     __ cbz(copied_oop, L_store_element);
 
     __ load_klass(r19_klass, copied_oop);// query the object klass
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2018, Red Hat Inc. 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
@@ -333,16 +333,17 @@
   return entry;
 }
 
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(
-        const char* name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
   // expression stack must be empty before entering the VM if an
   // exception happened
   __ empty_expression_stack();
   // setup parameters
+
   // ??? convention: expect aberrant index in register r1
   __ movw(c_rarg2, r1);
-  __ mov(c_rarg1, (address)name);
+  // ??? convention: expect array in register r3
+  __ mov(c_rarg1, r3);
   __ call_VM(noreg,
              CAST_FROM_FN_PTR(address,
                               InterpreterRuntime::
@@ -483,7 +484,7 @@
 #if INCLUDE_JVMCI
   // Check if we need to take lock at entry of synchronized method.  This can
   // only occur on method entry so emit it only for vtos with step 0.
-  if (EnableJVMCI && state == vtos && step == 0) {
+  if ((EnableJVMCI || UseAOT) && state == vtos && step == 0) {
     Label L;
     __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
     __ cbz(rscratch1, L);
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Tue May 15 10:13:52 2018 -0700
@@ -147,16 +147,14 @@
                          Register val,
                          DecoratorSet decorators) {
   assert(val == noreg || val == r0, "parameter is just for looks");
-  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->store_at(_masm, decorators, T_OBJECT, dst, val, /*tmp1*/ r10, /*tmp2*/ r1);
+  __ store_heap_oop(dst, val, r10, r1, decorators);
 }
 
 static void do_oop_load(InterpreterMacroAssembler* _masm,
                         Address src,
                         Register dst,
                         DecoratorSet decorators) {
-  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->load_at(_masm, decorators, T_OBJECT, dst, src, /*tmp1*/ r10, /*tmp_thread*/ r1);
+  __ load_heap_oop(dst, src, r10, r1, decorators);
 }
 
 Address TemplateTable::at_bcp(int offset) {
@@ -747,6 +745,8 @@
   }
   Label ok;
   __ br(Assembler::LO, ok);
+    // ??? convention: move array into r3 for exception message
+  __ mov(r3, array);
   __ mov(rscratch1, Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
   __ br(rscratch1);
   __ bind(ok);
--- a/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_CodeStubs_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -50,14 +50,18 @@
 
 // TODO: ARM - is it possible to inline these stubs into the main code stream?
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception)
-  : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
-  , _index(index)
-{
-  _info = info == NULL ? NULL : new CodeEmitInfo(info);
+
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
 }
 
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
 
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
@@ -73,7 +77,7 @@
     return;
   }
   // Pass the array index on stack because all registers must be preserved
-  ce->verify_reserved_argument_area_size(1);
+  ce->verify_reserved_argument_area_size(_throw_index_out_of_bounds_exception ? 1 : 2);
   if (_index->is_cpu_register()) {
     __ str_32(_index->as_register(), Address(SP));
   } else {
@@ -87,6 +91,7 @@
 #endif
     __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
   } else {
+    __ str(_array->as_pointer_register(), Address(SP, BytesPerWord)); // ??? Correct offset? Correct instruction?
     __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
   }
   ce->add_call_info_here(_info);
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -3285,7 +3285,8 @@
 }
 
 
-void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
+void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(patch_code == lir_patch_none, "Patch code not supported");
   LIR_Address* addr = addr_opr->as_address_ptr();
   if (addr->index()->is_illegal()) {
     jint c = addr->disp();
--- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -366,11 +366,15 @@
 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
   OopMap* oop_map = save_live_registers(sasm);
 
+  int call_offset;
   if (has_argument) {
     __ ldr(R1, Address(SP, arg1_offset));
+    __ ldr(R2, Address(SP, arg2_offset));
+    call_offset = __ call_RT(noreg, noreg, target, R1, R2);
+  } else {
+    call_offset = __ call_RT(noreg, noreg, target);
   }
 
-  int call_offset = __ call_RT(noreg, noreg, target);
   OopMapSet* oop_maps = new OopMapSet();
   oop_maps->add_gc_map(call_offset, oop_map);
 
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -91,6 +91,11 @@
 }
 #endif // COMPILER2_OR_JVMCI
 
+int CompiledStaticCall::to_trampoline_stub_size() {
+  // ARM doesn't use trampolines.
+  return 0;
+}
+
 // size of C2 call stub, compiled java to interpretor
 int CompiledStaticCall::to_interp_stub_size() {
   return 8 * NativeInstruction::instruction_size;
--- a/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -52,7 +52,7 @@
   Unimplemented();
 }
 
-void CodeInstaller::pd_relocate_JavaMethod(Handle hotspot_method, jint pc_offset, TRAPS) {
+void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle hotspot_method, jint pc_offset, TRAPS) {
   Unimplemented();
 }
 
--- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -185,18 +185,16 @@
   return entry;
 }
 
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
 
   // index is in R4_ArrayIndexOutOfBounds_index
 
-  InlinedString Lname(name);
-
   // expression stack must be empty before entering the VM if an exception happened
   __ empty_expression_stack();
 
   // setup parameters
-  __ ldr_literal(R1, Lname);
+  // Array expected in R1.
   __ mov(R2, R4_ArrayIndexOutOfBounds_index);
 
   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), R1, R2);
@@ -204,7 +202,6 @@
   __ nop(); // to avoid filling CPU pipeline with invalid instructions
   __ nop();
   __ should_not_reach_here();
-  __ bind_literal(Lname);
 
   return entry;
 }
--- a/src/hotspot/cpu/arm/templateTable_arm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/arm/templateTable_arm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -398,7 +398,7 @@
 
 void TemplateTable::ldc(bool wide) {
   transition(vtos, vtos);
-  Label fastCase, Done;
+  Label fastCase, Condy, Done;
 
   const Register Rindex = R1_tmp;
   const Register Rcpool = R2_tmp;
@@ -450,15 +450,11 @@
 
   // int, float, String
   __ bind(fastCase);
-#ifdef ASSERT
-  { Label L;
-    __ cmp(RtagType, JVM_CONSTANT_Integer);
-    __ cond_cmp(RtagType, JVM_CONSTANT_Float, ne);
-    __ b(L, eq);
-    __ stop("unexpected tag type in ldc");
-    __ bind(L);
-  }
-#endif // ASSERT
+
+  __ cmp(RtagType, JVM_CONSTANT_Integer);
+  __ cond_cmp(RtagType, JVM_CONSTANT_Float, ne);
+  __ b(Condy, ne);
+
   // itos, ftos
   __ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
   __ ldr_u32(R0_tos, Address(Rtemp, base_offset));
@@ -466,6 +462,11 @@
   // floats and ints are placed on stack in the same way, so
   // we can use push(itos) to transfer float value without VFP
   __ push(itos);
+  __ b(Done);
+
+  __ bind(Condy);
+  condy_helper(Done);
+
   __ bind(Done);
 }
 
@@ -489,6 +490,23 @@
   __ call_VM(R0_tos, entry, R1);
   __ bind(resolved);
 
+  { // Check for the null sentinel.
+    // If we just called the VM, that already did the mapping for us,
+    // but it's harmless to retry.
+    Label notNull;
+    Register result = R0;
+    Register tmp = R1;
+    Register rarg = R2;
+
+    // Stash null_sentinel address to get its value later
+    __ mov_slow(rarg, (uintptr_t)Universe::the_null_sentinel_addr());
+    __ ldr(tmp, Address(rarg));
+    __ cmp(result, tmp);
+    __ b(notNull, ne);
+    __ mov(result, 0);  // NULL object reference
+    __ bind(notNull);
+  }
+
   if (VerifyOops) {
     __ verify_oop(R0_tos);
   }
@@ -509,8 +527,9 @@
 
   __ add(Rbase, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
 
+  Label Condy, exit;
 #ifdef __ABI_HARD__
-  Label Long, exit;
+  Label Long;
   // get type from tags
   __ add(Rtemp, Rtags, tags_offset);
   __ ldrb(Rtemp, Address(Rtemp, Rindex));
@@ -523,6 +542,8 @@
   __ bind(Long);
 #endif
 
+  __ cmp(Rtemp, JVM_CONSTANT_Long);
+  __ b(Condy, ne);
 #ifdef AARCH64
   __ ldr(R0_tos, Address(Rbase, base_offset));
 #else
@@ -530,10 +551,115 @@
   __ ldr(R1_tos_hi, Address(Rbase, base_offset + 1 * wordSize));
 #endif // AARCH64
   __ push(ltos);
-
-#ifdef __ABI_HARD__
+  __ b(exit);
+
+  __ bind(Condy);
+  condy_helper(exit);
+
   __ bind(exit);
+}
+
+
+void TemplateTable::condy_helper(Label& Done)
+{
+  Register obj   = R0_tmp;
+  Register rtmp  = R1_tmp;
+  Register flags = R2_tmp;
+  Register off   = R3_tmp;
+
+  __ mov(rtmp, (int) bytecode());
+  __ call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rtmp);
+  __ get_vm_result_2(flags, rtmp);
+
+  // VMr = obj = base address to find primitive value to push
+  // VMr2 = flags = (tos, off) using format of CPCE::_flags
+  __ mov(off, flags);
+
+#ifdef AARCH64
+  __ andr(off, off, (unsigned)ConstantPoolCacheEntry::field_index_mask);
+#else
+  __ logical_shift_left( off, off, 32 - ConstantPoolCacheEntry::field_index_bits);
+  __ logical_shift_right(off, off, 32 - ConstantPoolCacheEntry::field_index_bits);
 #endif
+
+  const Address field(obj, off);
+
+  __ logical_shift_right(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
+  // Make sure we don't need to mask flags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
+
+  switch (bytecode()) {
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+      {
+        // tos in (itos, ftos, stos, btos, ctos, ztos)
+        Label notIntFloat, notShort, notByte, notChar, notBool;
+        __ cmp(flags, itos);
+        __ cond_cmp(flags, ftos, ne);
+        __ b(notIntFloat, ne);
+        __ ldr(R0_tos, field);
+        __ push(itos);
+        __ b(Done);
+
+        __ bind(notIntFloat);
+        __ cmp(flags, stos);
+        __ b(notShort, ne);
+        __ ldrsh(R0_tos, field);
+        __ push(stos);
+        __ b(Done);
+
+        __ bind(notShort);
+        __ cmp(flags, btos);
+        __ b(notByte, ne);
+        __ ldrsb(R0_tos, field);
+        __ push(btos);
+        __ b(Done);
+
+        __ bind(notByte);
+        __ cmp(flags, ctos);
+        __ b(notChar, ne);
+        __ ldrh(R0_tos, field);
+        __ push(ctos);
+        __ b(Done);
+
+        __ bind(notChar);
+        __ cmp(flags, ztos);
+        __ b(notBool, ne);
+        __ ldrsb(R0_tos, field);
+        __ push(ztos);
+        __ b(Done);
+
+        __ bind(notBool);
+        break;
+      }
+
+    case Bytecodes::_ldc2_w:
+      {
+        Label notLongDouble;
+        __ cmp(flags, ltos);
+        __ cond_cmp(flags, dtos, ne);
+        __ b(notLongDouble, ne);
+
+#ifdef AARCH64
+        __ ldr(R0_tos, field);
+#else
+        __ add(rtmp, obj, wordSize);
+        __ ldr(R0_tos_lo, Address(obj, off));
+        __ ldr(R1_tos_hi, Address(rtmp, off));
+#endif
+        __ push(ltos);
+        __ b(Done);
+
+        __ bind(notLongDouble);
+
+        break;
+      }
+
+    default:
+      ShouldNotReachHere();
+    }
+
+    __ stop("bad ldc/condy");
 }
 
 
@@ -746,6 +872,7 @@
     // convention with generate_ArrayIndexOutOfBounds_handler()
     __ mov(R4_ArrayIndexOutOfBounds_index, index, hs);
   }
+  __ mov(R1, array, hs);
   __ b(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry, hs);
 }
 
--- a/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. 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
@@ -37,10 +37,14 @@
 #define __ ce->masm()->
 
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception)
-  : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
-  , _index(index) {
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
+
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
   assert(info != NULL, "must have info");
   _info = new CodeEmitInfo(info);
 }
@@ -68,12 +72,16 @@
   __ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
   __ mtctr(R0);
 
-  Register index = R0; // pass in R0
+  Register index = R0;
   if (_index->is_register()) {
     __ extsw(index, _index->as_register());
   } else {
     __ load_const_optimized(index, _index->as_jint());
   }
+  if (_array) {
+    __ std(_array->as_pointer_register(), -8, R1_SP);
+  }
+  __ std(index, -16, R1_SP);
 
   __ bctrl();
   ce->add_call_info_here(_info);
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2925,7 +2925,8 @@
   Unimplemented();
 }
 
-void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
+void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(patch_code == lir_patch_none, "Patch code not supported");
   LIR_Address* addr = addr_opr->as_address_ptr();
   assert(addr->scale() == LIR_Address::times_1, "no scaling on this platform");
   if (addr->index()->is_illegal()) {
--- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 SAP SE. 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
@@ -502,8 +502,7 @@
     case throw_range_check_failed_id:
       {
         __ set_info("range_check_failed", dont_gc_arguments); // Arguments will be discarded.
-        __ std(R0, -8, R1_SP); // Pass index on stack.
-        oop_maps = generate_exception_throw_with_stack_parms(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), 1);
+        oop_maps = generate_exception_throw_with_stack_parms(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), 2);
       }
       break;
 
--- a/src/hotspot/cpu/ppc/ppc.ad	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/ppc/ppc.ad	Tue May 15 10:13:52 2018 -0700
@@ -1037,7 +1037,7 @@
   // So first get the Proj node, mem_proj, to use it to iterate forward.
   Node *mem_proj = NULL;
   for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) {
-    mem_proj = mba->fast_out(i);      // Throw out-of-bounds if proj not found
+    mem_proj = mba->fast_out(i);      // Runs out of bounds and asserts if Proj not found.
     assert(mem_proj->is_Proj(), "only projections here");
     ProjNode *proj = mem_proj->as_Proj();
     if (proj->_con == TypeFunc::Memory &&
--- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -564,13 +564,13 @@
   return entry;
 }
 
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
   __ empty_expression_stack();
-  __ load_const_optimized(R4_ARG2, (address) name);
+  // R4_ARG2 already contains the array.
   // Index is in R17_tos.
   __ mr(R5_ARG3, R17_tos);
-  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException));
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), R4_ARG2, R5_ARG3);
   return entry;
 }
 
--- a/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/s390/c1_CodeStubs_s390.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -39,10 +39,14 @@
 #undef  CHECK_BAILOUT
 #define CHECK_BAILOUT() { if (ce->compilation()->bailed_out()) return; }
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception) :
-  _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception),
-  _index(index) {
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
+
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
   assert(info != NULL, "must have info");
   _info = new CodeEmitInfo(info);
 }
@@ -71,6 +75,7 @@
     stub_id = Runtime1::throw_index_exception_id;
   } else {
     stub_id = Runtime1::throw_range_check_failed_id;
+    __ lgr_if_needed(Z_R0_scratch, _array->as_pointer_register());
   }
   ce->emit_call_c(Runtime1::entry_for (stub_id));
   CHECK_BAILOUT();
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2922,7 +2922,8 @@
   Unimplemented();
 }
 
-void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
+void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(patch_code == lir_patch_none, "Patch code not supported");
   LIR_Address* addr = addr_opr->as_address_ptr();
   assert(addr->scale() == LIR_Address::times_1, "scaling unsupported");
   __ load_address(dest->as_pointer_register(), as_Address(addr));
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -314,8 +314,8 @@
   __ save_return_pc(return_pc);
 
   // Push a new frame (includes stack linkage).
-  // use return_pc as scratch for push_frame. Z_R0_scratch (the default) and Z_R1_scratch are
-  // illegally used to pass parameters (SAPJVM extension) by RangeCheckStub::emit_code().
+  // Use return_pc as scratch for push_frame. Z_R0_scratch (the default) and Z_R1_scratch are
+  // illegally used to pass parameters by RangeCheckStub::emit_code().
   __ push_frame(frame_size_in_bytes, return_pc);
   // We have to restore return_pc right away.
   // Nobody else will. Furthermore, return_pc isn't necessarily the default (Z_R14).
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp	Tue May 15 10:13:52 2018 -0700
@@ -551,9 +551,10 @@
 
 //
 // Args:
+//   Z_ARG2: oop of array
 //   Z_ARG3: aberrant index
 //
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char * name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
   address excp = CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException);
 
@@ -562,8 +563,7 @@
   __ empty_expression_stack();
 
   // Setup parameters.
-  // Leave out the name and use register for array to create more detailed exceptions.
-  __ load_absolute_address(Z_ARG2, (address) name);
+  // Pass register with array to create more detailed exceptions.
   __ call_VM(noreg, excp, Z_ARG2, Z_ARG3);
   return entry;
 }
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp	Tue May 15 10:13:52 2018 -0700
@@ -784,7 +784,7 @@
   __ z_cl(index, Address(array, arrayOopDesc::length_offset_in_bytes()));
   __ z_brl(index_ok);
   __ lgr_if_needed(Z_ARG3, index); // See generate_ArrayIndexOutOfBounds_handler().
-  // Give back the array to create more detailed exceptions.
+  // Pass the array to create more detailed exceptions.
   __ lgr_if_needed(Z_ARG2, array); // See generate_ArrayIndexOutOfBounds_handler().
   __ load_absolute_address(Z_R1_scratch,
                            Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
--- a/src/hotspot/cpu/sparc/c1_CodeStubs_sparc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/sparc/c1_CodeStubs_sparc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -35,15 +35,17 @@
 
 #define __ ce->masm()->
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception)
-  : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
-  , _index(index)
-{
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
   assert(info != NULL, "must have info");
   _info = new CodeEmitInfo(info);
 }
 
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
 
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
@@ -66,6 +68,7 @@
   if (_throw_index_out_of_bounds_exception) {
     __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type);
   } else {
+    __ mov(_array->as_pointer_register(), G5);
     __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type);
   }
   __ delayed()->nop();
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -3195,7 +3195,7 @@
   __ srl (rs,  0, rd->successor());
 }
 
-void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
+void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
   const LIR_Address* addr = addr_opr->as_address_ptr();
   assert(addr->scale() == LIR_Address::times_1, "can't handle complex addresses yet");
   const Register dest_reg = dest->as_pointer_register();
--- a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -302,7 +302,7 @@
   if (!has_argument) {
     call_offset = __ call_RT(noreg, noreg, target);
   } else {
-    call_offset = __ call_RT(noreg, noreg, target, G4);
+    call_offset = __ call_RT(noreg, noreg, target, G4, G5);
   }
   OopMapSet* oop_maps = new OopMapSet();
   oop_maps->add_gc_map(call_offset, oop_map);
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -881,27 +881,32 @@
   assert_not_delayed();
 
   verify_oop(array);
-  // sign extend since tos (index) can be a 32bit value
+  // Sign extend since tos (index) can be a 32bit value.
   sra(index, G0, index);
 
-  // check array
+  // Check array.
   Label ptr_ok;
   tst(array);
-  throw_if_not_1_x( notZero, ptr_ok );
-  delayed()->ld( array, arrayOopDesc::length_offset_in_bytes(), tmp ); // check index
-  throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ptr_ok);
+  throw_if_not_1_x(notZero, ptr_ok);
+  delayed()->ld(array, arrayOopDesc::length_offset_in_bytes(), tmp); // Check index.
+  throw_if_not_2(Interpreter::_throw_NullPointerException_entry, G3_scratch, ptr_ok);
 
   Label index_ok;
   cmp(index, tmp);
-  throw_if_not_1_icc( lessUnsigned, index_ok );
-  if (index_shift > 0)  delayed()->sll(index, index_shift, index);
-  else                  delayed()->add(array, index, res); // addr - const offset in index
-  // convention: move aberrant index into G3_scratch for exception message
-  mov(index, G3_scratch);
-  throw_if_not_2( Interpreter::_throw_ArrayIndexOutOfBoundsException_entry, G4_scratch, index_ok);
+  throw_if_not_1_icc(lessUnsigned, index_ok);
+  if (index_shift > 0) {
+    delayed()->sll(index, index_shift, index);
+  } else {
+    delayed()->add(array, index, res); // addr - const offset in index
+  }
+  // Pass the array to create more detailed exceptions.
+  // Convention: move aberrant index into Otos_i for exception message.
+  mov(index, Otos_i);
+  mov(array, G3_scratch);
+  throw_if_not_2(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry, G4_scratch, index_ok);
 
   // add offset if didn't do it in delay slot
-  if (index_shift > 0)   add(array, index, res); // addr - const offset in index
+  if (index_shift > 0) { add(array, index, res); } // addr - const offset in index
 }
 
 
--- a/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Tue May 15 10:13:52 2018 -0700
@@ -255,15 +255,14 @@
 }
 
 
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
   // expression stack must be empty before entering the VM if an exception happened
   __ empty_expression_stack();
+  // Pass the array to create more detailed exceptions.
   // convention: expect aberrant index in register G3_scratch, then shuffle the
   // index to G4_scratch for the VM call
-  __ mov(G3_scratch, G4_scratch);
-  __ set((intptr_t)name, G3_scratch);
-  __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch);
+  __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, Otos_i);
   __ should_not_reach_here();
   return entry;
 }
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -8981,6 +8981,13 @@
   emit_arith(0x85, 0xC0, dst, src);
 }
 
+void Assembler::testq(Register dst, Address src) {
+  InstructionMark im(this);
+  prefixq(src, dst);
+  emit_int8((unsigned char)0x85);
+  emit_operand(dst, src);
+}
+
 void Assembler::xaddq(Address dst, Register src) {
   InstructionMark im(this);
   prefixq(dst, src);
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1813,6 +1813,7 @@
 
   void testq(Register dst, int32_t imm32);
   void testq(Register dst, Register src);
+  void testq(Register dst, Address src);
 
   // BMI - count trailing zeros
   void tzcntl(Register dst, Register src);
--- a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -88,15 +88,17 @@
   __ jmp(_continuation);
 }
 
-RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
-                               bool throw_index_out_of_bounds_exception)
-  : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception)
-  , _index(index)
-{
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array)
+  : _throw_index_out_of_bounds_exception(false), _index(index), _array(array) {
   assert(info != NULL, "must have info");
   _info = new CodeEmitInfo(info);
 }
 
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index)
+  : _throw_index_out_of_bounds_exception(true), _index(index), _array(NULL) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
 
 void RangeCheckStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
@@ -120,6 +122,7 @@
     stub_id = Runtime1::throw_index_exception_id;
   } else {
     stub_id = Runtime1::throw_range_check_failed_id;
+    ce->store_parameter(_array->as_pointer_register(), 1);
   }
   __ call(RuntimeAddress(Runtime1::entry_for(stub_id)));
   ce->add_call_info_here(_info);
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -3786,11 +3786,22 @@
 }
 
 
-void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) {
-  assert(addr->is_address() && dest->is_register(), "check");
-  Register reg;
-  reg = dest->as_pointer_register();
-  __ lea(reg, as_Address(addr->as_address_ptr()));
+void LIR_Assembler::leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(src->is_address(), "must be an address");
+  assert(dest->is_register(), "must be a register");
+
+  PatchingStub* patch = NULL;
+  if (patch_code != lir_patch_none) {
+    patch = new PatchingStub(_masm, PatchingStub::access_field_id);
+  }
+
+  Register reg = dest->as_pointer_register();
+  LIR_Address* addr = src->as_address_ptr();
+  __ lea(reg, as_Address(addr));
+
+  if (patch != NULL) {
+    patching_epilog(patch, patch_code, addr->base()->as_register(), info);
+  }
 }
 
 
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -611,26 +611,29 @@
 }
 
 
-// target: the entry point of the method that creates and posts the exception oop
-// has_argument: true if the exception needs an argument (passed on stack because registers must be preserved)
-
+// Target: the entry point of the method that creates and posts the exception oop.
+// has_argument: true if the exception needs arguments (passed on the stack because
+//               registers must be preserved).
 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
-  // preserve all registers
-  int num_rt_args = has_argument ? 2 : 1;
+  // Preserve all registers.
+  int num_rt_args = has_argument ? (2 + 1) : 1;
   OopMap* oop_map = save_live_registers(sasm, num_rt_args);
 
-  // now all registers are saved and can be used freely
-  // verify that no old value is used accidentally
+  // Now all registers are saved and can be used freely.
+  // Verify that no old value is used accidentally.
   __ invalidate_registers(true, true, true, true, true, true);
 
-  // registers used by this stub
+  // Registers used by this stub.
   const Register temp_reg = rbx;
 
-  // load argument for exception that is passed as an argument into the stub
+  // Load arguments for exception that are passed as arguments into the stub.
   if (has_argument) {
 #ifdef _LP64
     __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
+    __ movptr(c_rarg2, Address(rbp, 3*BytesPerWord));
 #else
+    __ movptr(temp_reg, Address(rbp, 3*BytesPerWord));
+    __ push(temp_reg);
     __ movptr(temp_reg, Address(rbp, 2*BytesPerWord));
     __ push(temp_reg);
 #endif // _LP64
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -504,18 +504,15 @@
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
                                            Register result, Register index, Register tmp) {
   assert_different_registers(result, index);
-  // convert from field index to resolved_references() index and from
-  // word index to byte offset. Since this is a java object, it can be compressed
-  shll(index, LogBytesPerHeapOop);
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
   movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
   resolve_oop_handle(result, tmp);
-  // Add in the index
-  addptr(result, index);
-  load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp);
+  load_heap_oop(result, Address(result, index,
+                                UseCompressedOops ? Address::times_4 : Address::times_ptr,
+                                arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp);
 }
 
 // load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue May 15 10:13:52 2018 -0700
@@ -836,6 +836,7 @@
   void orptr(Address dst, int32_t imm32) { LP64_ONLY(orq(dst, imm32)) NOT_LP64(orl(dst, imm32)); }
 
   void testptr(Register src, int32_t imm32) {  LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
+  void testptr(Register src1, Address src2) { LP64_ONLY(testq(src1, src2)) NOT_LP64(testl(src1, src2)); }
   void testptr(Register src1, Register src2);
 
   void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); }
--- a/src/hotspot/cpu/x86/nativeInst_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/nativeInst_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -436,6 +436,8 @@
   case instruction_code_reg2memb:       // 0x88
   case instruction_code_mem2regb:       // 0x8a
 
+  case instruction_code_lea:            // 0x8d
+
   case instruction_code_float_s:        // 0xd9 fld_s a
   case instruction_code_float_d:        // 0xdd fld_d a
 
@@ -508,6 +510,9 @@
     case instruction_code_xmm_lpd:   // 0x12 movlpd xmm, a
       break;
 
+    case instruction_code_lea:       // 0x8d lea r, a
+      break;
+
     default:
           fatal ("not a mov [reg+offs], reg instruction");
   }
--- a/src/hotspot/cpu/x86/nativeInst_x86.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp	Tue May 15 10:13:52 2018 -0700
@@ -354,6 +354,8 @@
     instruction_code_xmm_store          = 0x11,
     instruction_code_xmm_lpd            = 0x12,
 
+    instruction_code_lea                = 0x8d,
+
     instruction_VEX_prefix_2bytes       = Assembler::VEX_2bytes,
     instruction_VEX_prefix_3bytes       = Assembler::VEX_3bytes,
     instruction_EVEX_prefix_4bytes      = Assembler::EVEX_4bytes,
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -102,16 +102,16 @@
   return entry;
 }
 
-address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(
-        const char* name) {
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler() {
   address entry = __ pc();
-  // expression stack must be empty before entering the VM if an
-  // exception happened
+  // The expression stack must be empty before entering the VM if an
+  // exception happened.
   __ empty_expression_stack();
-  // setup parameters
-  // ??? convention: expect aberrant index in register ebx
+
+  // Setup parameters.
+  // ??? convention: expect aberrant index in register ebx/rbx.
+  // Pass array to create more detailed exceptions.
   Register rarg = NOT_LP64(rax) LP64_ONLY(c_rarg1);
-  __ lea(rarg, ExternalAddress((address)name));
   __ call_VM(noreg,
              CAST_FROM_FN_PTR(address,
                               InterpreterRuntime::
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Tue May 15 10:13:52 2018 -0700
@@ -757,11 +757,14 @@
     assert(rbx != array, "different registers");
     __ movl(rbx, index);
   }
-  __ jump_cc(Assembler::aboveEqual,
-             ExternalAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry));
+  Label skip;
+  __ jccb(Assembler::below, skip);
+  // Pass array to create more detailed exceptions.
+  __ mov(NOT_LP64(rax) LP64_ONLY(c_rarg1), array);
+  __ jump(ExternalAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry));
+  __ bind(skip);
 }
 
-
 void TemplateTable::iaload() {
   transition(itos, itos);
   // rax: index
@@ -1109,8 +1112,6 @@
   __ load_klass(rax, rdx);
   __ movptr(rax, Address(rax,
                          ObjArrayKlass::element_klass_offset()));
-  // Compress array + index*oopSize + 12 into a single register.  Frees rcx.
-  __ lea(rdx, element_address);
 
   // Generate subtype check.  Blows rcx, rdi
   // Superklass in rax.  Subklass in rbx.
@@ -1125,8 +1126,9 @@
 
   // Get the value we will store
   __ movptr(rax, at_tos());
+  __ movl(rcx, at_tos_p1()); // index
   // Now store using the appropriate barrier
-  do_oop_store(_masm, Address(rdx, 0), rax, IN_HEAP_ARRAY);
+  do_oop_store(_masm, element_address, rax, IN_HEAP_ARRAY);
   __ jmp(done);
 
   // Have a NULL in rax, rdx=array, ecx=index.  Store NULL at ary[idx]
--- a/src/hotspot/os/aix/attachListener_aix.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/aix/attachListener_aix.cpp	Tue May 15 10:13:52 2018 -0700
@@ -235,7 +235,12 @@
   if (res == 0) {
     RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
     if (res == 0) {
-      res = ::rename(initial_path, path);
+      // make sure the file is owned by the effective user and effective group
+      // e.g. the group could be inherited from the directory in case the s bit is set
+      RESTARTABLE(::chown(initial_path, geteuid(), getegid()), res);
+      if (res == 0) {
+        res = ::rename(initial_path, path);
+      }
     }
   }
   if (res == -1) {
--- a/src/hotspot/os/aix/perfMemory_aix.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/aix/perfMemory_aix.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1246,7 +1246,7 @@
   *sizep = size;
 
   log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at "
-                          INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress));
+                          INTPTR_FORMAT, size, vmid, p2i((void*)mapAddress));
 }
 
 // create the PerfData memory region
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp	Tue May 15 10:13:52 2018 -0700
@@ -215,7 +215,8 @@
     RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
     if (res == 0) {
       // make sure the file is owned by the effective user and effective group
-      // (this is the default on linux, but not on mac os)
+      // e.g. default behavior on mac is that new files inherit the group of
+      // the directory that they are created in
       RESTARTABLE(::chown(initial_path, geteuid(), getegid()), res);
       if (res == 0) {
         res = ::rename(initial_path, path);
--- a/src/hotspot/os/bsd/perfMemory_bsd.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/bsd/perfMemory_bsd.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1152,7 +1152,7 @@
   *sizep = size;
 
   log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at "
-                          INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress));
+                          INTPTR_FORMAT, size, vmid, p2i((void*)mapAddress));
 }
 
 // create the PerfData memory region
--- a/src/hotspot/os/linux/attachListener_linux.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/linux/attachListener_linux.cpp	Tue May 15 10:13:52 2018 -0700
@@ -215,7 +215,12 @@
   if (res == 0) {
     RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
     if (res == 0) {
-      res = ::rename(initial_path, path);
+      // make sure the file is owned by the effective user and effective group
+      // e.g. the group could be inherited from the directory in case the s bit is set
+      RESTARTABLE(::chown(initial_path, geteuid(), getegid()), res);
+      if (res == 0) {
+        res = ::rename(initial_path, path);
+      }
     }
   }
   if (res == -1) {
--- a/src/hotspot/os/linux/perfMemory_linux.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/linux/perfMemory_linux.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1241,7 +1241,7 @@
   *sizep = size;
 
   log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at "
-                          INTPTR_FORMAT "\n", size, vmid, p2i((void*)mapAddress));
+                          INTPTR_FORMAT, size, vmid, p2i((void*)mapAddress));
 }
 
 // create the PerfData memory region
--- a/src/hotspot/os/solaris/perfMemory_solaris.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/solaris/perfMemory_solaris.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -1186,7 +1186,7 @@
   *sizep = size;
 
   log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at "
-                          INTPTR_FORMAT "\n", size, vmid, (void*)mapAddress);
+                          INTPTR_FORMAT, size, vmid, (void*)mapAddress);
 }
 
 // create the PerfData memory region
--- a/src/hotspot/os/windows/os_windows.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/windows/os_windows.cpp	Tue May 15 10:13:52 2018 -0700
@@ -4417,10 +4417,11 @@
     return false;
   }
   strcpy(search_path, path);
+  os::native_path(search_path);
   // Append "*", or possibly "\\*", to path
-  if (path[1] == ':' &&
-    (path[2] == '\0' ||
-    (path[2] == '\\' && path[3] == '\0'))) {
+  if (search_path[1] == ':' &&
+       (search_path[2] == '\0' ||
+         (search_path[2] == '\\' && search_path[3] == '\0'))) {
     // No '\\' needed for cases like "Z:" or "Z:\"
     strcat(search_path, "*");
   }
--- a/src/hotspot/os/windows/perfMemory_windows.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/os/windows/perfMemory_windows.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1697,7 +1697,7 @@
   CloseHandle(fmh);
 
   log_debug(perf, memops)("mapped " SIZE_FORMAT " bytes for vmid %d at "
-                          INTPTR_FORMAT "\n", size, vmid, mapAddress);
+                          INTPTR_FORMAT, size, vmid, mapAddress);
 }
 
 // this method unmaps the the mapped view of the the
--- a/src/hotspot/share/asm/codeBuffer.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/asm/codeBuffer.hpp	Tue May 15 10:13:52 2018 -0700
@@ -382,6 +382,10 @@
 
   address      _last_insn;      // used to merge consecutive memory barriers, loads or stores.
 
+#if INCLUDE_AOT
+  bool         _immutable_PIC;
+#endif
+
   address      _decode_begin;   // start address for decode
   address      decode_begin();
 
@@ -396,6 +400,9 @@
     _overflow_arena  = NULL;
     _code_strings    = CodeStrings();
     _last_insn       = NULL;
+#if INCLUDE_AOT
+    _immutable_PIC   = false;
+#endif
   }
 
   void initialize(address code_start, csize_t code_size) {
@@ -629,6 +636,13 @@
   // Log a little info about section usage in the CodeBuffer
   void log_section_sizes(const char* name);
 
+#if INCLUDE_AOT
+  // True if this is a code buffer used for immutable PIC, i.e. AOT
+  // compilation.
+  bool immutable_PIC() { return _immutable_PIC; }
+  void set_immutable_PIC(bool pic) { _immutable_PIC = pic; }
+#endif
+
 #ifndef PRODUCT
  public:
   // Printing / Decoding
--- a/src/hotspot/share/c1/c1_CodeStubs.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_CodeStubs.hpp	Tue May 15 10:13:52 2018 -0700
@@ -147,10 +147,14 @@
  private:
   CodeEmitInfo* _info;
   LIR_Opr       _index;
+  LIR_Opr       _array;
   bool          _throw_index_out_of_bounds_exception;
 
  public:
-  RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
+  // For ArrayIndexOutOfBoundsException.
+  RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array);
+  // For IndexOutOfBoundsException.
+  RangeCheckStub(CodeEmitInfo* info, LIR_Opr index);
   virtual void emit_code(LIR_Assembler* e);
   virtual CodeEmitInfo* info() const             { return _info; }
   virtual bool is_exception_throw_stub() const   { return true; }
@@ -158,6 +162,7 @@
   virtual void visit(LIR_OpVisitState* visitor) {
     visitor->do_slow_case(_info);
     visitor->do_input(_index);
+    if (_array) { visitor->do_input(_array); }
   }
 #ifndef PRODUCT
   virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
--- a/src/hotspot/share/c1/c1_LIR.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIR.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -2074,7 +2074,7 @@
   void branch_destination(Label* lbl)            { append(new LIR_OpLabel(lbl)); }
 
   void negate(LIR_Opr from, LIR_Opr to)          { append(new LIR_Op1(lir_neg, from, to)); }
-  void leal(LIR_Opr from, LIR_Opr result_reg)    { append(new LIR_Op1(lir_leal, from, result_reg)); }
+  void leal(LIR_Opr from, LIR_Opr result_reg, LIR_PatchCode patch_code = lir_patch_none, CodeEmitInfo* info = NULL) { append(new LIR_Op1(lir_leal, from, result_reg, T_ILLEGAL, patch_code, info)); }
 
   // result is a stack location for old backend and vreg for UseLinearScan
   // stack_loc_temp is an illegal register for old backend
--- a/src/hotspot/share/c1/c1_LIRAssembler.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -276,7 +276,8 @@
       // branches since they include block and stub names.  Also print
       // patching moves since they generate funny looking code.
       if (op->code() == lir_branch ||
-          (op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none)) {
+          (op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none) ||
+          (op->code() == lir_leal && op->as_Op1()->patch_code() != lir_patch_none)) {
         stringStream st;
         op->print_on(&st);
         _masm->block_comment(st.as_string());
@@ -554,7 +555,7 @@
       break;
 
     case lir_leal:
-      leal(op->in_opr(), op->result_opr());
+      leal(op->in_opr(), op->result_opr(), op->patch_code(), op->info());
       break;
 
     case lir_null_check: {
--- a/src/hotspot/share/c1/c1_LIRAssembler.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp	Tue May 15 10:13:52 2018 -0700
@@ -240,7 +240,7 @@
   void align_call(LIR_Code code);
 
   void negate(LIR_Opr left, LIR_Opr dest);
-  void leal(LIR_Opr left, LIR_Opr dest);
+  void leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info);
 
   void rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info);
 
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp	Tue May 15 10:13:52 2018 -0700
@@ -480,7 +480,7 @@
 
 void LIRGenerator::array_range_check(LIR_Opr array, LIR_Opr index,
                                     CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info) {
-  CodeStub* stub = new RangeCheckStub(range_check_info, index);
+  CodeStub* stub = new RangeCheckStub(range_check_info, index, array);
   if (index->is_constant()) {
     cmp_mem_int(lir_cond_belowEqual, array, arrayOopDesc::length_offset_in_bytes(),
                 index->as_jint(), null_check_info);
@@ -494,7 +494,7 @@
 
 
 void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
-  CodeStub* stub = new RangeCheckStub(info, index, true);
+  CodeStub* stub = new RangeCheckStub(info, index);
   if (index->is_constant()) {
     cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info);
     __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch
@@ -1592,7 +1592,7 @@
   if (GenerateRangeChecks && needs_range_check) {
     if (use_length) {
       __ cmp(lir_cond_belowEqual, length.result(), index.result());
-      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
+      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result(), array.result()));
     } else {
       array_range_check(array.result(), index.result(), null_check_info, range_check_info);
       // range_check also does the null check
@@ -1756,7 +1756,7 @@
   LIR_Opr result = rlock_result(x);
   if (GenerateRangeChecks) {
     CodeEmitInfo* info = state_for(x);
-    CodeStub* stub = new RangeCheckStub(info, index.result(), true);
+    CodeStub* stub = new RangeCheckStub(info, index.result());
     if (index.result()->is_constant()) {
       cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info);
       __ branch(lir_cond_belowEqual, T_INT, stub);
@@ -1837,12 +1837,12 @@
 
   if (GenerateRangeChecks && needs_range_check) {
     if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) {
-      __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result()));
+      __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result(), array.result()));
     } else if (use_length) {
       // TODO: use a (modified) version of array_range_check that does not require a
       //       constant length to be loaded to a register
       __ cmp(lir_cond_belowEqual, length.result(), index.result());
-      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
+      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result(), array.result()));
     } else {
       array_range_check(array.result(), index.result(), null_check_info, range_check_info);
       // The range check performs the null check, so clear it out for the load
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Tue May 15 10:13:52 2018 -0700
@@ -641,10 +641,12 @@
 }
 
 
-JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index))
+JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index, arrayOopDesc* a))
   NOT_PRODUCT(_throw_range_check_exception_count++;)
-  char message[jintAsStringSize];
-  sprintf(message, "%d", index);
+  const int len = 35;
+  assert(len < strlen("Index %d out of bounds for length %d"), "Must allocate more space for message.");
+  char message[2 * jintAsStringSize + len];
+  sprintf(message, "Index %d out of bounds for length %d", index, a->length());
   SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message);
 JRT_END
 
--- a/src/hotspot/share/c1/c1_Runtime1.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/c1/c1_Runtime1.hpp	Tue May 15 10:13:52 2018 -0700
@@ -149,7 +149,7 @@
 
   static address exception_handler_for_pc(JavaThread* thread);
 
-  static void throw_range_check_exception(JavaThread* thread, int index);
+  static void throw_range_check_exception(JavaThread* thread, int index, arrayOopDesc* a);
   static void throw_index_exception(JavaThread* thread, int index);
   static void throw_div0_exception(JavaThread* thread);
   static void throw_null_pointer_exception(JavaThread* thread);
--- a/src/hotspot/share/classfile/classLoader.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/classLoader.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1552,56 +1552,63 @@
   PackageEntry* pkg_entry = ik->package();
 
   if (FileMapInfo::get_number_of_shared_paths() > 0) {
-    char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN);
+    char* canonical_path_table_entry = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, JVM_MAXPATHLEN);
 
     // save the path from the file: protocol or the module name from the jrt: protocol
     // if no protocol prefix is found, path is the same as stream->source()
     char* path = skip_uri_protocol(src);
+    char* canonical_class_src_path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, JVM_MAXPATHLEN);
+    if (!get_canonical_path(path, canonical_class_src_path, JVM_MAXPATHLEN)) {
+      tty->print_cr("Bad pathname %s. CDS dump aborted.", path);
+      vm_exit(1);
+    }
     for (int i = 0; i < FileMapInfo::get_number_of_shared_paths(); i++) {
       SharedClassPathEntry* ent = FileMapInfo::shared_path(i);
-      if (get_canonical_path(ent->name(), canonical_path, JVM_MAXPATHLEN)) {
-        // If the path (from the class stream source) is the same as the shared
-        // class or module path, then we have a match.
-        if (strcmp(canonical_path, os::native_path((char*)path)) == 0) {
-          // NULL pkg_entry and pkg_entry in an unnamed module implies the class
-          // is from the -cp or boot loader append path which consists of -Xbootclasspath/a
-          // and jvmti appended entries.
-          if ((pkg_entry == NULL) || (pkg_entry->in_unnamed_module())) {
-            // Ensure the index is within the -cp range before assigning
-            // to the classpath_index.
-            if (SystemDictionary::is_system_class_loader(loader) &&
-                (i >= ClassLoaderExt::app_class_paths_start_index()) &&
-                (i < ClassLoaderExt::app_module_paths_start_index())) {
+      if (!get_canonical_path(ent->name(), canonical_path_table_entry, JVM_MAXPATHLEN)) {
+        tty->print_cr("Bad pathname %s. CDS dump aborted.", ent->name());
+        vm_exit(1);
+      }
+      // If the path (from the class stream source) is the same as the shared
+      // class or module path, then we have a match.
+      if (strcmp(canonical_path_table_entry, canonical_class_src_path) == 0) {
+        // NULL pkg_entry and pkg_entry in an unnamed module implies the class
+        // is from the -cp or boot loader append path which consists of -Xbootclasspath/a
+        // and jvmti appended entries.
+        if ((pkg_entry == NULL) || (pkg_entry->in_unnamed_module())) {
+          // Ensure the index is within the -cp range before assigning
+          // to the classpath_index.
+          if (SystemDictionary::is_system_class_loader(loader) &&
+              (i >= ClassLoaderExt::app_class_paths_start_index()) &&
+              (i < ClassLoaderExt::app_module_paths_start_index())) {
+            classpath_index = i;
+            break;
+          } else {
+            if ((i >= 1) &&
+                (i < ClassLoaderExt::app_class_paths_start_index())) {
+              // The class must be from boot loader append path which consists of
+              // -Xbootclasspath/a and jvmti appended entries.
+              assert(loader == NULL, "sanity");
               classpath_index = i;
               break;
-            } else {
-              if ((i >= 1) &&
-                  (i < ClassLoaderExt::app_class_paths_start_index())) {
-                // The class must be from boot loader append path which consists of
-                // -Xbootclasspath/a and jvmti appended entries.
-                assert(loader == NULL, "sanity");
-                classpath_index = i;
-                break;
-              }
             }
-          } else {
-            // A class from a named module from the --module-path. Ensure the index is
-            // within the --module-path range before assigning to the classpath_index.
-            if ((pkg_entry != NULL) && !(pkg_entry->in_unnamed_module()) && (i > 0)) {
-              if (i >= ClassLoaderExt::app_module_paths_start_index() &&
-                  i < FileMapInfo::get_number_of_shared_paths()) {
-                classpath_index = i;
-                break;
-              }
+          }
+        } else {
+          // A class from a named module from the --module-path. Ensure the index is
+          // within the --module-path range before assigning to the classpath_index.
+          if ((pkg_entry != NULL) && !(pkg_entry->in_unnamed_module()) && (i > 0)) {
+            if (i >= ClassLoaderExt::app_module_paths_start_index() &&
+                i < FileMapInfo::get_number_of_shared_paths()) {
+              classpath_index = i;
+              break;
             }
           }
         }
-        // for index 0 and the stream->source() is the modules image or has the jrt: protocol.
-        // The class must be from the runtime modules image.
-        if (i == 0 && (is_modules_image(src) || string_starts_with(src, "jrt:"))) {
-          classpath_index = i;
-          break;
-        }
+      }
+      // for index 0 and the stream->source() is the modules image or has the jrt: protocol.
+      // The class must be from the runtime modules image.
+      if (i == 0 && (is_modules_image(src) || string_starts_with(src, "jrt:"))) {
+        classpath_index = i;
+        break;
       }
     }
 
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Tue May 15 10:13:52 2018 -0700
@@ -79,12 +79,11 @@
 }
 
 void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) {
-  ResourceMark rm;
+  ResourceMark rm(THREAD);
   for (int i = 0; i < met->table_size(); i++) {
     for (ModuleEntry* m = met->bucket(i); m != NULL;) {
       char* path = m->location()->as_C_string();
-      if (strncmp(path, "file:", 5) == 0 && ClassLoader::string_ends_with(path, ".jar")) {
-        m->print();
+      if (strncmp(path, "file:", 5) == 0) {
         path = ClassLoader::skip_uri_protocol(path);
         ClassLoader::setup_module_search_path(path, THREAD);
       }
--- a/src/hotspot/share/classfile/javaClasses.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue May 15 10:13:52 2018 -0700
@@ -768,7 +768,7 @@
         {
           assert(fd->signature() == vmSymbols::string_signature(),
                  "just checking");
-          if (DumpSharedSpaces && oopDesc::is_archive_object(mirror())) {
+          if (DumpSharedSpaces && MetaspaceShared::is_archive_object(mirror())) {
             // Archive the String field and update the pointer.
             oop s = mirror()->obj_field(fd->offset());
             oop archived_s = StringTable::create_archived_string(s, CHECK);
@@ -809,7 +809,7 @@
     if (MetaspaceShared::open_archive_heap_region_mapped()) {
       oop m = k->archived_java_mirror();
       assert(m != NULL, "archived mirror is NULL");
-      assert(oopDesc::is_archive_object(m), "must be archived mirror object");
+      assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
       Handle m_h(THREAD, m);
       // restore_archived_mirror() clears the klass' _has_raw_archived_mirror flag
       restore_archived_mirror(k, m_h, Handle(), Handle(), Handle(), CHECK);
@@ -3556,34 +3556,6 @@
   base->long_field_put(static_clock_offset, value);
 }
 
-// Support for java_lang_ref_ReferenceQueue
-
-oop java_lang_ref_ReferenceQueue::NULL_queue() {
-  InstanceKlass* ik = SystemDictionary::ReferenceQueue_klass();
-  oop mirror = ik->java_mirror();
-  return mirror->obj_field(static_NULL_queue_offset);
-}
-
-oop java_lang_ref_ReferenceQueue::ENQUEUED_queue() {
-  InstanceKlass* ik = SystemDictionary::ReferenceQueue_klass();
-  oop mirror = ik->java_mirror();
-  return mirror->obj_field(static_ENQUEUED_queue_offset);
-}
-
-void java_lang_ref_ReferenceQueue::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ReferenceQueue_klass();
-  compute_offset(static_NULL_queue_offset,
-                 k,
-                 vmSymbols::referencequeue_null_name(),
-                 vmSymbols::referencequeue_signature(),
-                 true /* is_static */);
-  compute_offset(static_ENQUEUED_queue_offset,
-                 k,
-                 vmSymbols::referencequeue_enqueued_name(),
-                 vmSymbols::referencequeue_signature(),
-                 true /* is_static */);
-}
-
 // Support for java_lang_invoke_DirectMethodHandle
 
 int java_lang_invoke_DirectMethodHandle::_member_offset;
@@ -4263,8 +4235,6 @@
 int java_lang_ref_Reference::queue_offset;
 int java_lang_ref_Reference::next_offset;
 int java_lang_ref_Reference::discovered_offset;
-int java_lang_ref_ReferenceQueue::static_NULL_queue_offset;
-int java_lang_ref_ReferenceQueue::static_ENQUEUED_queue_offset;
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
 int java_lang_ClassLoader::parent_offset;
@@ -4509,7 +4479,6 @@
   java_lang_StackTraceElement::compute_offsets();
   java_lang_StackFrameInfo::compute_offsets();
   java_lang_LiveStackFrameInfo::compute_offsets();
-  java_lang_ref_ReferenceQueue::compute_offsets();
 
   // generated interpreter code wants to know about the offsets we just computed:
   AbstractAssembler::update_delayed_values();
--- a/src/hotspot/share/classfile/javaClasses.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue May 15 10:13:52 2018 -0700
@@ -946,20 +946,6 @@
   static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
 };
 
-// Interface to java.lang.ref.ReferenceQueue objects
-
-class java_lang_ref_ReferenceQueue: public AllStatic {
-public:
-  static int static_NULL_queue_offset;
-  static int static_ENQUEUED_queue_offset;
-
-  // Accessors
-  static oop NULL_queue();
-  static oop ENQUEUED_queue();
-
-  static void compute_offsets();
-};
-
 // Interface to java.lang.invoke.MethodHandle objects
 
 class MethodHandleEntry;
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp	Tue May 15 10:13:52 2018 -0700
@@ -127,12 +127,6 @@
 HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
   return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
 }
-oop java_lang_ref_Reference::queue(oop ref) {
-  return ref->obj_field(queue_offset);
-}
-void java_lang_ref_Reference::set_queue(oop ref, oop value) {
-  return ref->obj_field_put(queue_offset, value);
-}
 bool java_lang_ref_Reference::is_phantom(oop ref) {
   return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
 }
--- a/src/hotspot/share/classfile/stringTable.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/stringTable.cpp	Tue May 15 10:13:52 2018 -0700
@@ -28,12 +28,13 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
-#include "gc/shared/collectedHeap.inline.hpp"
+#include "gc/shared/collectedHeap.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
@@ -44,9 +45,6 @@
 #include "services/diagnosticCommand.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_G1GC
-#include "gc/g1/g1StringDedup.hpp"
-#endif
 
 // the number of buckets a thread claims
 const int ClaimChunkSize = 32;
@@ -260,14 +258,10 @@
     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
   }
 
-#if INCLUDE_G1GC
-  if (G1StringDedup::is_enabled()) {
-    // Deduplicate the string before it is interned. Note that we should never
-    // deduplicate a string after it has been interned. Doing so will counteract
-    // compiler optimizations done on e.g. interned string literals.
-    G1StringDedup::deduplicate(string());
-  }
-#endif
+  // Deduplicate the string before it is interned. Note that we should never
+  // deduplicate a string after it has been interned. Doing so will counteract
+  // compiler optimizations done on e.g. interned string literals.
+  Universe::heap()->deduplicate_string(string());
 
   // Grab the StringTable_lock before getting the_table() because it could
   // change at safepoint.
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2076,8 +2076,6 @@
   InstanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
   InstanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
 
-  initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(ReferenceQueue_klass), scan, CHECK);
-
   // JSR 292 classes
   WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
   WKID jsr292_group_end   = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Tue May 15 10:13:52 2018 -0700
@@ -135,7 +135,6 @@
   do_klass(FinalReference_klass,                        java_lang_ref_FinalReference,              Pre                 ) \
   do_klass(PhantomReference_klass,                      java_lang_ref_PhantomReference,            Pre                 ) \
   do_klass(Finalizer_klass,                             java_lang_ref_Finalizer,                   Pre                 ) \
-  do_klass(ReferenceQueue_klass,                        java_lang_ref_ReferenceQueue,              Pre                 ) \
                                                                                                                          \
   do_klass(Thread_klass,                                java_lang_Thread,                          Pre                 ) \
   do_klass(ThreadGroup_klass,                           java_lang_ThreadGroup,                     Pre                 ) \
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Tue May 15 10:13:52 2018 -0700
@@ -86,7 +86,6 @@
   template(java_lang_ref_FinalReference,              "java/lang/ref/FinalReference")             \
   template(java_lang_ref_PhantomReference,            "java/lang/ref/PhantomReference")           \
   template(java_lang_ref_Finalizer,                   "java/lang/ref/Finalizer")                  \
-  template(java_lang_ref_ReferenceQueue,              "java/lang/ref/ReferenceQueue")             \
   template(java_lang_reflect_AccessibleObject,        "java/lang/reflect/AccessibleObject")       \
   template(java_lang_reflect_Method,                  "java/lang/reflect/Method")                 \
   template(java_lang_reflect_Constructor,             "java/lang/reflect/Constructor")            \
@@ -439,8 +438,6 @@
   template(module_entry_name,                         "module_entry")                             \
   template(resolved_references_name,                  "<resolved_references>")                    \
   template(init_lock_name,                            "<init_lock>")                              \
-  template(referencequeue_null_name,                  "NULL")                                     \
-  template(referencequeue_enqueued_name,              "ENQUEUED")                                 \
                                                                                                   \
   /* name symbols needed by intrinsics */                                                         \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
@@ -534,8 +531,6 @@
   template(string_signature,                          "Ljava/lang/String;")                                       \
   template(string_array_signature,                    "[Ljava/lang/String;")                                      \
   template(reference_signature,                       "Ljava/lang/ref/Reference;")                                \
-  template(referencequeue_signature,                  "Ljava/lang/ref/ReferenceQueue;")                           \
-  template(sun_misc_Cleaner_signature,                "Lsun/misc/Cleaner;")                                       \
   template(executable_signature,                      "Ljava/lang/reflect/Executable;")                           \
   template(module_signature,                          "Ljava/lang/Module;")                                       \
   template(concurrenthashmap_signature,               "Ljava/util/concurrent/ConcurrentHashMap;")                 \
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Tue May 15 10:13:52 2018 -0700
@@ -5062,22 +5062,6 @@
   assert(_collector->_overflow_list == NULL, "non-empty _overflow_list");
 }
 
-class CMSRefEnqueueTaskProxy: public AbstractGangTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _task;
-
-public:
-  CMSRefEnqueueTaskProxy(EnqueueTask& task)
-    : AbstractGangTask("Enqueue reference objects in parallel"),
-      _task(task)
-  { }
-
-  virtual void work(uint worker_id)
-  {
-    _task.work(worker_id);
-  }
-};
-
 CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector,
   MemRegion span, CMSBitMap* bit_map, OopTaskQueue* work_queue):
    _span(span),
@@ -5147,16 +5131,6 @@
   workers->run_task(&rp_task);
 }
 
-void CMSRefProcTaskExecutor::execute(EnqueueTask& task)
-{
-
-  CMSHeap* heap = CMSHeap::heap();
-  WorkGang* workers = heap->workers();
-  assert(workers != NULL, "Need parallel worker threads.");
-  CMSRefEnqueueTaskProxy enq_task(task);
-  workers->run_task(&enq_task);
-}
-
 void CMSCollector::refProcessingWork() {
   ResourceMark rm;
   HandleMark   hm;
@@ -7149,7 +7123,7 @@
     // coalesced chunk to the appropriate free list.
     if (inFreeRange()) {
       assert(freeFinger() >= _sp->bottom() && freeFinger() < _limit,
-             "freeFinger() " PTR_FORMAT " is out-of-bounds", p2i(freeFinger()));
+             "freeFinger() " PTR_FORMAT " is out of bounds", p2i(freeFinger()));
       flush_cur_free_chunk(freeFinger(),
                            pointer_delta(addr, freeFinger()));
       log_develop_trace(gc, sweep)("Sweep: last chunk: put_free_blk " PTR_FORMAT " (" SIZE_FORMAT ") [coalesced:%d]",
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp	Tue May 15 10:13:52 2018 -0700
@@ -487,7 +487,6 @@
 
   // Executes a task using worker threads.
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 private:
   CMSCollector& _collector;
 };
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp	Tue May 15 10:13:52 2018 -0700
@@ -789,21 +789,6 @@
              par_scan_state.evacuate_followers_closure());
 }
 
-class ParNewRefEnqueueTaskProxy: public AbstractGangTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _task;
-
-public:
-  ParNewRefEnqueueTaskProxy(EnqueueTask& task)
-    : AbstractGangTask("ParNewGeneration parallel reference enqueue"),
-      _task(task)
-  { }
-
-  virtual void work(uint worker_id) {
-    _task.work(worker_id);
-  }
-};
-
 void ParNewRefProcTaskExecutor::execute(ProcessTask& task) {
   CMSHeap* gch = CMSHeap::heap();
   WorkGang* workers = gch->workers();
@@ -816,14 +801,6 @@
                    _young_gen.promotion_failed());
 }
 
-void ParNewRefProcTaskExecutor::execute(EnqueueTask& task) {
-  CMSHeap* gch = CMSHeap::heap();
-  WorkGang* workers = gch->workers();
-  assert(workers != NULL, "Need parallel worker threads.");
-  ParNewRefEnqueueTaskProxy enq_task(task);
-  workers->run_task(&enq_task);
-}
-
 void ParNewRefProcTaskExecutor::set_single_threaded_mode() {
   _state_set.flush();
   CMSHeap* heap = CMSHeap::heap();
--- a/src/hotspot/share/gc/cms/parNewGeneration.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/cms/parNewGeneration.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -297,7 +297,6 @@
 
   // Executes a task using worker threads.
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
   // Switch to single threaded mode.
   virtual void set_single_threaded_mode();
 };
--- a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp	Tue May 15 10:13:52 2018 -0700
@@ -64,7 +64,7 @@
 
 inline PLAB* G1PLABAllocator::alloc_buffer(InCSetState dest) {
   assert(dest.is_valid(),
-         "Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value());
+         "Allocation buffer index out of bounds: " CSETSTATE_FORMAT, dest.value());
   assert(_alloc_buffers[dest.value()] != NULL,
          "Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value());
   return _alloc_buffers[dest.value()];
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2164,6 +2164,14 @@
   return ret_val;
 }
 
+void G1CollectedHeap::deduplicate_string(oop str) {
+  assert(java_lang_String::is_instance(str), "invariant");
+
+  if (G1StringDedup::is_enabled()) {
+    G1StringDedup::deduplicate(str);
+  }
+}
+
 void G1CollectedHeap::prepare_for_verify() {
   _verifier->prepare_for_verify();
 }
@@ -3783,7 +3791,6 @@
 
   // Executes the given task using concurrent marking worker threads.
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 };
 
 // Gang task for possibly parallel reference processing
@@ -3848,35 +3855,6 @@
   _workers->run_task(&proc_task_proxy);
 }
 
-// Gang task for parallel reference enqueueing.
-
-class G1STWRefEnqueueTaskProxy: public AbstractGangTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _enq_task;
-
-public:
-  G1STWRefEnqueueTaskProxy(EnqueueTask& enq_task) :
-    AbstractGangTask("Enqueue reference objects in parallel"),
-    _enq_task(enq_task)
-  { }
-
-  virtual void work(uint worker_id) {
-    _enq_task.work(worker_id);
-  }
-};
-
-// Driver routine for parallel reference enqueueing.
-// Creates an instance of the ref enqueueing gang
-// task and has the worker threads execute it.
-
-void G1STWRefProcTaskExecutor::execute(EnqueueTask& enq_task) {
-  assert(_workers != NULL, "Need parallel worker threads.");
-
-  G1STWRefEnqueueTaskProxy enq_task_proxy(enq_task);
-
-  _workers->run_task(&enq_task_proxy);
-}
-
 // End of weak reference support closures
 
 void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1338,6 +1338,9 @@
   void redirty_logged_cards();
   // Verification
 
+  // Deduplicate the string
+  virtual void deduplicate_string(oop str);
+
   // Perform any cleanup actions necessary before allowing a verification.
   virtual void prepare_for_verify();
 
@@ -1363,6 +1366,8 @@
   virtual const char* const* concurrent_phases() const;
   virtual bool request_concurrent_phase(const char* phase);
 
+  virtual WorkGang* get_safepoint_workers() { return _workers; }
+
   // The methods below are here for convenience and dispatch the
   // appropriate method depending on value of the given VerifyOption
   // parameter. The values for that parameter, and their meanings,
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1520,7 +1520,6 @@
 
   // Executes the given task using concurrent marking worker threads.
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 };
 
 class G1CMRefProcTaskProxy : public AbstractGangTask {
@@ -1565,36 +1564,6 @@
   _workers->run_task(&proc_task_proxy);
 }
 
-class G1CMRefEnqueueTaskProxy : public AbstractGangTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _enq_task;
-
-public:
-  G1CMRefEnqueueTaskProxy(EnqueueTask& enq_task) :
-    AbstractGangTask("Enqueue reference objects in parallel"),
-    _enq_task(enq_task) { }
-
-  virtual void work(uint worker_id) {
-    _enq_task.work(worker_id);
-  }
-};
-
-void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) {
-  assert(_workers != NULL, "Need parallel worker threads.");
-  assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT");
-
-  G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task);
-
-  // Not strictly necessary but...
-  //
-  // We need to reset the concurrency level before each
-  // proxy task execution, so that the termination protocol
-  // and overflow handling in G1CMTask::do_marking_step() knows
-  // how many workers to wait for.
-  _cm->set_concurrency(_active_workers);
-  _workers->run_task(&enq_task_proxy);
-}
-
 void G1ConcurrentMark::weak_refs_work(bool clear_all_soft_refs) {
   ResourceMark rm;
   HandleMark   hm;
@@ -1706,6 +1675,44 @@
   }
 }
 
+class G1PrecleanYieldClosure : public YieldClosure {
+  G1ConcurrentMark* _cm;
+
+public:
+  G1PrecleanYieldClosure(G1ConcurrentMark* cm) : _cm(cm) { }
+
+  virtual bool should_return() {
+    return _cm->has_aborted();
+  }
+
+  virtual bool should_return_fine_grain() {
+    _cm->do_yield_check();
+    return _cm->has_aborted();
+  }
+};
+
+void G1ConcurrentMark::preclean() {
+  assert(G1UseReferencePrecleaning, "Precleaning must be enabled.");
+
+  SuspendibleThreadSetJoiner joiner;
+
+  G1CMKeepAliveAndDrainClosure keep_alive(this, task(0), true /* is_serial */);
+  G1CMDrainMarkingStackClosure drain_mark_stack(this, task(0), true /* is_serial */);
+
+  set_concurrency_and_phase(1, true);
+
+  G1PrecleanYieldClosure yield_cl(this);
+
+  ReferenceProcessor* rp = _g1h->ref_processor_cm();
+  // Precleaning is single threaded. Temporarily disable MT discovery.
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
+  rp->preclean_discovered_references(rp->is_alive_non_header(),
+                                     &keep_alive,
+                                     &drain_mark_stack,
+                                     &yield_cl,
+                                     _gc_timer_cm);
+}
+
 // When sampling object counts, we already swapped the mark bitmaps, so we need to use
 // the prev bitmap determining liveness.
 class G1ObjectCountIsAliveClosure: public BoolObjectClosure {
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp	Tue May 15 10:13:52 2018 -0700
@@ -563,6 +563,9 @@
   // Do concurrent phase of marking, to a tentative transitive closure.
   void mark_from_roots();
 
+  // Do concurrent preclean work.
+  void preclean();
+
   void remark();
 
   void cleanup();
--- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp	Tue May 15 10:13:52 2018 -0700
@@ -57,6 +57,7 @@
   expander(SCAN_ROOT_REGIONS,, "Concurrent Scan Root Regions")             \
   expander(CONCURRENT_MARK,, "Concurrent Mark")                            \
   expander(MARK_FROM_ROOTS,, "Concurrent Mark From Roots")                 \
+  expander(PRECLEAN,, "Concurrent Preclean")                               \
   expander(BEFORE_REMARK,, NULL)                                           \
   expander(REMARK,, NULL)                                                  \
   expander(REBUILD_REMEMBERED_SETS,, "Concurrent Rebuild Remembered Sets") \
@@ -309,7 +310,12 @@
             break;
           }
 
-          // Provide a control point after mark_from_roots.
+          if (G1UseReferencePrecleaning) {
+            G1ConcPhase p(G1ConcurrentPhase::PRECLEAN, this);
+            _cm->preclean();
+          }
+
+          // Provide a control point before remark.
           {
             G1ConcPhaseManager p(G1ConcurrentPhase::BEFORE_REMARK, this);
           }
--- a/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -63,14 +63,6 @@
                   *marker->stack_closure());
 }
 
-G1FullGCReferenceProcessingExecutor::G1RefEnqueueTaskProxy::G1RefEnqueueTaskProxy(EnqueueTask& enq_task) :
-  AbstractGangTask("G1 reference enqueue task"),
-  _enq_task(enq_task) { }
-
-void G1FullGCReferenceProcessingExecutor::G1RefEnqueueTaskProxy::work(uint worker_id) {
-  _enq_task.work(worker_id);
-}
-
 void G1FullGCReferenceProcessingExecutor::run_task(AbstractGangTask* task) {
   G1CollectedHeap::heap()->workers()->run_task(task, _collector->workers());
 }
@@ -80,12 +72,6 @@
   run_task(&proc_task_proxy);
 }
 
-// Driver routine for parallel reference processing.
-void G1FullGCReferenceProcessingExecutor::execute(EnqueueTask& enq_task) {
-  G1RefEnqueueTaskProxy enq_task_proxy(enq_task);
-  run_task(&enq_task_proxy);
-}
-
 void G1FullGCReferenceProcessingExecutor::execute(STWGCTimer* timer, G1FullGCTracer* tracer) {
   GCTraceTime(Debug, gc, phases) debug("Phase 1: Reference Processing", timer);
   // Process reference objects found during marking.
--- a/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1FullGCReferenceProcessorExecutor.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -51,7 +51,6 @@
 
   // Executes the given task using concurrent marking worker threads.
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 
 private:
   void run_task(AbstractGangTask* task);
@@ -68,15 +67,6 @@
 
     virtual void work(uint worker_id);
   };
-
-  class G1RefEnqueueTaskProxy: public AbstractGangTask {
-    typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-    EnqueueTask& _enq_task;
-
-  public:
-    G1RefEnqueueTaskProxy(EnqueueTask& enq_task);
-    virtual void work(uint worker_id);
-  };
 };
 
 #endif // SHARE_GC_G1_G1FULLGCREFERENCEPROCESSOREXECUTOR_HPP
--- a/src/hotspot/share/gc/g1/g1_globals.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/g1/g1_globals.hpp	Tue May 15 10:13:52 2018 -0700
@@ -79,6 +79,10 @@
           "draining concurrent marking work queues.")                       \
           range(1, INT_MAX)                                                 \
                                                                             \
+  experimental(bool, G1UseReferencePrecleaning, true,                       \
+               "Concurrently preclean java.lang.ref.references instances "  \
+               "before the Remark pause.")                                  \
+                                                                            \
   experimental(double, G1LastPLABAverageOccupancy, 50.0,                    \
                "The expected average occupancy of the last PLAB in "        \
                "percent.")                                                  \
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -60,15 +60,7 @@
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
   MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);
 
-  if (_java_thread != NULL)
-    _java_thread->oops_do(
-        &mark_and_push_closure,
-        &mark_and_push_in_blobs);
-
-  if (_vm_thread != NULL)
-    _vm_thread->oops_do(
-        &mark_and_push_closure,
-        &mark_and_push_in_blobs);
+  _thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);
 
   // Do the real work
   cm->follow_marking_stacks();
@@ -175,17 +167,6 @@
   PSParallelCompact::gc_task_manager()->execute_and_wait(q);
 }
 
-void RefProcTaskExecutor::execute(EnqueueTask& task)
-{
-  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
-  uint parallel_gc_threads = heap->gc_task_manager()->workers();
-  GCTaskQueue* q = GCTaskQueue::create();
-  for(uint i=0; i<parallel_gc_threads; i++) {
-    q->enqueue(new RefEnqueueTaskProxy(task, i));
-  }
-  PSParallelCompact::gc_task_manager()->execute_and_wait(q);
-}
-
 //
 // StealMarkingTask
 //
--- a/src/hotspot/share/gc/parallel/pcTasks.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/pcTasks.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -67,11 +67,10 @@
 
 class ThreadRootsMarkingTask : public GCTask {
  private:
-  JavaThread* _java_thread;
-  VMThread* _vm_thread;
+  Thread* _thread;
+
  public:
-  ThreadRootsMarkingTask(JavaThread* root) : _java_thread(root), _vm_thread(NULL) {}
-  ThreadRootsMarkingTask(VMThread* root) : _java_thread(NULL), _vm_thread(root) {}
+  ThreadRootsMarkingTask(Thread* root) : _thread(root) {}
 
   char* name() { return (char *)"thread-roots-marking-task"; }
 
@@ -133,32 +132,6 @@
 };
 
 
-
-//
-// RefEnqueueTaskProxy
-//
-// This task is used as a proxy to parallel reference processing tasks .
-//
-
-class RefEnqueueTaskProxy: public GCTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _enq_task;
-  uint         _work_id;
-
-public:
-  RefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
-    : _enq_task(enq_task),
-      _work_id(work_id)
-  { }
-
-  virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
-  virtual void do_it(GCTaskManager* manager, uint which)
-  {
-    _enq_task.work(_work_id);
-  }
-};
-
-
 //
 // RefProcTaskExecutor
 //
@@ -168,7 +141,6 @@
 
 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 };
 
 
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Tue May 15 10:13:52 2018 -0700
@@ -71,6 +71,7 @@
   _span_based_discoverer.set_span(ParallelScavengeHeap::heap()->reserved_region());
   set_ref_processor(new ReferenceProcessor(&_span_based_discoverer));     // a vanilla ref proc
   _counters = new CollectorCounters("PSMarkSweep", 1);
+  MarkSweep::initialize();
 }
 
 // This method contains all heap specific policy for invoking mark sweep.
@@ -292,7 +293,7 @@
         assert(young_gen->max_size() >
           young_gen->from_space()->capacity_in_bytes() +
           young_gen->to_space()->capacity_in_bytes(),
-          "Sizes of space in young gen are out-of-bounds");
+          "Sizes of space in young gen are out of bounds");
 
         size_t young_live = young_gen->used_in_bytes();
         size_t eden_live = young_gen->eden_space()->used_in_bytes();
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Tue May 15 10:13:52 2018 -0700
@@ -2049,6 +2049,17 @@
   return ParallelScavengeHeap::gc_task_manager();
 }
 
+class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure {
+private:
+  GCTaskQueue* _q;
+
+public:
+  PCAddThreadRootsMarkingTaskClosure(GCTaskQueue* q) : _q(q) { }
+  void do_thread(Thread* t) {
+    _q->enqueue(new ThreadRootsMarkingTask(t));
+  }
+};
+
 void PSParallelCompact::marking_phase(ParCompactionManager* cm,
                                       bool maximum_heap_compaction,
                                       ParallelOldTracer *gc_tracer) {
@@ -2077,7 +2088,8 @@
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles));
     // We scan the thread roots in parallel
-    Threads::create_thread_roots_marking_tasks(q);
+    PCAddThreadRootsMarkingTaskClosure cl(q);
+    Threads::java_threads_and_vm_thread_do(&cl);
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Tue May 15 10:13:52 2018 -0700
@@ -148,27 +148,8 @@
   _rp_task.work(_work_id, is_alive, keep_alive, evac_followers);
 }
 
-class PSRefEnqueueTaskProxy: public GCTask {
-  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
-  EnqueueTask& _enq_task;
-  uint         _work_id;
-
-public:
-  PSRefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
-    : _enq_task(enq_task),
-      _work_id(work_id)
-  { }
-
-  virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
-  virtual void do_it(GCTaskManager* manager, uint which)
-  {
-    _enq_task.work(_work_id);
-  }
-};
-
 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
   virtual void execute(ProcessTask& task);
-  virtual void execute(EnqueueTask& task);
 };
 
 void PSRefProcTaskExecutor::execute(ProcessTask& task)
@@ -188,17 +169,6 @@
   manager->execute_and_wait(q);
 }
 
-
-void PSRefProcTaskExecutor::execute(EnqueueTask& task)
-{
-  GCTaskQueue* q = GCTaskQueue::create();
-  GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager();
-  for(uint i=0; i < manager->active_workers(); i++) {
-    q->enqueue(new PSRefEnqueueTaskProxy(task, i));
-  }
-  manager->execute_and_wait(q);
-}
-
 // This method contains all heap specific policy for invoking scavenge.
 // PSScavenge::invoke_no_policy() will do nothing but attempt to
 // scavenge. It will not clean up after failed promotions, bail out if
@@ -242,6 +212,17 @@
   return full_gc_done;
 }
 
+class PSAddThreadRootsTaskClosure : public ThreadClosure {
+private:
+  GCTaskQueue* _q;
+
+public:
+  PSAddThreadRootsTaskClosure(GCTaskQueue* q) : _q(q) { }
+  void do_thread(Thread* t) {
+    _q->enqueue(new ThreadRootsTask(t));
+  }
+};
+
 // This method contains no policy. You should probably
 // be calling invoke() instead.
 bool PSScavenge::invoke_no_policy() {
@@ -382,7 +363,8 @@
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles));
       // We scan the thread roots in parallel
-      Threads::create_thread_roots_tasks(q);
+      PSAddThreadRootsTaskClosure cl(q);
+      Threads::java_threads_and_vm_thread_do(&cl);
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
--- a/src/hotspot/share/gc/parallel/psTasks.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psTasks.cpp	Tue May 15 10:13:52 2018 -0700
@@ -119,11 +119,7 @@
   PSScavengeRootsClosure roots_closure(pm);
   MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
 
-  if (_java_thread != NULL)
-    _java_thread->oops_do(&roots_closure, &roots_in_blobs);
-
-  if (_vm_thread != NULL)
-    _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
+  _thread->oops_do(&roots_closure, &roots_in_blobs);
 
   // Do the real work
   pm->drain_stacks(false);
--- a/src/hotspot/share/gc/parallel/psTasks.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/parallel/psTasks.hpp	Tue May 15 10:13:52 2018 -0700
@@ -81,11 +81,10 @@
 
 class ThreadRootsTask : public GCTask {
  private:
-  JavaThread* _java_thread;
-  VMThread* _vm_thread;
+  Thread* _thread;
+
  public:
-  ThreadRootsTask(JavaThread* root) : _java_thread(root), _vm_thread(NULL) {}
-  ThreadRootsTask(VMThread* root) : _java_thread(NULL), _vm_thread(root) {}
+  ThreadRootsTask(Thread* root) : _thread(root) {}
 
   char* name() { return (char *)"thread-roots-task"; }
 
--- a/src/hotspot/share/gc/serial/markSweep.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/serial/markSweep.cpp	Tue May 15 10:13:52 2018 -0700
@@ -265,7 +265,7 @@
 void MarkSweep::KeepAliveClosure::do_oop(oop* p)       { MarkSweep::KeepAliveClosure::do_oop_work(p); }
 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
 
-void marksweep_init() {
+void MarkSweep::initialize() {
   MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
   MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
 }
--- a/src/hotspot/share/gc/serial/markSweep.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/serial/markSweep.hpp	Tue May 15 10:13:52 2018 -0700
@@ -87,7 +87,6 @@
   friend class AdjustPointerClosure;
   friend class KeepAliveClosure;
   friend class VM_MarkSweep;
-  friend void marksweep_init();
 
   //
   // Vars
@@ -117,6 +116,8 @@
   static KeepAliveClosure keep_alive;
 
  public:
+  static void initialize();
+
   // Public closures
   static IsAliveClosure       is_alive;
   static FollowRootClosure    follow_root_closure;
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Tue May 15 10:13:52 2018 -0700
@@ -652,3 +652,7 @@
 void CollectedHeap::unpin_object(JavaThread* thread, oop obj) {
   ShouldNotReachHere();
 }
+
+void CollectedHeap::deduplicate_string(oop str) {
+  // Do nothing, unless overridden in subclass.
+}
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Tue May 15 10:13:52 2018 -0700
@@ -597,6 +597,9 @@
   virtual oop pin_object(JavaThread* thread, oop obj);
   virtual void unpin_object(JavaThread* thread, oop obj);
 
+  // Deduplicate the string, iff the GC supports string deduplication.
+  virtual void deduplicate_string(oop str);
+
   virtual bool is_oop(oop object) const;
 
   // Non product verification and debugging.
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Tue May 15 10:13:52 2018 -0700
@@ -182,6 +182,8 @@
   initialize_size_policy(def_new_gen->eden()->capacity(),
                          _old_gen->capacity(),
                          def_new_gen->from()->capacity());
+
+  MarkSweep::initialize();
 }
 
 void GenCollectedHeap::ref_processing_init() {
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp	Tue May 15 10:13:52 2018 -0700
@@ -594,19 +594,33 @@
   bool _clear_referent;
 };
 
+void ReferenceProcessor::log_reflist(const char* prefix, DiscoveredList list[], uint num_active_queues) {
+  LogTarget(Trace, gc, ref) lt;
+
+  if (!lt.is_enabled()) {
+    return;
+  }
+
+  size_t total = 0;
+
+  LogStream ls(lt);
+  ls.print("%s", prefix);
+  for (uint i = 0; i < num_active_queues; i++) {
+    ls.print(SIZE_FORMAT " ", list[i].length());
+    total += list[i].length();
+  }
+  ls.print_cr("(" SIZE_FORMAT ")", total);
+}
+
 #ifndef PRODUCT
-void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_refs) {
+void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint num_active_queues) {
   if (!log_is_enabled(Trace, gc, ref)) {
     return;
   }
 
-  stringStream st;
-  for (uint i = 0; i < active_length; ++i) {
-    st.print(SIZE_FORMAT " ", ref_lists[i].length());
-  }
-  log_develop_trace(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs);
+  log_reflist("", ref_lists, num_active_queues);
 #ifdef ASSERT
-  for (uint i = active_length; i < _max_num_queues; i++) {
+  for (uint i = num_active_queues; i < _max_num_queues; i++) {
     assert(ref_lists[i].length() == 0, SIZE_FORMAT " unexpected References in %u",
            ref_lists[i].length(), i);
   }
@@ -629,10 +643,11 @@
   size_t total_refs = 0;
   log_develop_trace(gc, ref)("Balance ref_lists ");
 
+  log_reflist_counts(ref_lists, _max_num_queues);
+
   for (uint i = 0; i < _max_num_queues; ++i) {
     total_refs += ref_lists[i].length();
   }
-  log_reflist_counts(ref_lists, _max_num_queues, total_refs);
   size_t avg_refs = total_refs / _num_queues + 1;
   uint to_idx = 0;
   for (uint from_idx = 0; from_idx < _max_num_queues; from_idx++) {
@@ -693,11 +708,11 @@
     }
   }
 #ifdef ASSERT
+  log_reflist_counts(ref_lists, _num_queues);
   size_t balanced_total_refs = 0;
   for (uint i = 0; i < _num_queues; ++i) {
     balanced_total_refs += ref_lists[i].length();
   }
-  log_reflist_counts(ref_lists, _num_queues, balanced_total_refs);
   assert(total_refs == balanced_total_refs, "Balancing was incomplete");
 #endif
 }
@@ -790,7 +805,7 @@
       id = next_id();
     }
   }
-  assert(id < _max_num_queues, "Id is out-of-bounds id %u and max id %u)", id, _max_num_queues);
+  assert(id < _max_num_queues, "Id is out of bounds id %u and max id %u)", id, _max_num_queues);
 
   // Get the discovered queue to which we will add
   DiscoveredList* list = NULL;
@@ -1011,63 +1026,79 @@
   return false;
 }
 
-// Preclean the discovered references by removing those
-// whose referents are alive, and by marking from those that
-// are not active. These lists can be handled here
-// in any order and, indeed, concurrently.
-void ReferenceProcessor::preclean_discovered_references(
-  BoolObjectClosure* is_alive,
-  OopClosure* keep_alive,
-  VoidClosure* complete_gc,
-  YieldClosure* yield,
-  GCTimer* gc_timer) {
+void ReferenceProcessor::preclean_discovered_references(BoolObjectClosure* is_alive,
+                                                        OopClosure* keep_alive,
+                                                        VoidClosure* complete_gc,
+                                                        YieldClosure* yield,
+                                                        GCTimer* gc_timer) {
+  // These lists can be handled here in any order and, indeed, concurrently.
 
   // Soft references
   {
     GCTraceTime(Debug, gc, ref) tm("Preclean SoftReferences", gc_timer);
+    log_reflist("SoftRef before: ", _discoveredSoftRefs, _max_num_queues);
     for (uint i = 0; i < _max_num_queues; i++) {
       if (yield->should_return()) {
         return;
       }
-      preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
-                                  keep_alive, complete_gc, yield);
+      if (preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
+                                      keep_alive, complete_gc, yield)) {
+        log_reflist("SoftRef abort: ", _discoveredSoftRefs, _max_num_queues);
+        return;
+      }
     }
+    log_reflist("SoftRef after: ", _discoveredSoftRefs, _max_num_queues);
   }
 
   // Weak references
   {
     GCTraceTime(Debug, gc, ref) tm("Preclean WeakReferences", gc_timer);
+    log_reflist("WeakRef before: ", _discoveredWeakRefs, _max_num_queues);
     for (uint i = 0; i < _max_num_queues; i++) {
       if (yield->should_return()) {
         return;
       }
-      preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
-                                  keep_alive, complete_gc, yield);
+      if (preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
+                                      keep_alive, complete_gc, yield)) {
+        log_reflist("WeakRef abort: ", _discoveredWeakRefs, _max_num_queues);
+        return;
+      }
     }
+    log_reflist("WeakRef after: ", _discoveredWeakRefs, _max_num_queues);
   }
 
   // Final references
   {
     GCTraceTime(Debug, gc, ref) tm("Preclean FinalReferences", gc_timer);
+    log_reflist("FinalRef before: ", _discoveredFinalRefs, _max_num_queues);
     for (uint i = 0; i < _max_num_queues; i++) {
       if (yield->should_return()) {
         return;
       }
-      preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
-                                  keep_alive, complete_gc, yield);
+      if (preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
+                                      keep_alive, complete_gc, yield)) {
+        log_reflist("FinalRef abort: ", _discoveredFinalRefs, _max_num_queues);
+        return;
+      }
     }
+    log_reflist("FinalRef after: ", _discoveredFinalRefs, _max_num_queues);
   }
 
   // Phantom references
   {
     GCTraceTime(Debug, gc, ref) tm("Preclean PhantomReferences", gc_timer);
+    log_reflist("PhantomRef before: ", _discoveredPhantomRefs, _max_num_queues);
     for (uint i = 0; i < _max_num_queues; i++) {
       if (yield->should_return()) {
         return;
       }
-      preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
-                                  keep_alive, complete_gc, yield);
+      if (preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
+                                      keep_alive, complete_gc, yield)) {
+        log_reflist("PhantomRef abort: ", _discoveredPhantomRefs, _max_num_queues);
+        return;
+      }
     }
+    log_reflist("PhantomRef after: ", _discoveredPhantomRefs, _max_num_queues);
   }
 }
 
@@ -1079,19 +1110,20 @@
 // java.lang.Reference. As a result, we need to be careful below
 // that ref removal steps interleave safely with ref discovery steps
 // (in this thread).
-void
-ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
-                                                BoolObjectClosure* is_alive,
-                                                OopClosure*        keep_alive,
-                                                VoidClosure*       complete_gc,
-                                                YieldClosure*      yield) {
+bool ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
+                                                     BoolObjectClosure* is_alive,
+                                                     OopClosure*        keep_alive,
+                                                     VoidClosure*       complete_gc,
+                                                     YieldClosure*      yield) {
   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
+    if (yield->should_return_fine_grain()) {
+      return true;
+    }
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
     oop obj = iter.obj();
     oop next = java_lang_ref_Reference::next(obj);
-    if (iter.referent() == NULL || iter.is_referent_alive() ||
-        next != NULL) {
+    if (iter.referent() == NULL || iter.is_referent_alive() || next != NULL) {
       // The referent has been cleared, or is alive, or the Reference is not
       // active; we need to trace and mark its cohort.
       log_develop_trace(gc, ref)("Precleaning Reference (" INTPTR_FORMAT ": %s)",
@@ -1121,6 +1153,7 @@
         iter.removed(), iter.processed(), p2i(&refs_list));
     }
   )
+  return false;
 }
 
 const char* ReferenceProcessor::list_name(uint i) {
--- a/src/hotspot/share/gc/shared/referenceProcessor.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/referenceProcessor.hpp	Tue May 15 10:13:52 2018 -0700
@@ -279,15 +279,15 @@
                       OopClosure*        keep_alive,
                       VoidClosure*       complete_gc);
 
-  // "Preclean" all the discovered reference lists
-  // by removing references with strongly reachable referents.
+  // "Preclean" all the discovered reference lists by removing references that
+  // are active (e.g. due to the mutator calling enqueue()) or with NULL or
+  // strongly reachable referents.
   // The first argument is a predicate on an oop that indicates
-  // its (strong) reachability and the second is a closure that
+  // its (strong) reachability and the fourth is a closure that
   // may be used to incrementalize or abort the precleaning process.
   // The caller is responsible for taking care of potential
   // interference with concurrent operations on these lists
-  // (or predicates involved) by other threads. Currently
-  // only used by the CMS collector.
+  // (or predicates involved) by other threads.
   void preclean_discovered_references(BoolObjectClosure* is_alive,
                                       OopClosure*        keep_alive,
                                       VoidClosure*       complete_gc,
@@ -298,15 +298,17 @@
   // occupying the i / _num_queues slot.
   const char* list_name(uint i);
 
-  // "Preclean" the given discovered reference list
-  // by removing references with strongly reachable referents.
-  // Currently used in support of CMS only.
-  void preclean_discovered_reflist(DiscoveredList&    refs_list,
+private:
+  // "Preclean" the given discovered reference list by removing references with
+  // the attributes mentioned in preclean_discovered_references().
+  // Supports both normal and fine grain yielding.
+  // Returns whether the operation should be aborted.
+  bool preclean_discovered_reflist(DiscoveredList&    refs_list,
                                    BoolObjectClosure* is_alive,
                                    OopClosure*        keep_alive,
                                    VoidClosure*       complete_gc,
                                    YieldClosure*      yield);
-private:
+
   // round-robin mod _num_queues (not: _not_ mod _max_num_queues)
   uint next_id() {
     uint id = _next_id;
@@ -323,7 +325,8 @@
 
   void clear_discovered_references(DiscoveredList& refs_list);
 
-  void log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_count) PRODUCT_RETURN;
+  void log_reflist(const char* prefix, DiscoveredList list[], uint num_active_queues);
+  void log_reflist_counts(DiscoveredList ref_lists[], uint num_active_queues) PRODUCT_RETURN;
 
   // Balances reference queues.
   void balance_queues(DiscoveredList ref_lists[]);
@@ -589,11 +592,9 @@
 
   // Abstract tasks to execute.
   class ProcessTask;
-  class EnqueueTask;
 
   // Executes a task using worker threads.
   virtual void execute(ProcessTask& task) = 0;
-  virtual void execute(EnqueueTask& task) = 0;
 
   // Switch to single threaded mode.
   virtual void set_single_threaded_mode() { };
@@ -628,27 +629,4 @@
   const bool                    _marks_oops_alive;
 };
 
-// Abstract reference processing task to execute.
-class AbstractRefProcTaskExecutor::EnqueueTask {
-protected:
-  EnqueueTask(ReferenceProcessor&           ref_processor,
-              DiscoveredList                refs_lists[],
-              int                           n_queues,
-              ReferenceProcessorPhaseTimes* phase_times)
-    : _ref_processor(ref_processor),
-      _refs_lists(refs_lists),
-      _n_queues(n_queues),
-      _phase_times(phase_times)
-  { }
-
-public:
-  virtual void work(unsigned int work_id) = 0;
-
-protected:
-  ReferenceProcessor&           _ref_processor;
-  DiscoveredList*               _refs_lists;
-  ReferenceProcessorPhaseTimes* _phase_times;
-  int                           _n_queues;
-};
-
 #endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_HPP
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp	Tue May 15 10:13:52 2018 -0700
@@ -79,6 +79,8 @@
 
   size_t remaining() const                       { return end() == NULL ? 0 : pointer_delta(hard_end(), top()); }
 
+  bool is_last_allocation(HeapWord* obj, size_t size) { return pointer_delta(top(), obj) == size; }
+
   // Make parsable and release it.
   void reset();
 
@@ -129,6 +131,9 @@
   // Allocate size HeapWords. The memory is NOT initialized to zero.
   inline HeapWord* allocate(size_t size);
 
+  // Undo last allocation.
+  inline bool undo_allocate(HeapWord* obj, size_t size);
+
   // Reserve space at the end of TLAB
   static size_t end_reserve() {
     int reserve_size = typeArrayOopDesc::header_size(T_INT);
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.inline.hpp	Tue May 15 10:13:52 2018 -0700
@@ -53,6 +53,19 @@
   return NULL;
 }
 
+inline bool ThreadLocalAllocBuffer::undo_allocate(HeapWord* obj, size_t size) {
+  invariants();
+
+  if (!is_last_allocation(obj, size)) {
+    return false;
+  }
+
+  set_top(obj);
+
+  invariants();
+  return true;
+}
+
 inline size_t ThreadLocalAllocBuffer::compute_size(size_t obj_size) {
   // Compute the size for the new TLAB.
   // The "last" tlab may be smaller to reduce fragmentation.
@@ -76,7 +89,7 @@
 inline size_t ThreadLocalAllocBuffer::compute_min_size(size_t obj_size) {
   const size_t aligned_obj_size = align_object_size(obj_size);
   const size_t size_with_reserve = aligned_obj_size + alignment_reserve();
-  return MAX2(size_with_reserve, MinTLABSize);
+  return MAX2(size_with_reserve, heap_word_size(MinTLABSize));
 }
 
 void ThreadLocalAllocBuffer::record_slow_allocation(size_t obj_size) {
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue May 15 10:13:52 2018 -0700
@@ -58,6 +58,7 @@
 #include "runtime/icache.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/java.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/jfieldIDWorkaround.hpp"
 #include "runtime/osThread.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -446,17 +447,16 @@
   thread->set_vm_result(exception());
 IRT_END
 
-
-IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index))
-  char message[jintAsStringSize];
-  // lookup exception klass
-  TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
+IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, arrayOopDesc* a, jint index))
   if (ProfileTraps) {
     note_trap(thread, Deoptimization::Reason_range_check, CHECK);
   }
-  // create exception
-  sprintf(message, "%d", index);
-  THROW_MSG(s, message);
+
+  ResourceMark rm(thread);
+  stringStream ss;
+  ss.print("Index %d out of bounds for length %d", index, a->length());
+
+  THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException(
--- a/src/hotspot/share/interpreter/interpreterRuntime.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp	Tue May 15 10:13:52 2018 -0700
@@ -83,7 +83,7 @@
                                                            Klass* interfaceKlass);
   static void    throw_StackOverflowError(JavaThread* thread);
   static void    throw_delayed_StackOverflowError(JavaThread* thread);
-  static void    throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index);
+  static void    throw_ArrayIndexOutOfBoundsException(JavaThread* thread, arrayOopDesc* a, jint index);
   static void    throw_ClassCastException(JavaThread* thread, oopDesc* obj);
   static void    create_exception(JavaThread* thread, char* name, char* message);
   static void    create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
--- a/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp	Tue May 15 10:13:52 2018 -0700
@@ -173,11 +173,11 @@
   }
 
   { CodeletMark cm(_masm, "throw exception entrypoints");
-    Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
-    Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException"                 );
-    Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException"           , "/ by zero");
+    Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler();
+    Interpreter::_throw_ArrayStoreException_entry            = generate_klass_exception_handler("java/lang/ArrayStoreException");
+    Interpreter::_throw_ArithmeticException_entry            = generate_exception_handler("java/lang/ArithmeticException", "/ by zero");
     Interpreter::_throw_ClassCastException_entry             = generate_ClassCastException_handler();
-    Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException"          , NULL       );
+    Interpreter::_throw_NullPointerException_entry           = generate_exception_handler("java/lang/NullPointerException", NULL);
     Interpreter::_throw_StackOverflowError_entry             = generate_StackOverflowError_handler();
   }
 
--- a/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/interpreter/templateInterpreterGenerator.hpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -51,7 +51,7 @@
   }
   address generate_exception_handler_common(const char* name, const char* message, bool pass_oop);
   address generate_ClassCastException_handler();
-  address generate_ArrayIndexOutOfBounds_handler(const char* name);
+  address generate_ArrayIndexOutOfBounds_handler();
   address generate_return_entry_for(TosState state, int step, size_t index_size);
   address generate_earlyret_entry_for(TosState state);
   address generate_deopt_entry_for(TosState state, int step, address continuation = NULL);
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Tue May 15 10:13:52 2018 -0700
@@ -591,6 +591,9 @@
   // Get instructions and constants CodeSections early because we need it.
   _instructions = buffer.insts();
   _constants = buffer.consts();
+#if INCLUDE_AOT
+  buffer.set_immutable_PIC(_immutable_pic_compilation);
+#endif
 
   initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
   JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, false, CHECK_OK);
@@ -624,6 +627,9 @@
   // Get instructions and constants CodeSections early because we need it.
   _instructions = buffer.insts();
   _constants = buffer.consts();
+#if INCLUDE_AOT
+  buffer.set_immutable_PIC(_immutable_pic_compilation);
+#endif
 
   initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
   JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, true, CHECK_OK);
--- a/src/hotspot/share/memory/iterator.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/iterator.hpp	Tue May 15 10:13:52 2018 -0700
@@ -318,8 +318,11 @@
 // by means of checking the return value from the polling
 // call.
 class YieldClosure : public StackObj {
-  public:
-   virtual bool should_return() = 0;
+public:
+ virtual bool should_return() = 0;
+
+ // Yield on a fine-grain level. The check in case of not yielding should be very fast.
+ virtual bool should_return_fine_grain() { return false; }
 };
 
 // Abstract closure for serializing data (read or write).
--- a/src/hotspot/share/memory/metachunk.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/metachunk.cpp	Tue May 15 10:13:52 2018 -0700
@@ -107,7 +107,7 @@
   Copy::fill_to_words(start, size, word_value);
 }
 
-void Metachunk::verify() {
+void Metachunk::verify() const {
   assert(is_valid_sentinel(), "Chunk " PTR_FORMAT ": sentinel invalid", p2i(this));
   const ChunkIndex chunk_type = get_chunk_type();
   assert(is_valid_chunktype(chunk_type), "Chunk " PTR_FORMAT ": Invalid chunk type.", p2i(this));
--- a/src/hotspot/share/memory/metachunk.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/metachunk.hpp	Tue May 15 10:13:52 2018 -0700
@@ -228,7 +228,7 @@
   bool is_class() const                 { return _is_class; }
 
   DEBUG_ONLY(void mangle(juint word_value);)
-  DEBUG_ONLY(void verify();)
+  DEBUG_ONLY(void verify() const;)
 
 };
 
--- a/src/hotspot/share/memory/metaspace.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/metaspace.cpp	Tue May 15 10:13:52 2018 -0700
@@ -299,11 +299,11 @@
   void remove_chunk(Metachunk* chunk);
 
   // Return a single chunk of type index to the ChunkManager.
-  void return_single_chunk(ChunkIndex index, Metachunk* chunk);
+  void return_single_chunk(Metachunk* chunk);
 
   // Add the simple linked list of chunks to the freelist of chunks
   // of type index.
-  void return_chunk_list(ChunkIndex index, Metachunk* chunk);
+  void return_chunk_list(Metachunk* chunks);
 
   // Total of the space in the free chunks list
   size_t free_chunks_total_words();
@@ -1281,7 +1281,7 @@
   // List of chunks in use by this SpaceManager.  Allocations
   // are done from the current chunk.  The list is used for deallocating
   // chunks when the SpaceManager is freed.
-  Metachunk* _chunks_in_use[NumberOfInUseLists];
+  Metachunk* _chunk_list;
   Metachunk* _current_chunk;
 
   // Maximum number of small chunks to allocate to a SpaceManager
@@ -1298,6 +1298,7 @@
   size_t _overhead_words;
   size_t _capacity_words;
   size_t _used_words;
+  uintx _num_chunks_by_type[NumberOfInUseLists];
 
   // Free lists of blocks are per SpaceManager since they
   // are assumed to be in chunks in use by the SpaceManager
@@ -1307,10 +1308,7 @@
 
  private:
   // Accessors
-  Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; }
-  void set_chunks_in_use(ChunkIndex index, Metachunk* v) {
-    _chunks_in_use[index] = v;
-  }
+  Metachunk* chunk_list() const { return _chunk_list; }
 
   BlockFreelist* block_freelists() const { return _block_freelists; }
 
@@ -1338,9 +1336,6 @@
   // Verify internal counters against the current state. Expects to be locked with lock().
   DEBUG_ONLY(void verify_metrics_locked() const;)
 
- protected:
-  void initialize();
-
  public:
   SpaceManager(Metaspace::MetadataType mdtype,
                Metaspace::MetaspaceType space_type,
@@ -1393,7 +1388,7 @@
   size_t get_initial_chunk_size(Metaspace::MetaspaceType type) const;
 
   // Todo: remove this once we have counters by chunk type.
-  size_t sum_count_in_chunks_in_use(ChunkIndex i);
+  uintx num_chunks_by_type(ChunkIndex chunk_type) const       { return _num_chunks_by_type[chunk_type]; }
 
   Metachunk* get_new_chunk(size_t chunk_word_size);
 
@@ -1619,7 +1614,7 @@
 
     // Return Chunk to freelist.
     inc_container_count();
-    chunk_manager->return_single_chunk(padding_chunk_type, padding_chunk);
+    chunk_manager->return_single_chunk(padding_chunk);
     // Please note: at this point, ChunkManager::return_single_chunk()
     // may already have merged the padding chunk with neighboring chunks, so
     // it may have vanished at this point. Do not reference the padding
@@ -2122,7 +2117,7 @@
       if (chunk == NULL) {
         break;
       }
-      chunk_manager->return_single_chunk(index, chunk);
+      chunk_manager->return_single_chunk(chunk);
     }
     DEBUG_ONLY(verify_container_count();)
   }
@@ -3026,10 +3021,10 @@
   return chunk;
 }
 
-void ChunkManager::return_single_chunk(ChunkIndex index, Metachunk* chunk) {
+void ChunkManager::return_single_chunk(Metachunk* chunk) {
+  const ChunkIndex index = chunk->get_chunk_type();
   assert_lock_strong(MetaspaceExpand_lock);
   DEBUG_ONLY(do_verify_chunk(chunk);)
-  assert(chunk->get_chunk_type() == index, "Chunk does not match expected index.");
   assert(chunk != NULL, "Expected chunk.");
   assert(chunk->container() != NULL, "Container should have been set.");
   assert(chunk->is_tagged_free() == false, "Chunk should be in use.");
@@ -3077,14 +3072,13 @@
 
 }
 
-void ChunkManager::return_chunk_list(ChunkIndex index, Metachunk* chunks) {
-  index_bounds_check(index);
+void ChunkManager::return_chunk_list(Metachunk* chunks) {
   if (chunks == NULL) {
     return;
   }
   LogTarget(Trace, gc, metaspace, freelist) log;
   if (log.is_enabled()) { // tracing
-    log.print("returning list of %s chunks...", chunk_size_name(index));
+    log.print("returning list of chunks...");
   }
   unsigned num_chunks_returned = 0;
   size_t size_chunks_returned = 0;
@@ -3097,17 +3091,12 @@
       num_chunks_returned ++;
       size_chunks_returned += cur->word_size();
     }
-    return_single_chunk(index, cur);
+    return_single_chunk(cur);
     cur = next;
   }
   if (log.is_enabled()) { // tracing
-    log.print("returned %u %s chunks to freelist, total word size " SIZE_FORMAT ".",
-        num_chunks_returned, chunk_size_name(index), size_chunks_returned);
-    if (index != HumongousIndex) {
-      log.print("updated freelist count: " SIZE_FORMAT ".", free_chunks(index)->size());
-    } else {
-      log.print("updated dictionary count " SIZE_FORMAT ".", _humongous_dictionary.total_count());
-    }
+    log.print("returned %u chunks to freelist, total word size " SIZE_FORMAT ".",
+        num_chunks_returned, size_chunks_returned);
   }
 }
 
@@ -3170,28 +3159,11 @@
   return adjusted;
 }
 
-size_t SpaceManager::sum_count_in_chunks_in_use(ChunkIndex i) {
-  size_t count = 0;
-  Metachunk* chunk = chunks_in_use(i);
-  while (chunk != NULL) {
-    count++;
-    chunk = chunk->next();
-  }
-  return count;
-}
-
 void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const {
 
   for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
-    Metachunk* chunk = chunks_in_use(i);
-    st->print("SpaceManager: %s " PTR_FORMAT,
-                 chunk_size_name(i), p2i(chunk));
-    if (chunk != NULL) {
-      st->print_cr(" free " SIZE_FORMAT,
-                   chunk->free_word_size());
-    } else {
-      st->cr();
-    }
+    st->print("SpaceManager: " UINTX_FORMAT " %s chunks.",
+        num_chunks_by_type(i), chunk_size_name(i));
   }
 
   chunk_manager()->locked_print_free_chunks(st);
@@ -3212,13 +3184,13 @@
   // reduces space waste from 60+% to around 30%.
   if ((_space_type == Metaspace::AnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) &&
       _mdtype == Metaspace::NonClassType &&
-      sum_count_in_chunks_in_use(SpecializedIndex) < _anon_and_delegating_metadata_specialize_chunk_limit &&
+      num_chunks_by_type(SpecializedIndex) < _anon_and_delegating_metadata_specialize_chunk_limit &&
       word_size + Metachunk::overhead() <= SpecializedChunk) {
     return SpecializedChunk;
   }
 
-  if (chunks_in_use(MediumIndex) == NULL &&
-      sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
+  if (num_chunks_by_type(MediumIndex) == 0 &&
+      num_chunks_by_type(SmallIndex) < _small_chunk_limit) {
     chunk_word_size = (size_t) small_chunk_size();
     if (word_size + Metachunk::overhead() > small_chunk_size()) {
       chunk_word_size = medium_chunk_size();
@@ -3324,9 +3296,13 @@
   _used_words(0),
   _overhead_words(0),
   _block_freelists(NULL),
-  _lock(lock)
+  _lock(lock),
+  _chunk_list(NULL),
+  _current_chunk(NULL)
 {
-  initialize();
+  Metadebug::init_allocation_fail_alot_count();
+  memset(_num_chunks_by_type, 0, sizeof(_num_chunks_by_type));
+  log_trace(gc, metaspace, freelist)("SpaceManager(): " PTR_FORMAT, p2i(this));
 }
 
 void SpaceManager::account_for_new_chunk(const Metachunk* new_chunk) {
@@ -3335,6 +3311,8 @@
 
   _capacity_words += new_chunk->word_size();
   _overhead_words += Metachunk::overhead();
+  DEBUG_ONLY(new_chunk->verify());
+  _num_chunks_by_type[new_chunk->get_chunk_type()] ++;
 
   // Adjust global counters:
   MetaspaceUtils::inc_capacity(mdtype(), new_chunk->word_size());
@@ -3362,15 +3340,6 @@
   MetaspaceUtils::dec_used(mdtype(), _used_words);
 }
 
-void SpaceManager::initialize() {
-  Metadebug::init_allocation_fail_alot_count();
-  for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
-    _chunks_in_use[i] = NULL;
-  }
-  _current_chunk = NULL;
-  log_trace(gc, metaspace, freelist)("SpaceManager(): " PTR_FORMAT, p2i(this));
-}
-
 SpaceManager::~SpaceManager() {
 
   // This call this->_lock which can't be done while holding MetaspaceExpand_lock
@@ -3399,12 +3368,11 @@
 
   // Follow each list of chunks-in-use and add them to the
   // free lists.  Each list is NULL terminated.
-
-  for (ChunkIndex i = ZeroIndex; i <= HumongousIndex; i = next_chunk_index(i)) {
-    Metachunk* chunks = chunks_in_use(i);
-    chunk_manager()->return_chunk_list(i, chunks);
-    set_chunks_in_use(i, NULL);
-  }
+  chunk_manager()->return_chunk_list(chunk_list());
+#ifdef ASSERT
+  _chunk_list = NULL;
+  _current_chunk = NULL;
+#endif
 
   chunk_manager()->slow_locked_verify();
 
@@ -3446,8 +3414,8 @@
   }
 
   // Add the new chunk at the head of its respective chunk list.
-  new_chunk->set_next(chunks_in_use(index));
-  set_chunks_in_use(index, new_chunk);
+  new_chunk->set_next(_chunk_list);
+  _chunk_list = new_chunk;
 
   // Adjust counters.
   account_for_new_chunk(new_chunk);
@@ -3540,21 +3508,17 @@
 
   if (result != NULL) {
     account_for_allocation(word_size);
-    assert(result != (MetaWord*) chunks_in_use(MediumIndex),
-           "Head of the list is being allocated");
   }
 
   return result;
 }
 
 void SpaceManager::verify() {
-  for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
-    Metachunk* curr = chunks_in_use(i);
-    while (curr != NULL) {
-      DEBUG_ONLY(do_verify_chunk(curr);)
-      assert(curr->is_tagged_free() == false, "Chunk should be tagged as in use.");
-      curr = curr->next();
-    }
+  Metachunk* curr = chunk_list();
+  while (curr != NULL) {
+    DEBUG_ONLY(do_verify_chunk(curr);)
+    assert(curr->is_tagged_free() == false, "Chunk should be tagged as in use.");
+    curr = curr->next();
   }
 }
 
@@ -3569,21 +3533,19 @@
 
 void SpaceManager::add_to_statistics_locked(SpaceManagerStatistics* out) const {
   assert_lock_strong(lock());
-  for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
-    UsedChunksStatistics& chunk_stat = out->chunk_stats(i);
-    Metachunk* chunk = chunks_in_use(i);
-    while (chunk != NULL) {
-      chunk_stat.add_num(1);
-      chunk_stat.add_cap(chunk->word_size());
-      chunk_stat.add_overhead(Metachunk::overhead());
-      chunk_stat.add_used(chunk->used_word_size() - Metachunk::overhead());
-      if (chunk != current_chunk()) {
-        chunk_stat.add_waste(chunk->free_word_size());
-      } else {
-        chunk_stat.add_free(chunk->free_word_size());
-      }
-      chunk = chunk->next();
+  Metachunk* chunk = chunk_list();
+  while (chunk != NULL) {
+    UsedChunksStatistics& chunk_stat = out->chunk_stats(chunk->get_chunk_type());
+    chunk_stat.add_num(1);
+    chunk_stat.add_cap(chunk->word_size());
+    chunk_stat.add_overhead(Metachunk::overhead());
+    chunk_stat.add_used(chunk->used_word_size() - Metachunk::overhead());
+    if (chunk != current_chunk()) {
+      chunk_stat.add_waste(chunk->free_word_size());
+    } else {
+      chunk_stat.add_free(chunk->free_word_size());
     }
+    chunk = chunk->next();
   }
   if (block_freelists() != NULL) {
     out->add_free_blocks_info(block_freelists()->num_blocks(), block_freelists()->total_size());
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1922,6 +1922,10 @@
   }
 }
 
+bool MetaspaceShared::is_archive_object(oop p) {
+  return (p == NULL) ? false : G1ArchiveAllocator::is_archive_object(p);
+}
+
 void MetaspaceShared::fixup_mapped_heap_regions() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
   mapinfo->fixup_mapped_heap_regions();
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Tue May 15 10:13:52 2018 -0700
@@ -113,6 +113,9 @@
   static oop archive_heap_object(oop obj, Thread* THREAD);
   static void archive_klass_objects(Thread* THREAD);
 #endif
+
+  static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
+
   static bool is_heap_object_archiving_allowed() {
     CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);)
     NOT_CDS_JAVA_HEAP(return false;)
--- a/src/hotspot/share/oops/klass.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/klass.cpp	Tue May 15 10:13:52 2018 -0700
@@ -536,7 +536,7 @@
       log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
       if (m != NULL) {
         // mirror is archived, restore
-        assert(oopDesc::is_archive_object(m), "must be archived mirror object");
+        assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
         Handle m_h(THREAD, m);
         java_lang_Class::restore_archived_mirror(this, m_h, loader, module_handle, protection_domain, CHECK);
         return;
--- a/src/hotspot/share/oops/objArrayKlass.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/objArrayKlass.cpp	Tue May 15 10:13:52 2018 -0700
@@ -251,12 +251,34 @@
 
   // Check is all offsets and lengths are non negative
   if (src_pos < 0 || dst_pos < 0 || length < 0) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+    // Pass specific exception reason.
+    ResourceMark rm;
+    stringStream ss;
+    if (src_pos < 0) {
+      ss.print("arraycopy: source index %d out of bounds for object array[%d]",
+               src_pos, s->length());
+    } else if (dst_pos < 0) {
+      ss.print("arraycopy: destination index %d out of bounds for object array[%d]",
+               dst_pos, d->length());
+    } else {
+      ss.print("arraycopy: length %d is negative", length);
+    }
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
   // Check if the ranges are valid
-  if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
-     || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+  if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
+      (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
+    // Pass specific exception reason.
+    ResourceMark rm;
+    stringStream ss;
+    if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
+      ss.print("arraycopy: last source index %u out of bounds for object array[%d]",
+               (unsigned int) length + (unsigned int) src_pos, s->length());
+    } else {
+      ss.print("arraycopy: last destination index %u out of bounds for object array[%d]",
+               (unsigned int) length + (unsigned int) dst_pos, d->length());
+    }
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
 
   // Special case. Boundary cases must be checked first
--- a/src/hotspot/share/oops/oop.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/oop.cpp	Tue May 15 10:13:52 2018 -0700
@@ -32,9 +32,6 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/copy.hpp"
-#if INCLUDE_G1GC
-#include "gc/g1/g1Allocator.inline.hpp"
-#endif
 
 bool always_do_update_barrier = false;
 
@@ -214,9 +211,3 @@
 
 jdouble oopDesc::double_field_acquire(int offset) const               { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); }
 void oopDesc::release_double_field_put(int offset, jdouble value)     { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); }
-
-#if INCLUDE_CDS_JAVA_HEAP
-bool oopDesc::is_archive_object(oop p) {
-  return (p == NULL) ? false : G1ArchiveAllocator::is_archive_object(p);
-}
-#endif
--- a/src/hotspot/share/oops/oop.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/oop.hpp	Tue May 15 10:13:52 2018 -0700
@@ -339,8 +339,6 @@
     assert(has_klass_gap(), "only applicable to compressed klass pointers");
     return klass_offset_in_bytes() + sizeof(narrowKlass);
   }
-
-  static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
 };
 
 #endif // SHARE_VM_OOPS_OOP_HPP
--- a/src/hotspot/share/oops/oop.inline.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/oop.inline.hpp	Tue May 15 10:13:52 2018 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_OOP_INLINE_HPP
 
 #include "gc/shared/collectedHeap.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/arrayKlass.hpp"
 #include "oops/arrayOop.hpp"
@@ -329,8 +330,8 @@
          "forwarding to something not aligned");
   assert(Universe::heap()->is_in_reserved(p),
          "forwarding to something not in heap");
-  assert(!is_archive_object(oop(this)) &&
-         !is_archive_object(p),
+  assert(!MetaspaceShared::is_archive_object(oop(this)) &&
+         !MetaspaceShared::is_archive_object(p),
          "forwarding archive object");
   markOop m = markOopDesc::encode_pointer_as_mark(p);
   assert(m->decode_pointer() == p, "encoding must be reversable");
--- a/src/hotspot/share/oops/typeArrayKlass.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/oops/typeArrayKlass.cpp	Tue May 15 10:13:52 2018 -0700
@@ -138,12 +138,36 @@
 
   // Check is all offsets and lengths are non negative
   if (src_pos < 0 || dst_pos < 0 || length < 0) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+    // Pass specific exception reason.
+    ResourceMark rm;
+    stringStream ss;
+    if (src_pos < 0) {
+      ss.print("arraycopy: source index %d out of bounds for %s[%d]",
+               src_pos, type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
+    } else if (dst_pos < 0) {
+      ss.print("arraycopy: destination index %d out of bounds for %s[%d]",
+               dst_pos, type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
+    } else {
+      ss.print("arraycopy: length %d is negative", length);
+    }
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
   // Check if the ranges are valid
-  if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
-     || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+  if ((((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) ||
+      (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length())) {
+    // Pass specific exception reason.
+    ResourceMark rm;
+    stringStream ss;
+    if (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length()) {
+      ss.print("arraycopy: last source index %u out of bounds for %s[%d]",
+               (unsigned int) length + (unsigned int) src_pos,
+               type2name_tab[ArrayKlass::cast(s->klass())->element_type()], s->length());
+    } else {
+      ss.print("arraycopy: last destination index %u out of bounds for %s[%d]",
+               (unsigned int) length + (unsigned int) dst_pos,
+               type2name_tab[ArrayKlass::cast(d->klass())->element_type()], d->length());
+    }
+    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
   }
   // Check zero copy
   if (length == 0)
@@ -157,7 +181,6 @@
   HeapAccess<ARRAYCOPY_ATOMIC>::arraycopy(s, d, src, dst, (size_t)length << l2es);
 }
 
-
 // create a klass of array holding typeArrays
 Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
   int dim = dimension();
@@ -240,16 +263,11 @@
 void TypeArrayKlass::print_value_on(outputStream* st) const {
   assert(is_klass(), "must be klass");
   st->print("{type array ");
-  switch (element_type()) {
-    case T_BOOLEAN: st->print("bool");    break;
-    case T_CHAR:    st->print("char");    break;
-    case T_FLOAT:   st->print("float");   break;
-    case T_DOUBLE:  st->print("double");  break;
-    case T_BYTE:    st->print("byte");    break;
-    case T_SHORT:   st->print("short");   break;
-    case T_INT:     st->print("int");     break;
-    case T_LONG:    st->print("long");    break;
-    default: ShouldNotReachHere();
+  BasicType bt = element_type();
+  if (bt == T_BOOLEAN) {
+    st->print("bool");
+  } else {
+    st->print("%s", type2name_tab[bt]);
   }
   st->print("}");
 }
--- a/src/hotspot/share/opto/library_call.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/opto/library_call.cpp	Tue May 15 10:13:52 2018 -0700
@@ -52,6 +52,7 @@
 #include "opto/subnode.hpp"
 #include "prims/nativeLookup.hpp"
 #include "prims/unsafe.hpp"
+#include "runtime/objectMonitor.hpp"
 #include "runtime/sharedRuntime.hpp"
 #ifdef TRACE_HAVE_INTRINSICS
 #include "trace/traceMacros.hpp"
@@ -545,7 +546,7 @@
 
   case vmIntrinsics::_notify:
   case vmIntrinsics::_notifyAll:
-    if (InlineNotify) {
+    if (ObjectMonitor::Knob_InlineNotify) {
       return inline_notify(intrinsic_id());
     }
     return false;
--- a/src/hotspot/share/opto/loopnode.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/opto/loopnode.cpp	Tue May 15 10:13:52 2018 -0700
@@ -413,11 +413,38 @@
   Node* trunc1 = NULL;
   Node* trunc2 = NULL;
   const TypeInt* iv_trunc_t = NULL;
+  Node* orig_incr = incr;
   if (!(incr = CountedLoopNode::match_incr_with_optional_truncation(incr, &trunc1, &trunc2, &iv_trunc_t))) {
     return false; // Funny increment opcode
   }
   assert(incr->Opcode() == Op_AddI, "wrong increment code");
 
+  const TypeInt* limit_t = gvn->type(limit)->is_int();
+  if (trunc1 != NULL) {
+    // When there is a truncation, we must be sure that after the truncation
+    // the trip counter will end up higher than the limit, otherwise we are looking
+    // at an endless loop. Can happen with range checks.
+
+    // Example:
+    // int i = 0;
+    // while (true)
+    //    sum + = array[i];
+    //    i++;
+    //    i = i && 0x7fff;
+    //  }
+    //
+    // If the array is shorter than 0x8000 this exits through a AIOOB
+    //  - Counted loop transformation is ok
+    // If the array is longer then this is an endless loop
+    //  - No transformation can be done.
+
+    const TypeInt* incr_t = gvn->type(orig_incr)->is_int();
+    if (limit_t->_hi > incr_t->_hi) {
+      // if the limit can have a higher value than the increment (before the phi)
+      return false;
+    }
+  }
+
   // Get merge point
   Node *xphi = incr->in(1);
   Node *stride = incr->in(2);
@@ -499,7 +526,6 @@
   }
 
   const TypeInt* init_t = gvn->type(init_trip)->is_int();
-  const TypeInt* limit_t = gvn->type(limit)->is_int();
 
   if (stride_con > 0) {
     jlong init_p = (jlong)init_t->_lo + stride_con;
@@ -3218,10 +3244,16 @@
 void PhaseIdealLoop::recompute_dom_depth() {
   uint no_depth_marker = C->unique();
   uint i;
-  // Initialize depth to "no depth yet"
+  // Initialize depth to "no depth yet" and realize all lazy updates
   for (i = 0; i < _idom_size; i++) {
+    // Only indices with a _dom_depth has a Node* or NULL (otherwise uninitalized).
     if (_dom_depth[i] > 0 && _idom[i] != NULL) {
-     _dom_depth[i] = no_depth_marker;
+      _dom_depth[i] = no_depth_marker;
+
+      // heal _idom if it has a fwd mapping in _nodes
+      if (_idom[i]->in(0) == NULL) {
+        idom(i);
+      }
     }
   }
   if (_dom_stk == NULL) {
--- a/src/hotspot/share/opto/loopnode.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/opto/loopnode.hpp	Tue May 15 10:13:52 2018 -0700
@@ -852,27 +852,35 @@
   // Array of immediate dominance info for each CFG node indexed by node idx
 private:
   uint _idom_size;
-  Node **_idom;                 // Array of immediate dominators
-  uint *_dom_depth;           // Used for fast LCA test
+  Node **_idom;                  // Array of immediate dominators
+  uint *_dom_depth;              // Used for fast LCA test
   GrowableArray<uint>* _dom_stk; // For recomputation of dom depth
 
   Node* idom_no_update(Node* d) const {
-    assert(d->_idx < _idom_size, "oob");
-    Node* n = _idom[d->_idx];
+    return idom_no_update(d->_idx);
+  }
+
+  Node* idom_no_update(uint didx) const {
+    assert(didx < _idom_size, "oob");
+    Node* n = _idom[didx];
     assert(n != NULL,"Bad immediate dominator info.");
-    while (n->in(0) == NULL) {  // Skip dead CFG nodes
-      //n = n->in(1);
+    while (n->in(0) == NULL) { // Skip dead CFG nodes
       n = (Node*)(((intptr_t)_nodes[n->_idx]) & ~1);
       assert(n != NULL,"Bad immediate dominator info.");
     }
     return n;
   }
+
   Node *idom(Node* d) const {
-    uint didx = d->_idx;
-    Node *n = idom_no_update(d);
-    _idom[didx] = n;            // Lazily remove dead CFG nodes from table.
+    return idom(d->_idx);
+  }
+
+  Node *idom(uint didx) const {
+    Node *n = idom_no_update(didx);
+    _idom[didx] = n; // Lazily remove dead CFG nodes from table.
     return n;
   }
+
   uint dom_depth(Node* d) const {
     guarantee(d != NULL, "Null dominator info.");
     guarantee(d->_idx < _idom_size, "");
--- a/src/hotspot/share/prims/jvm.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/prims/jvm.cpp	Tue May 15 10:13:52 2018 -0700
@@ -629,35 +629,6 @@
 JVM_END
 
 
-template<DecoratorSet decorators>
-static void fixup_clone_referent(oop src, oop new_obj) {
-  typedef HeapAccess<decorators> RefAccess;
-  const int ref_offset = java_lang_ref_Reference::referent_offset;
-  oop referent = RefAccess::oop_load_at(src, ref_offset);
-  RefAccess::oop_store_at(new_obj, ref_offset, referent);
-}
-
-static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
-  // Kludge: After unbarriered clone, re-copy the referent with
-  // correct barriers. This works for current collectors, but won't
-  // work for ZGC and maybe other future collectors or variants of
-  // existing ones (like G1 with concurrent reference processing).
-  if (ref_type == REF_PHANTOM) {
-    fixup_clone_referent<ON_PHANTOM_OOP_REF>(src, clone);
-  } else {
-    fixup_clone_referent<ON_WEAK_OOP_REF>(src, clone);
-  }
-  if ((java_lang_ref_Reference::next(clone) != NULL) ||
-      (java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) {
-    // If the source has been enqueued or is being enqueued, don't
-    // register the clone with a queue.
-    java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());
-  }
-  // discovered and next are list links; the clone is not in those lists.
-  java_lang_ref_Reference::set_discovered(clone, NULL);
-  java_lang_ref_Reference::set_next(clone, NULL);
-}
-
 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
   JVMWrapper("JVM_Clone");
   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
@@ -676,35 +647,27 @@
 #endif
 
   // Check if class of obj supports the Cloneable interface.
-  // All arrays are considered to be cloneable (See JLS 20.1.5)
-  if (!klass->is_cloneable()) {
+  // All arrays are considered to be cloneable (See JLS 20.1.5).
+  // All j.l.r.Reference classes are considered non-cloneable.
+  if (!klass->is_cloneable() ||
+      (klass->is_instance_klass() &&
+       InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
     ResourceMark rm(THREAD);
     THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
   }
 
   // Make shallow object copy
-  ReferenceType ref_type = REF_NONE;
   const int size = obj->size();
   oop new_obj_oop = NULL;
   if (obj->is_array()) {
     const int length = ((arrayOop)obj())->length();
     new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
   } else {
-    ref_type = InstanceKlass::cast(klass)->reference_type();
-    assert((ref_type == REF_NONE) ==
-           !klass->is_subclass_of(SystemDictionary::Reference_klass()),
-           "invariant");
     new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
   }
 
   HeapAccess<>::clone(obj(), new_obj_oop, size);
 
-  // If cloning a Reference, set Reference fields to a safe state.
-  // Fixup must be completed before any safepoint.
-  if (ref_type != REF_NONE) {
-    fixup_cloned_reference(ref_type, obj(), new_obj_oop);
-  }
-
   Handle new_obj(THREAD, new_obj_oop);
   // Caution: this involves a java upcall, so the clone should be
   // "gc-robust" by this stage.
--- a/src/hotspot/share/prims/whitebox.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/prims/whitebox.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1713,7 +1713,7 @@
 
 WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj))
   oop obj_oop = JNIHandles::resolve(obj);
-  return oopDesc::is_archive_object(obj_oop);
+  return MetaspaceShared::is_archive_object(obj_oop);
 WB_END
 
 WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz))
--- a/src/hotspot/share/runtime/advancedThresholdPolicy.cpp	Tue May 15 18:03:31 2018 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,667 +0,0 @@
-/*
- * Copyright (c) 2010, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "code/codeCache.hpp"
-#include "runtime/advancedThresholdPolicy.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/simpleThresholdPolicy.inline.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmciRuntime.hpp"
-#endif
-
-#ifdef TIERED
-// Print an event.
-void AdvancedThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
-                                             int bci, CompLevel level) {
-  tty->print(" rate=");
-  if (mh->prev_time() == 0) tty->print("n/a");
-  else tty->print("%f", mh->rate());
-
-  tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
-                               threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
-
-}
-
-void AdvancedThresholdPolicy::initialize() {
-  int count = CICompilerCount;
-#ifdef _LP64
-  // Turn on ergonomic compiler count selection
-  if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
-    FLAG_SET_DEFAULT(CICompilerCountPerCPU, true);
-  }
-  if (CICompilerCountPerCPU) {
-    // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
-    int log_cpu = log2_intptr(os::active_processor_count());
-    int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
-    count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
-    FLAG_SET_ERGO(intx, CICompilerCount, count);
-  }
-#else
-  // On 32-bit systems, the number of compiler threads is limited to 3.
-  // On these systems, the virtual address space available to the JVM
-  // is usually limited to 2-4 GB (the exact value depends on the platform).
-  // As the compilers (especially C2) can consume a large amount of
-  // memory, scaling the number of compiler threads with the number of
-  // available cores can result in the exhaustion of the address space
-  /// available to the VM and thus cause the VM to crash.
-  if (FLAG_IS_DEFAULT(CICompilerCount)) {
-    count = 3;
-    FLAG_SET_ERGO(intx, CICompilerCount, count);
-  }
-#endif
-
-  if (TieredStopAtLevel < CompLevel_full_optimization) {
-    // No C2 compiler thread required
-    set_c1_count(count);
-  } else {
-    set_c1_count(MAX2(count / 3, 1));
-    set_c2_count(MAX2(count - c1_count(), 1));
-  }
-  assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
-
-  // Some inlining tuning
-#ifdef X86
-  if (FLAG_IS_DEFAULT(InlineSmallCode)) {
-    FLAG_SET_DEFAULT(InlineSmallCode, 2000);
-  }
-#endif
-
-#if defined SPARC || defined AARCH64
-  if (FLAG_IS_DEFAULT(InlineSmallCode)) {
-    FLAG_SET_DEFAULT(InlineSmallCode, 2500);
-  }
-#endif
-
-  set_increase_threshold_at_ratio();
-  set_start_time(os::javaTimeMillis());
-}
-
-// update_rate() is called from select_task() while holding a compile queue lock.
-void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) {
-  // Skip update if counters are absent.
-  // Can't allocate them since we are holding compile queue lock.
-  if (m->method_counters() == NULL)  return;
-
-  if (is_old(m)) {
-    // We don't remove old methods from the queue,
-    // so we can just zero the rate.
-    m->set_rate(0);
-    return;
-  }
-
-  // We don't update the rate if we've just came out of a safepoint.
-  // delta_s is the time since last safepoint in milliseconds.
-  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
-  jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
-  // How many events were there since the last time?
-  int event_count = m->invocation_count() + m->backedge_count();
-  int delta_e = event_count - m->prev_event_count();
-
-  // We should be running for at least 1ms.
-  if (delta_s >= TieredRateUpdateMinTime) {
-    // And we must've taken the previous point at least 1ms before.
-    if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
-      m->set_prev_time(t);
-      m->set_prev_event_count(event_count);
-      m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
-    } else {
-      if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
-        // If nothing happened for 25ms, zero the rate. Don't modify prev values.
-        m->set_rate(0);
-      }
-    }
-  }
-}
-
-// Check if this method has been stale from a given number of milliseconds.
-// See select_task().
-bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) {
-  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
-  jlong delta_t = t - m->prev_time();
-  if (delta_t > timeout && delta_s > timeout) {
-    int event_count = m->invocation_count() + m->backedge_count();
-    int delta_e = event_count - m->prev_event_count();
-    // Return true if there were no events.
-    return delta_e == 0;
-  }
-  return false;
-}
-
-// We don't remove old methods from the compile queue even if they have
-// very low activity. See select_task().
-bool AdvancedThresholdPolicy::is_old(Method* method) {
-  return method->invocation_count() > 50000 || method->backedge_count() > 500000;
-}
-
-double AdvancedThresholdPolicy::weight(Method* method) {
-  return (double)(method->rate() + 1) *
-    (method->invocation_count() + 1) * (method->backedge_count() + 1);
-}
-
-// Apply heuristics and return true if x should be compiled before y
-bool AdvancedThresholdPolicy::compare_methods(Method* x, Method* y) {
-  if (x->highest_comp_level() > y->highest_comp_level()) {
-    // recompilation after deopt
-    return true;
-  } else
-    if (x->highest_comp_level() == y->highest_comp_level()) {
-      if (weight(x) > weight(y)) {
-        return true;
-      }
-    }
-  return false;
-}
-
-// Is method profiled enough?
-bool AdvancedThresholdPolicy::is_method_profiled(Method* method) {
-  MethodData* mdo = method->method_data();
-  if (mdo != NULL) {
-    int i = mdo->invocation_count_delta();
-    int b = mdo->backedge_count_delta();
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
-  }
-  return false;
-}
-
-// Called with the queue locked and with at least one element
-CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) {
-  CompileTask *max_blocking_task = NULL;
-  CompileTask *max_task = NULL;
-  Method* max_method = NULL;
-  jlong t = os::javaTimeMillis();
-  // Iterate through the queue and find a method with a maximum rate.
-  for (CompileTask* task = compile_queue->first(); task != NULL;) {
-    CompileTask* next_task = task->next();
-    Method* method = task->method();
-    update_rate(t, method);
-    if (max_task == NULL) {
-      max_task = task;
-      max_method = method;
-    } else {
-      // If a method has been stale for some time, remove it from the queue.
-      // Blocking tasks and tasks submitted from whitebox API don't become stale
-      if (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
-        if (PrintTieredEvents) {
-          print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
-        }
-        compile_queue->remove_and_mark_stale(task);
-        method->clear_queued_for_compilation();
-        task = next_task;
-        continue;
-      }
-
-      // Select a method with a higher rate
-      if (compare_methods(method, max_method)) {
-        max_task = task;
-        max_method = method;
-      }
-    }
-
-    if (task->is_blocking()) {
-      if (max_blocking_task == NULL || compare_methods(method, max_blocking_task->method())) {
-        max_blocking_task = task;
-      }
-    }
-
-    task = next_task;
-  }
-
-  if (max_blocking_task != NULL) {
-    // In blocking compilation mode, the CompileBroker will make
-    // compilations submitted by a JVMCI compiler thread non-blocking. These
-    // compilations should be scheduled after all blocking compilations
-    // to service non-compiler related compilations sooner and reduce the
-    // chance of such compilations timing out.
-    max_task = max_blocking_task;
-    max_method = max_task->method();
-  }
-
-  if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile
-      && is_method_profiled(max_method)) {
-    max_task->set_comp_level(CompLevel_limited_profile);
-    if (PrintTieredEvents) {
-      print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
-    }
-  }
-
-  return max_task;
-}
-
-double AdvancedThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
-  double queue_size = CompileBroker::queue_size(level);
-  int comp_count = compiler_count(level);
-  double k = queue_size / (feedback_k * comp_count) + 1;
-
-  // Increase C1 compile threshold when the code cache is filled more
-  // than specified by IncreaseFirstTierCompileThresholdAt percentage.
-  // The main intention is to keep enough free space for C2 compiled code
-  // to achieve peak performance if the code cache is under stress.
-  if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization))  {
-    double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
-    if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
-      k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
-    }
-  }
-  return k;
-}
-
-// Call and loop predicates determine whether a transition to a higher
-// compilation level should be performed (pointers to predicate functions
-// are passed to common()).
-// Tier?LoadFeedback is basically a coefficient that determines of
-// how many methods per compiler thread can be in the queue before
-// the threshold values double.
-bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
-  switch(cur_level) {
-  case CompLevel_aot: {
-    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return loop_predicate_helper<CompLevel_aot>(i, b, k, method);
-  }
-  case CompLevel_none:
-  case CompLevel_limited_profile: {
-    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return loop_predicate_helper<CompLevel_none>(i, b, k, method);
-  }
-  case CompLevel_full_profile: {
-    double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
-  }
-  default:
-    return true;
-  }
-}
-
-bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
-  switch(cur_level) {
-  case CompLevel_aot: {
-    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return call_predicate_helper<CompLevel_aot>(i, b, k, method);
-  }
-  case CompLevel_none:
-  case CompLevel_limited_profile: {
-    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
-    return call_predicate_helper<CompLevel_none>(i, b, k, method);
-  }
-  case CompLevel_full_profile: {
-    double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
-    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
-  }
-  default:
-    return true;
-  }
-}
-
-// If a method is old enough and is still in the interpreter we would want to
-// start profiling without waiting for the compiled method to arrive.
-// We also take the load on compilers into the account.
-bool AdvancedThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) {
-  if (cur_level == CompLevel_none &&
-      CompileBroker::queue_size(CompLevel_full_optimization) <=
-      Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
-    int i = method->invocation_count();
-    int b = method->backedge_count();
-    double k = Tier0ProfilingStartPercentage / 100.0;
-    return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
-  }
-  return false;
-}
-
-// Inlining control: if we're compiling a profiled method with C1 and the callee
-// is known to have OSRed in a C2 version, don't inline it.
-bool AdvancedThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) {
-  CompLevel comp_level = (CompLevel)env->comp_level();
-  if (comp_level == CompLevel_full_profile ||
-      comp_level == CompLevel_limited_profile) {
-    return callee->highest_osr_comp_level() == CompLevel_full_optimization;
-  }
-  return false;
-}
-
-// Create MDO if necessary.
-void AdvancedThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREAD) {
-  if (mh->is_native() ||
-      mh->is_abstract() ||
-      mh->is_accessor() ||
-      mh->is_constant_getter()) {
-    return;
-  }
-  if (mh->method_data() == NULL) {
-    Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
-  }
-}
-
-
-/*
- * Method states:
- *   0 - interpreter (CompLevel_none)
- *   1 - pure C1 (CompLevel_simple)
- *   2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
- *   3 - C1 with full profiling (CompLevel_full_profile)
- *   4 - C2 (CompLevel_full_optimization)
- *
- * Common state transition patterns:
- * a. 0 -> 3 -> 4.
- *    The most common path. But note that even in this straightforward case
- *    profiling can start at level 0 and finish at level 3.
- *
- * b. 0 -> 2 -> 3 -> 4.
- *    This case occurs when the load on C2 is deemed too high. So, instead of transitioning
- *    into state 3 directly and over-profiling while a method is in the C2 queue we transition to
- *    level 2 and wait until the load on C2 decreases. This path is disabled for OSRs.
- *
- * c. 0 -> (3->2) -> 4.
- *    In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
- *    to enable the profiling to fully occur at level 0. In this case we change the compilation level
- *    of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
- *    without full profiling while c2 is compiling.
- *
- * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
- *    After a method was once compiled with C1 it can be identified as trivial and be compiled to
- *    level 1. These transition can also occur if a method can't be compiled with C2 but can with C1.
- *
- * e. 0 -> 4.
- *    This can happen if a method fails C1 compilation (it will still be profiled in the interpreter)
- *    or because of a deopt that didn't require reprofiling (compilation won't happen in this case because
- *    the compiled version already exists).
- *
- * Note that since state 0 can be reached from any other state via deoptimization different loops
- * are possible.
- *
- */
-
-// Common transition function. Given a predicate determines if a method should transition to another level.
-CompLevel AdvancedThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) {
-  CompLevel next_level = cur_level;
-  int i = method->invocation_count();
-  int b = method->backedge_count();
-
-  if (is_trivial(method)) {
-    next_level = CompLevel_simple;
-  } else {
-    switch(cur_level) {
-      default: break;
-      case CompLevel_aot: {
-      // If we were at full profile level, would we switch to full opt?
-      if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
-        next_level = CompLevel_full_optimization;
-      } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
-                               Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
-                               (this->*p)(i, b, cur_level, method))) {
-        next_level = CompLevel_full_profile;
-      }
-    }
-    break;
-    case CompLevel_none:
-      // If we were at full profile level, would we switch to full opt?
-      if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
-        next_level = CompLevel_full_optimization;
-      } else if ((this->*p)(i, b, cur_level, method)) {
-#if INCLUDE_JVMCI
-        if (EnableJVMCI && UseJVMCICompiler) {
-          // Since JVMCI takes a while to warm up, its queue inevitably backs up during
-          // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
-          // compilation method and all potential inlinees have mature profiles (which
-          // includes type profiling). If it sees immature profiles, JVMCI's inliner
-          // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
-          // exploring/inlining too many graphs). Since a rewrite of the inliner is
-          // in progress, we simply disable the dialing back heuristic for now and will
-          // revisit this decision once the new inliner is completed.
-          next_level = CompLevel_full_profile;
-        } else
-#endif
-        {
-          // C1-generated fully profiled code is about 30% slower than the limited profile
-          // code that has only invocation and backedge counters. The observation is that
-          // if C2 queue is large enough we can spend too much time in the fully profiled code
-          // while waiting for C2 to pick the method from the queue. To alleviate this problem
-          // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
-          // we choose to compile a limited profiled version and then recompile with full profiling
-          // when the load on C2 goes down.
-          if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
-              Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
-            next_level = CompLevel_limited_profile;
-          } else {
-            next_level = CompLevel_full_profile;
-          }
-        }
-      }
-      break;
-    case CompLevel_limited_profile:
-      if (is_method_profiled(method)) {
-        // Special case: we got here because this method was fully profiled in the interpreter.
-        next_level = CompLevel_full_optimization;
-      } else {
-        MethodData* mdo = method->method_data();
-        if (mdo != NULL) {
-          if (mdo->would_profile()) {
-            if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
-                                     Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
-                                     (this->*p)(i, b, cur_level, method))) {
-              next_level = CompLevel_full_profile;
-            }
-          } else {
-            next_level = CompLevel_full_optimization;
-          }
-        } else {
-          // If there is no MDO we need to profile
-          if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
-                                   Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
-                                   (this->*p)(i, b, cur_level, method))) {
-            next_level = CompLevel_full_profile;
-          }
-        }
-      }
-      break;
-    case CompLevel_full_profile:
-      {
-        MethodData* mdo = method->method_data();
-        if (mdo != NULL) {
-          if (mdo->would_profile()) {
-            int mdo_i = mdo->invocation_count_delta();
-            int mdo_b = mdo->backedge_count_delta();
-            if ((this->*p)(mdo_i, mdo_b, cur_level, method)) {
-              next_level = CompLevel_full_optimization;
-            }
-          } else {
-            next_level = CompLevel_full_optimization;
-          }
-        }
-      }
-      break;
-    }
-  }
-  return MIN2(next_level, (CompLevel)TieredStopAtLevel);
-}
-
-// Determine if a method should be compiled with a normal entry point at a different level.
-CompLevel AdvancedThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
-  CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
-                             common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true));
-  CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level);
-
-  // If OSR method level is greater than the regular method level, the levels should be
-  // equalized by raising the regular method level in order to avoid OSRs during each
-  // invocation of the method.
-  if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) {
-    MethodData* mdo = method->method_data();
-    guarantee(mdo != NULL, "MDO should not be NULL");
-    if (mdo->invocation_count() >= 1) {
-      next_level = CompLevel_full_optimization;
-    }
-  } else {
-    next_level = MAX2(osr_level, next_level);
-  }
-#if INCLUDE_JVMCI
-  if (UseJVMCICompiler) {
-    next_level = JVMCIRuntime::adjust_comp_level(method, false, next_level, thread);
-  }
-#endif
-  return next_level;
-}
-
-// Determine if we should do an OSR compilation of a given method.
-CompLevel AdvancedThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread * thread) {
-  CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true);
-  if (cur_level == CompLevel_none) {
-    // If there is a live OSR method that means that we deopted to the interpreter
-    // for the transition.
-    CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level);
-    if (osr_level > CompLevel_none) {
-      return osr_level;
-    }
-  }
-#if INCLUDE_JVMCI
-  if (UseJVMCICompiler) {
-    next_level = JVMCIRuntime::adjust_comp_level(method, true, next_level, thread);
-  }
-#endif
-  return next_level;
-}
-
-// Update the rate and submit compile
-void AdvancedThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
-  int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
-  update_rate(os::javaTimeMillis(), mh());
-  CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
-}
-
-bool AdvancedThresholdPolicy::maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
-  if (UseAOT && !delay_compilation_during_startup()) {
-    if (cur_level == CompLevel_full_profile || cur_level == CompLevel_none) {
-      // If the current level is full profile or interpreter and we're switching to any other level,
-      // activate the AOT code back first so that we won't waste time overprofiling.
-      compile(mh, InvocationEntryBci, CompLevel_aot, thread);
-      // Fall through for JIT compilation.
-    }
-    if (next_level == CompLevel_limited_profile && cur_level != CompLevel_aot && mh->has_aot_code()) {
-      // If the next level is limited profile, use the aot code (if there is any),
-      // since it's essentially the same thing.
-      compile(mh, InvocationEntryBci, CompLevel_aot, thread);
-      // Not need to JIT, we're done.
-      return true;
-    }
-  }
-  return false;
-}
-
-
-// Handle the invocation event.
-void AdvancedThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
-                                                      CompLevel level, CompiledMethod* nm, JavaThread* thread) {
-  if (should_create_mdo(mh(), level)) {
-    create_mdo(mh, thread);
-  }
-  CompLevel next_level = call_event(mh(), level, thread);
-  if (next_level != level) {
-    if (maybe_switch_to_aot(mh, level, next_level, thread)) {
-      // No JITting necessary
-      return;
-    }
-    if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
-      compile(mh, InvocationEntryBci, next_level, thread);
-    }
-  }
-}
-
-// Handle the back branch event. Notice that we can compile the method
-// with a regular entry from here.
-void AdvancedThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
-                                                       int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
-  if (should_create_mdo(mh(), level)) {
-    create_mdo(mh, thread);
-  }
-  // Check if MDO should be created for the inlined method
-  if (should_create_mdo(imh(), level)) {
-    create_mdo(imh, thread);
-  }
-
-  if (is_compilation_enabled()) {
-    CompLevel next_osr_level = loop_event(imh(), level, thread);
-    CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
-    // At the very least compile the OSR version
-    if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
-      compile(imh, bci, next_osr_level, thread);
-    }
-
-    // Use loop event as an opportunity to also check if there's been
-    // enough calls.
-    CompLevel cur_level, next_level;
-    if (mh() != imh()) { // If there is an enclosing method
-      if (level == CompLevel_aot) {
-        // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
-        if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
-          compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread);
-        }
-      } else {
-        // Current loop event level is not AOT
-        guarantee(nm != NULL, "Should have nmethod here");
-        cur_level = comp_level(mh());
-        next_level = call_event(mh(), cur_level, thread);
-
-        if (max_osr_level == CompLevel_full_optimization) {
-          // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
-          bool make_not_entrant = false;
-          if (nm->is_osr_method()) {
-            // This is an osr method, just make it not entrant and recompile later if needed
-            make_not_entrant = true;
-          } else {
-            if (next_level != CompLevel_full_optimization) {
-              // next_level is not full opt, so we need to recompile the
-              // enclosing method without the inlinee
-              cur_level = CompLevel_none;
-              make_not_entrant = true;
-            }
-          }
-          if (make_not_entrant) {
-            if (PrintTieredEvents) {
-              int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
-              print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
-            }
-            nm->make_not_entrant();
-          }
-        }
-        // Fix up next_level if necessary to avoid deopts
-        if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
-          next_level = CompLevel_full_profile;
-        }
-        if (cur_level != next_level) {
-          if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
-            compile(mh, InvocationEntryBci, next_level, thread);
-          }
-        }
-      }
-    } else {
-      cur_level = comp_level(mh());
-      next_level = call_event(mh(), cur_level, thread);
-      if (next_level != cur_level) {
-        if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
-          compile(mh, InvocationEntryBci, next_level, thread);
-        }
-      }
-    }
-  }
-}
-
-#endif // TIERED
--- a/src/hotspot/share/runtime/advancedThresholdPolicy.hpp	Tue May 15 18:03:31 2018 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
-#define SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
-
-#include "runtime/simpleThresholdPolicy.hpp"
-
-#ifdef TIERED
-class CompileTask;
-class CompileQueue;
-
-/*
- *  The system supports 5 execution levels:
- *  * level 0 - interpreter
- *  * level 1 - C1 with full optimization (no profiling)
- *  * level 2 - C1 with invocation and backedge counters
- *  * level 3 - C1 with full profiling (level 2 + MDO)
- *  * level 4 - C2
- *
- * Levels 0, 2 and 3 periodically notify the runtime about the current value of the counters
- * (invocation counters and backedge counters). The frequency of these notifications is
- * different at each level. These notifications are used by the policy to decide what transition
- * to make.
- *
- * Execution starts at level 0 (interpreter), then the policy can decide either to compile the
- * method at level 3 or level 2. The decision is based on the following factors:
- *    1. The length of the C2 queue determines the next level. The observation is that level 2
- * is generally faster than level 3 by about 30%, therefore we would want to minimize the time
- * a method spends at level 3. We should only spend the time at level 3 that is necessary to get
- * adequate profiling. So, if the C2 queue is long enough it is more beneficial to go first to
- * level 2, because if we transitioned to level 3 we would be stuck there until our C2 compile
- * request makes its way through the long queue. When the load on C2 recedes we are going to
- * recompile at level 3 and start gathering profiling information.
- *    2. The length of C1 queue is used to dynamically adjust the thresholds, so as to introduce
- * additional filtering if the compiler is overloaded. The rationale is that by the time a
- * method gets compiled it can become unused, so it doesn't make sense to put too much onto the
- * queue.
- *
- * After profiling is completed at level 3 the transition is made to level 4. Again, the length
- * of the C2 queue is used as a feedback to adjust the thresholds.
- *
- * After the first C1 compile some basic information is determined about the code like the number
- * of the blocks and the number of the loops. Based on that it can be decided that a method
- * is trivial and compiling it with C1 will yield the same code. In this case the method is
- * compiled at level 1 instead of 4.
- *
- * We also support profiling at level 0. If C1 is slow enough to produce the level 3 version of
- * the code and the C2 queue is sufficiently small we can decide to start profiling in the
- * interpreter (and continue profiling in the compiled code once the level 3 version arrives).
- * If the profiling at level 0 is fully completed before level 3 version is produced, a level 2
- * version is compiled instead in order to run faster waiting for a level 4 version.
- *
- * Compile queues are implemented as priority queues - for each method in the queue we compute
- * the event rate (the number of invocation and backedge counter increments per unit of time).
- * When getting an element off the queue we pick the one with the largest rate. Maintaining the
- * rate also allows us to remove stale methods (the ones that got on the queue but stopped
- * being used shortly after that).
-*/
-
-/* Command line options:
- * - Tier?InvokeNotifyFreqLog and Tier?BackedgeNotifyFreqLog control the frequency of method
- *   invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
- *   makes a call into the runtime.
- *
- * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
- *   compilation thresholds.
- *   Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
- *   Other thresholds work as follows:
- *
- *   Transition from interpreter (level 0) to C1 with full profiling (level 3) happens when
- *   the following predicate is true (X is the level):
- *
- *   i > TierXInvocationThreshold * s || (i > TierXMinInvocationThreshold * s  && i + b > TierXCompileThreshold * s),
- *
- *   where $i$ is the number of method invocations, $b$ number of backedges and $s$ is the scaling
- *   coefficient that will be discussed further.
- *   The intuition is to equalize the time that is spend profiling each method.
- *   The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
- *   noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
- *   from Method* and for 3->4 transition they come from MDO (since profiled invocations are
- *   counted separately). Finally, if a method does not contain anything worth profiling, a transition
- *   from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
- *   what is specified by Tier4InvocationThreshold).
- *
- *   OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
- *
- * - Tier?LoadFeedback options are used to automatically scale the predicates described above depending
- *   on the compiler load. The scaling coefficients are computed as follows:
- *
- *   s = queue_size_X / (TierXLoadFeedback * compiler_count_X) + 1,
- *
- *   where queue_size_X is the current size of the compiler queue of level X, and compiler_count_X
- *   is the number of level X compiler threads.
- *
- *   Basically these parameters describe how many methods should be in the compile queue
- *   per compiler thread before the scaling coefficient increases by one.
- *
- *   This feedback provides the mechanism to automatically control the flow of compilation requests
- *   depending on the machine speed, mutator load and other external factors.
- *
- * - Tier3DelayOn and Tier3DelayOff parameters control another important feedback loop.
- *   Consider the following observation: a method compiled with full profiling (level 3)
- *   is about 30% slower than a method at level 2 (just invocation and backedge counters, no MDO).
- *   Normally, the following transitions will occur: 0->3->4. The problem arises when the C2 queue
- *   gets congested and the 3->4 transition is delayed. While the method is the C2 queue it continues
- *   executing at level 3 for much longer time than is required by the predicate and at suboptimal speed.
- *   The idea is to dynamically change the behavior of the system in such a way that if a substantial
- *   load on C2 is detected we would first do the 0->2 transition allowing a method to run faster.
- *   And then when the load decreases to allow 2->3 transitions.
- *
- *   Tier3Delay* parameters control this switching mechanism.
- *   Tier3DelayOn is the number of methods in the C2 queue per compiler thread after which the policy
- *   no longer does 0->3 transitions but does 0->2 transitions instead.
- *   Tier3DelayOff switches the original behavior back when the number of methods in the C2 queue
- *   per compiler thread falls below the specified amount.
- *   The hysteresis is necessary to avoid jitter.
- *
- * - TieredCompileTaskTimeout is the amount of time an idle method can spend in the compile queue.
- *   Basically, since we use the event rate d(i + b)/dt as a value of priority when selecting a method to
- *   compile from the compile queue, we also can detect stale methods for which the rate has been
- *   0 for some time in the same iteration. Stale methods can appear in the queue when an application
- *   abruptly changes its behavior.
- *
- * - TieredStopAtLevel, is used mostly for testing. It allows to bypass the policy logic and stick
- *   to a given level. For example it's useful to set TieredStopAtLevel = 1 in order to compile everything
- *   with pure c1.
- *
- * - Tier0ProfilingStartPercentage allows the interpreter to start profiling when the inequalities in the
- *   0->3 predicate are already exceeded by the given percentage but the level 3 version of the
- *   method is still not ready. We can even go directly from level 0 to 4 if c1 doesn't produce a compiled
- *   version in time. This reduces the overall transition to level 4 and decreases the startup time.
- *   Note that this behavior is also guarded by the Tier3Delay mechanism: when the c2 queue is too long
- *   these is not reason to start profiling prematurely.
- *
- * - TieredRateUpdateMinTime and TieredRateUpdateMaxTime are parameters of the rate computation.
- *   Basically, the rate is not computed more frequently than TieredRateUpdateMinTime and is considered
- *   to be zero if no events occurred in TieredRateUpdateMaxTime.
- */
-
-
-class AdvancedThresholdPolicy : public SimpleThresholdPolicy {
-  jlong _start_time;
-
-  // Call and loop predicates determine whether a transition to a higher compilation
-  // level should be performed (pointers to predicate functions are passed to common().
-  // Predicates also take compiler load into account.
-  typedef bool (AdvancedThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, Method* method);
-  bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
-  bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
-  // Common transition function. Given a predicate determines if a method should transition to another level.
-  CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
-  // Transition functions.
-  // call_event determines if a method should be compiled at a different
-  // level with a regular invocation entry.
-  CompLevel call_event(Method* method, CompLevel cur_level, JavaThread * thread);
-  // loop_event checks if a method should be OSR compiled at a different
-  // level.
-  CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread * thread);
-  // Has a method been long around?
-  // We don't remove old methods from the compile queue even if they have
-  // very low activity (see select_task()).
-  inline bool is_old(Method* method);
-  // Was a given method inactive for a given number of milliseconds.
-  // If it is, we would remove it from the queue (see select_task()).
-  inline bool is_stale(jlong t, jlong timeout, Method* m);
-  // Compute the weight of the method for the compilation scheduling
-  inline double weight(Method* method);
-  // Apply heuristics and return true if x should be compiled before y
-  inline bool compare_methods(Method* x, Method* y);
-  // Compute event rate for a given method. The rate is the number of event (invocations + backedges)
-  // per millisecond.
-  inline void update_rate(jlong t, Method* m);
-  // Compute threshold scaling coefficient
-  inline double threshold_scale(CompLevel level, int feedback_k);
-  // If a method is old enough and is still in the interpreter we would want to
-  // start profiling without waiting for the compiled method to arrive. This function
-  // determines whether we should do that.
-  inline bool should_create_mdo(Method* method, CompLevel cur_level);
-  // Create MDO if necessary.
-  void create_mdo(const methodHandle& mh, JavaThread* thread);
-  // Is method profiled enough?
-  bool is_method_profiled(Method* method);
-
-  double _increase_threshold_at_ratio;
-
-  bool maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
-
-protected:
-  void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
-
-  void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
-  void set_start_time(jlong t) { _start_time = t;    }
-  jlong start_time() const     { return _start_time; }
-
-  // Submit a given method for compilation (and update the rate).
-  virtual void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
-  // event() from SimpleThresholdPolicy would call these.
-  virtual void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
-                                       CompLevel level, CompiledMethod* nm, JavaThread* thread);
-  virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
-                                        int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
-public:
-  AdvancedThresholdPolicy() : _start_time(0) { }
-  // Select task is called by CompileBroker. We should return a task or NULL.
-  virtual CompileTask* select_task(CompileQueue* compile_queue);
-  virtual void initialize();
-  virtual bool should_not_inline(ciEnv* env, ciMethod* callee);
-
-};
-
-#endif // TIERED
-
-#endif // SHARE_VM_RUNTIME_ADVANCEDTHRESHOLDPOLICY_HPP
--- a/src/hotspot/share/runtime/arguments.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/arguments.cpp	Tue May 15 10:13:52 2018 -0700
@@ -544,6 +544,7 @@
   { "SharedMiscCodeSize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
   { "UseUTCFileTimestamp",           JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "UseAppCDS",                     JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+  { "InlineNotify",                  JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -1603,9 +1604,9 @@
 }
 
 void Arguments::set_tiered_flags() {
-  // With tiered, set default policy to AdvancedThresholdPolicy, which is 3.
+  // With tiered, set default policy to SimpleThresholdPolicy, which is 2.
   if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) {
-    FLAG_SET_DEFAULT(CompilationPolicyChoice, 3);
+    FLAG_SET_DEFAULT(CompilationPolicyChoice, 2);
   }
   if (CompilationPolicyChoice < 2) {
     vm_exit_during_initialization(
--- a/src/hotspot/share/runtime/compilationPolicy.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/compilationPolicy.cpp	Tue May 15 10:13:52 2018 -0700
@@ -33,7 +33,6 @@
 #include "oops/method.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/nativeLookup.hpp"
-#include "runtime/advancedThresholdPolicy.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/frame.hpp"
 #include "runtime/handles.inline.hpp"
@@ -74,15 +73,8 @@
     Unimplemented();
 #endif
     break;
-  case 3:
-#ifdef TIERED
-    CompilationPolicy::set_policy(new AdvancedThresholdPolicy());
-#else
-    Unimplemented();
-#endif
-    break;
   default:
-    fatal("CompilationPolicyChoice must be in the range: [0-3]");
+    fatal("CompilationPolicyChoice must be in the range: [0-2]");
   }
   CompilationPolicy::policy()->initialize();
 }
--- a/src/hotspot/share/runtime/globals.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/globals.hpp	Tue May 15 10:13:52 2018 -0700
@@ -847,8 +847,6 @@
                                                                             \
   experimental(intx, SyncVerbose, 0, "(Unstable)")                          \
                                                                             \
-  diagnostic(bool, InlineNotify, true, "intrinsify subset of notify")       \
-                                                                            \
   experimental(intx, hashCode, 5,                                           \
                "(Unstable) select hashCode generation algorithm")           \
                                                                             \
@@ -1158,8 +1156,8 @@
           "UseDynamicNumberOfCompilerThreads")                              \
                                                                             \
   product(intx, CompilationPolicyChoice, 0,                                 \
-          "which compilation policy (0-3)")                                 \
-          range(0, 3)                                                       \
+          "which compilation policy (0-2)")                                 \
+          range(0, 2)                                                       \
                                                                             \
   develop(bool, UseStackBanging, true,                                      \
           "use stack banging for stack overflow checks (required for "      \
--- a/src/hotspot/share/runtime/init.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/init.cpp	Tue May 15 10:13:52 2018 -0700
@@ -62,9 +62,6 @@
 void gc_barrier_stubs_init();
 void interpreter_init();       // before any methods loaded
 void invocationCounter_init(); // before any methods loaded
-#if INCLUDE_SERIALGC
-void marksweep_init();
-#endif
 void accessFlags_init();
 void templateTable_init();
 void InterfaceSupport_init();
@@ -119,7 +116,6 @@
   gc_barrier_stubs_init();   // depends on universe_init, must be before interpreter_init
   interpreter_init();        // before any methods loaded
   invocationCounter_init();  // before any methods loaded
-  SERIALGC_ONLY(marksweep_init());
   accessFlags_init();
   templateTable_init();
   InterfaceSupport_init();
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Tue May 15 10:13:52 2018 -0700
@@ -98,13 +98,14 @@
 // The knob* variables are effectively final.  Once set they should
 // never be modified hence.  Consider using __read_mostly with GCC.
 
-int ObjectMonitor::Knob_ExitRelease = 0;
-int ObjectMonitor::Knob_Verbose     = 0;
-int ObjectMonitor::Knob_VerifyInUse = 0;
-int ObjectMonitor::Knob_VerifyMatch = 0;
-int ObjectMonitor::Knob_SpinLimit   = 5000;    // derived by an external tool -
+int ObjectMonitor::Knob_ExitRelease  = 0;
+int ObjectMonitor::Knob_InlineNotify = 1;
+int ObjectMonitor::Knob_Verbose      = 0;
+int ObjectMonitor::Knob_VerifyInUse  = 0;
+int ObjectMonitor::Knob_VerifyMatch  = 0;
+int ObjectMonitor::Knob_SpinLimit    = 5000;    // derived by an external tool -
+
 static int Knob_ReportSettings      = 0;
-
 static int Knob_SpinBase            = 0;       // Floor AKA SpinMin
 static int Knob_SpinBackOff         = 0;       // spin-loop backoff
 static int Knob_CASPenalty          = -1;      // Penalty for failed CAS
@@ -2319,6 +2320,7 @@
   #define SETKNOB(x) { Knob_##x = kvGetInt(knobs, #x, Knob_##x); }
   SETKNOB(ReportSettings);
   SETKNOB(ExitRelease);
+  SETKNOB(InlineNotify);
   SETKNOB(Verbose);
   SETKNOB(VerifyInUse);
   SETKNOB(VerifyMatch);
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Tue May 15 10:13:52 2018 -0700
@@ -199,6 +199,7 @@
   static PerfLongVariable * _sync_MonExtant;
 
   static int Knob_ExitRelease;
+  static int Knob_InlineNotify;
   static int Knob_Verbose;
   static int Knob_VerifyInUse;
   static int Knob_VerifyMatch;
--- a/src/hotspot/share/runtime/perfData.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/perfData.cpp	Tue May 15 10:13:52 2018 -0700
@@ -173,7 +173,7 @@
                                 " units = %d, dsize = " SIZE_FORMAT ", vlen = " SIZE_FORMAT ","
                                 " pad_length = " SIZE_FORMAT ", size = " SIZE_FORMAT ", on_c_heap = %s,"
                                 " address = " INTPTR_FORMAT ","
-                                " data address = " INTPTR_FORMAT "\n",
+                                " data address = " INTPTR_FORMAT,
                                 cname, dtype, variability(),
                                 units(), dsize, vlen,
                                 pad_length, size, is_on_c_heap() ? "TRUE":"FALSE",
--- a/src/hotspot/share/runtime/perfMemory.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/perfMemory.cpp	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -98,7 +98,7 @@
 
   log_debug(perf, memops)("PerfDataMemorySize = " SIZE_FORMAT ","
                           " os::vm_allocation_granularity = %d,"
-                          " adjusted size = " SIZE_FORMAT "\n",
+                          " adjusted size = " SIZE_FORMAT,
                           PerfDataMemorySize,
                           os::vm_allocation_granularity(),
                           capacity);
@@ -127,7 +127,7 @@
     // the PerfMemory region was created as expected.
 
     log_debug(perf, memops)("PerfMemory created: address = " INTPTR_FORMAT ","
-                            " size = " SIZE_FORMAT "\n",
+                            " size = " SIZE_FORMAT,
                             p2i(_start),
                             _capacity);
 
--- a/src/hotspot/share/runtime/simpleThresholdPolicy.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/simpleThresholdPolicy.cpp	Tue May 15 10:13:52 2018 -0700
@@ -140,20 +140,33 @@
 }
 
 void SimpleThresholdPolicy::initialize() {
-  if (FLAG_IS_DEFAULT(CICompilerCount)) {
-    FLAG_SET_DEFAULT(CICompilerCount, 3);
-  }
   int count = CICompilerCount;
 #ifdef _LP64
-  // On 64-bit systems, scale the number of compiler threads with
-  // the number of cores available on the system. Scaling is not
-  // performed on 32-bit systems because it can lead to exhaustion
-  // of the virtual memory address space available to the JVM.
+  // Turn on ergonomic compiler count selection
+  if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) {
+    FLAG_SET_DEFAULT(CICompilerCountPerCPU, true);
+  }
   if (CICompilerCountPerCPU) {
-    count = MAX2(log2_intptr(os::active_processor_count()) * 3 / 2, 2);
+    // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
+    int log_cpu = log2_intptr(os::active_processor_count());
+    int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
+    count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
+    FLAG_SET_ERGO(intx, CICompilerCount, count);
+  }
+#else
+  // On 32-bit systems, the number of compiler threads is limited to 3.
+  // On these systems, the virtual address space available to the JVM
+  // is usually limited to 2-4 GB (the exact value depends on the platform).
+  // As the compilers (especially C2) can consume a large amount of
+  // memory, scaling the number of compiler threads with the number of
+  // available cores can result in the exhaustion of the address space
+  /// available to the VM and thus cause the VM to crash.
+  if (FLAG_IS_DEFAULT(CICompilerCount)) {
+    count = 3;
     FLAG_SET_ERGO(intx, CICompilerCount, count);
   }
 #endif
+
   if (TieredStopAtLevel < CompLevel_full_optimization) {
     // No C2 compiler thread required
     set_c1_count(count);
@@ -162,6 +175,22 @@
     set_c2_count(MAX2(count - c1_count(), 1));
   }
   assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
+
+  // Some inlining tuning
+#ifdef X86
+  if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+    FLAG_SET_DEFAULT(InlineSmallCode, 2000);
+  }
+#endif
+
+#if defined SPARC || defined AARCH64
+  if (FLAG_IS_DEFAULT(InlineSmallCode)) {
+    FLAG_SET_DEFAULT(InlineSmallCode, 2500);
+  }
+#endif
+
+  set_increase_threshold_at_ratio();
+  set_start_time(os::javaTimeMillis());
 }
 
 void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
@@ -186,7 +215,66 @@
 
 // Called with the queue locked and with at least one element
 CompileTask* SimpleThresholdPolicy::select_task(CompileQueue* compile_queue) {
-  return select_task_helper(compile_queue);
+  CompileTask *max_blocking_task = NULL;
+  CompileTask *max_task = NULL;
+  Method* max_method = NULL;
+  jlong t = os::javaTimeMillis();
+  // Iterate through the queue and find a method with a maximum rate.
+  for (CompileTask* task = compile_queue->first(); task != NULL;) {
+    CompileTask* next_task = task->next();
+    Method* method = task->method();
+    update_rate(t, method);
+    if (max_task == NULL) {
+      max_task = task;
+      max_method = method;
+    } else {
+      // If a method has been stale for some time, remove it from the queue.
+      // Blocking tasks and tasks submitted from whitebox API don't become stale
+      if (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
+        if (PrintTieredEvents) {
+          print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
+        }
+        compile_queue->remove_and_mark_stale(task);
+        method->clear_queued_for_compilation();
+        task = next_task;
+        continue;
+      }
+
+      // Select a method with a higher rate
+      if (compare_methods(method, max_method)) {
+        max_task = task;
+        max_method = method;
+      }
+    }
+
+    if (task->is_blocking()) {
+      if (max_blocking_task == NULL || compare_methods(method, max_blocking_task->method())) {
+        max_blocking_task = task;
+      }
+    }
+
+    task = next_task;
+  }
+
+  if (max_blocking_task != NULL) {
+    // In blocking compilation mode, the CompileBroker will make
+    // compilations submitted by a JVMCI compiler thread non-blocking. These
+    // compilations should be scheduled after all blocking compilations
+    // to service non-compiler related compilations sooner and reduce the
+    // chance of such compilations timing out.
+    max_task = max_blocking_task;
+    max_method = max_task->method();
+  }
+
+  if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile
+      && is_method_profiled(max_method)) {
+    max_task->set_comp_level(CompLevel_limited_profile);
+    if (PrintTieredEvents) {
+      print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
+    }
+  }
+
+  return max_task;
 }
 
 void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
@@ -284,26 +372,150 @@
   }
 }
 
-// Tell the broker to compile the method
+// Update the rate and submit compile
 void SimpleThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
   int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
+  update_rate(os::javaTimeMillis(), mh());
   CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
 }
 
+// Print an event.
+void SimpleThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh,
+                                             int bci, CompLevel level) {
+  tty->print(" rate=");
+  if (mh->prev_time() == 0) tty->print("n/a");
+  else tty->print("%f", mh->rate());
+
+  tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
+                               threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
+
+}
+
+// update_rate() is called from select_task() while holding a compile queue lock.
+void SimpleThresholdPolicy::update_rate(jlong t, Method* m) {
+  // Skip update if counters are absent.
+  // Can't allocate them since we are holding compile queue lock.
+  if (m->method_counters() == NULL)  return;
+
+  if (is_old(m)) {
+    // We don't remove old methods from the queue,
+    // so we can just zero the rate.
+    m->set_rate(0);
+    return;
+  }
+
+  // We don't update the rate if we've just came out of a safepoint.
+  // delta_s is the time since last safepoint in milliseconds.
+  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+  jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement
+  // How many events were there since the last time?
+  int event_count = m->invocation_count() + m->backedge_count();
+  int delta_e = event_count - m->prev_event_count();
+
+  // We should be running for at least 1ms.
+  if (delta_s >= TieredRateUpdateMinTime) {
+    // And we must've taken the previous point at least 1ms before.
+    if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) {
+      m->set_prev_time(t);
+      m->set_prev_event_count(event_count);
+      m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond
+    } else {
+      if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) {
+        // If nothing happened for 25ms, zero the rate. Don't modify prev values.
+        m->set_rate(0);
+      }
+    }
+  }
+}
+
+// Check if this method has been stale from a given number of milliseconds.
+// See select_task().
+bool SimpleThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) {
+  jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint();
+  jlong delta_t = t - m->prev_time();
+  if (delta_t > timeout && delta_s > timeout) {
+    int event_count = m->invocation_count() + m->backedge_count();
+    int delta_e = event_count - m->prev_event_count();
+    // Return true if there were no events.
+    return delta_e == 0;
+  }
+  return false;
+}
+
+// We don't remove old methods from the compile queue even if they have
+// very low activity. See select_task().
+bool SimpleThresholdPolicy::is_old(Method* method) {
+  return method->invocation_count() > 50000 || method->backedge_count() > 500000;
+}
+
+double SimpleThresholdPolicy::weight(Method* method) {
+  return (double)(method->rate() + 1) *
+    (method->invocation_count() + 1) * (method->backedge_count() + 1);
+}
+
+// Apply heuristics and return true if x should be compiled before y
+bool SimpleThresholdPolicy::compare_methods(Method* x, Method* y) {
+  if (x->highest_comp_level() > y->highest_comp_level()) {
+    // recompilation after deopt
+    return true;
+  } else
+    if (x->highest_comp_level() == y->highest_comp_level()) {
+      if (weight(x) > weight(y)) {
+        return true;
+      }
+    }
+  return false;
+}
+
+// Is method profiled enough?
+bool SimpleThresholdPolicy::is_method_profiled(Method* method) {
+  MethodData* mdo = method->method_data();
+  if (mdo != NULL) {
+    int i = mdo->invocation_count_delta();
+    int b = mdo->backedge_count_delta();
+    return call_predicate_helper<CompLevel_full_profile>(i, b, 1, method);
+  }
+  return false;
+}
+
+double SimpleThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) {
+  double queue_size = CompileBroker::queue_size(level);
+  int comp_count = compiler_count(level);
+  double k = queue_size / (feedback_k * comp_count) + 1;
+
+  // Increase C1 compile threshold when the code cache is filled more
+  // than specified by IncreaseFirstTierCompileThresholdAt percentage.
+  // The main intention is to keep enough free space for C2 compiled code
+  // to achieve peak performance if the code cache is under stress.
+  if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization))  {
+    double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level));
+    if (current_reverse_free_ratio > _increase_threshold_at_ratio) {
+      k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio);
+    }
+  }
+  return k;
+}
+
 // Call and loop predicates determine whether a transition to a higher
 // compilation level should be performed (pointers to predicate functions
-// are passed to common() transition function).
+// are passed to common()).
+// Tier?LoadFeedback is basically a coefficient that determines of
+// how many methods per compiler thread can be in the queue before
+// the threshold values double.
 bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_aot: {
-    return loop_predicate_helper<CompLevel_aot>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+    return loop_predicate_helper<CompLevel_aot>(i, b, k, method);
   }
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return loop_predicate_helper<CompLevel_none>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+    return loop_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
-    return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+    return loop_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
@@ -313,14 +525,17 @@
 bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) {
   switch(cur_level) {
   case CompLevel_aot: {
-    return call_predicate_helper<CompLevel_aot>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+    return call_predicate_helper<CompLevel_aot>(i, b, k, method);
   }
   case CompLevel_none:
   case CompLevel_limited_profile: {
-    return call_predicate_helper<CompLevel_none>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback);
+    return call_predicate_helper<CompLevel_none>(i, b, k, method);
   }
   case CompLevel_full_profile: {
-    return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0, method);
+    double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback);
+    return call_predicate_helper<CompLevel_full_profile>(i, b, k, method);
   }
   default:
     return true;
@@ -341,31 +556,167 @@
   return false;
 }
 
+// If a method is old enough and is still in the interpreter we would want to
+// start profiling without waiting for the compiled method to arrive.
+// We also take the load on compilers into the account.
+bool SimpleThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) {
+  if (cur_level == CompLevel_none &&
+      CompileBroker::queue_size(CompLevel_full_optimization) <=
+      Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+    int i = method->invocation_count();
+    int b = method->backedge_count();
+    double k = Tier0ProfilingStartPercentage / 100.0;
+    return call_predicate_helper<CompLevel_none>(i, b, k, method) || loop_predicate_helper<CompLevel_none>(i, b, k, method);
+  }
+  return false;
+}
+
+// Inlining control: if we're compiling a profiled method with C1 and the callee
+// is known to have OSRed in a C2 version, don't inline it.
+bool SimpleThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) {
+  CompLevel comp_level = (CompLevel)env->comp_level();
+  if (comp_level == CompLevel_full_profile ||
+      comp_level == CompLevel_limited_profile) {
+    return callee->highest_osr_comp_level() == CompLevel_full_optimization;
+  }
+  return false;
+}
+
+// Create MDO if necessary.
+void SimpleThresholdPolicy::create_mdo(const methodHandle& mh, JavaThread* THREAD) {
+  if (mh->is_native() ||
+      mh->is_abstract() ||
+      mh->is_accessor() ||
+      mh->is_constant_getter()) {
+    return;
+  }
+  if (mh->method_data() == NULL) {
+    Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
+  }
+}
+
+
+/*
+ * Method states:
+ *   0 - interpreter (CompLevel_none)
+ *   1 - pure C1 (CompLevel_simple)
+ *   2 - C1 with invocation and backedge counting (CompLevel_limited_profile)
+ *   3 - C1 with full profiling (CompLevel_full_profile)
+ *   4 - C2 (CompLevel_full_optimization)
+ *
+ * Common state transition patterns:
+ * a. 0 -> 3 -> 4.
+ *    The most common path. But note that even in this straightforward case
+ *    profiling can start at level 0 and finish at level 3.
+ *
+ * b. 0 -> 2 -> 3 -> 4.
+ *    This case occurs when the load on C2 is deemed too high. So, instead of transitioning
+ *    into state 3 directly and over-profiling while a method is in the C2 queue we transition to
+ *    level 2 and wait until the load on C2 decreases. This path is disabled for OSRs.
+ *
+ * c. 0 -> (3->2) -> 4.
+ *    In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough
+ *    to enable the profiling to fully occur at level 0. In this case we change the compilation level
+ *    of the method to 2 while the request is still in-queue, because it'll allow it to run much faster
+ *    without full profiling while c2 is compiling.
+ *
+ * d. 0 -> 3 -> 1 or 0 -> 2 -> 1.
+ *    After a method was once compiled with C1 it can be identified as trivial and be compiled to
+ *    level 1. These transition can also occur if a method can't be compiled with C2 but can with C1.
+ *
+ * e. 0 -> 4.
+ *    This can happen if a method fails C1 compilation (it will still be profiled in the interpreter)
+ *    or because of a deopt that didn't require reprofiling (compilation won't happen in this case because
+ *    the compiled version already exists).
+ *
+ * Note that since state 0 can be reached from any other state via deoptimization different loops
+ * are possible.
+ *
+ */
+
 // Common transition function. Given a predicate determines if a method should transition to another level.
-CompLevel SimpleThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level) {
+CompLevel SimpleThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) {
   CompLevel next_level = cur_level;
   int i = method->invocation_count();
   int b = method->backedge_count();
 
-  if (is_trivial(method) && cur_level != CompLevel_aot) {
+  if (is_trivial(method)) {
     next_level = CompLevel_simple;
   } else {
     switch(cur_level) {
-    case CompLevel_aot: {
-      if ((this->*p)(i, b, cur_level, method)) {
+      default: break;
+      case CompLevel_aot: {
+      // If we were at full profile level, would we switch to full opt?
+      if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
+        next_level = CompLevel_full_optimization;
+      } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+                               Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+                               (this->*p)(i, b, cur_level, method))) {
         next_level = CompLevel_full_profile;
       }
     }
     break;
     case CompLevel_none:
       // If we were at full profile level, would we switch to full opt?
-      if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) {
+      if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) {
         next_level = CompLevel_full_optimization;
       } else if ((this->*p)(i, b, cur_level, method)) {
-        next_level = CompLevel_full_profile;
+#if INCLUDE_JVMCI
+        if (EnableJVMCI && UseJVMCICompiler) {
+          // Since JVMCI takes a while to warm up, its queue inevitably backs up during
+          // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root
+          // compilation method and all potential inlinees have mature profiles (which
+          // includes type profiling). If it sees immature profiles, JVMCI's inliner
+          // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to
+          // exploring/inlining too many graphs). Since a rewrite of the inliner is
+          // in progress, we simply disable the dialing back heuristic for now and will
+          // revisit this decision once the new inliner is completed.
+          next_level = CompLevel_full_profile;
+        } else
+#endif
+        {
+          // C1-generated fully profiled code is about 30% slower than the limited profile
+          // code that has only invocation and backedge counters. The observation is that
+          // if C2 queue is large enough we can spend too much time in the fully profiled code
+          // while waiting for C2 to pick the method from the queue. To alleviate this problem
+          // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long
+          // we choose to compile a limited profiled version and then recompile with full profiling
+          // when the load on C2 goes down.
+          if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) >
+              Tier3DelayOn * compiler_count(CompLevel_full_optimization)) {
+            next_level = CompLevel_limited_profile;
+          } else {
+            next_level = CompLevel_full_profile;
+          }
+        }
       }
       break;
     case CompLevel_limited_profile:
+      if (is_method_profiled(method)) {
+        // Special case: we got here because this method was fully profiled in the interpreter.
+        next_level = CompLevel_full_optimization;
+      } else {
+        MethodData* mdo = method->method_data();
+        if (mdo != NULL) {
+          if (mdo->would_profile()) {
+            if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+                                     Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+                                     (this->*p)(i, b, cur_level, method))) {
+              next_level = CompLevel_full_profile;
+            }
+          } else {
+            next_level = CompLevel_full_optimization;
+          }
+        } else {
+          // If there is no MDO we need to profile
+          if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <=
+                                   Tier3DelayOff * compiler_count(CompLevel_full_optimization) &&
+                                   (this->*p)(i, b, cur_level, method))) {
+            next_level = CompLevel_full_profile;
+          }
+        }
+      }
+      break;
     case CompLevel_full_profile:
       {
         MethodData* mdo = method->method_data();
@@ -382,17 +733,15 @@
         }
       }
       break;
-    default:
-      break;
     }
   }
   return MIN2(next_level, (CompLevel)TieredStopAtLevel);
 }
 
 // Determine if a method should be compiled with a normal entry point at a different level.
-CompLevel SimpleThresholdPolicy::call_event(Method* method,  CompLevel cur_level, JavaThread* thread) {
+CompLevel SimpleThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
   CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
-                             common(&SimpleThresholdPolicy::loop_predicate, method, cur_level));
+                             common(&SimpleThresholdPolicy::loop_predicate, method, cur_level, true));
   CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level);
 
   // If OSR method level is greater than the regular method level, the levels should be
@@ -417,7 +766,7 @@
 
 // Determine if we should do an OSR compilation of a given method.
 CompLevel SimpleThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread* thread) {
-  CompLevel next_level = common(&SimpleThresholdPolicy::loop_predicate, method, cur_level);
+  CompLevel next_level = common(&SimpleThresholdPolicy::loop_predicate, method, cur_level, true);
   if (cur_level == CompLevel_none) {
     // If there is a live OSR method that means that we deopted to the interpreter
     // for the transition.
@@ -434,13 +783,39 @@
   return next_level;
 }
 
+bool SimpleThresholdPolicy::maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread) {
+  if (UseAOT && !delay_compilation_during_startup()) {
+    if (cur_level == CompLevel_full_profile || cur_level == CompLevel_none) {
+      // If the current level is full profile or interpreter and we're switching to any other level,
+      // activate the AOT code back first so that we won't waste time overprofiling.
+      compile(mh, InvocationEntryBci, CompLevel_aot, thread);
+      // Fall through for JIT compilation.
+    }
+    if (next_level == CompLevel_limited_profile && cur_level != CompLevel_aot && mh->has_aot_code()) {
+      // If the next level is limited profile, use the aot code (if there is any),
+      // since it's essentially the same thing.
+      compile(mh, InvocationEntryBci, CompLevel_aot, thread);
+      // Not need to JIT, we're done.
+      return true;
+    }
+  }
+  return false;
+}
+
 
 // Handle the invocation event.
 void SimpleThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
-                                              CompLevel level, CompiledMethod* nm, JavaThread* thread) {
-  if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
-    CompLevel next_level = call_event(mh(), level, thread);
-    if (next_level != level) {
+                                                      CompLevel level, CompiledMethod* nm, JavaThread* thread) {
+  if (should_create_mdo(mh(), level)) {
+    create_mdo(mh, thread);
+  }
+  CompLevel next_level = call_event(mh(), level, thread);
+  if (next_level != level) {
+    if (maybe_switch_to_aot(mh, level, next_level, thread)) {
+      // No JITting necessary
+      return;
+    }
+    if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
       compile(mh, InvocationEntryBci, next_level, thread);
     }
   }
@@ -450,25 +825,77 @@
 // with a regular entry from here.
 void SimpleThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
                                                      int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
-  // If the method is already compiling, quickly bail out.
-  if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
-    // Use loop event as an opportunity to also check there's been
-    // enough calls.
-    CompLevel cur_level = comp_level(mh());
-    CompLevel next_level = call_event(mh(), cur_level, thread);
-    CompLevel next_osr_level = loop_event(mh(), level, thread);
+  if (should_create_mdo(mh(), level)) {
+    create_mdo(mh, thread);
+  }
+  // Check if MDO should be created for the inlined method
+  if (should_create_mdo(imh(), level)) {
+    create_mdo(imh, thread);
+  }
 
-    next_level = MAX2(next_level,
-                      next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level);
-    bool is_compiling = false;
-    if (next_level != cur_level) {
-      compile(mh, InvocationEntryBci, next_level, thread);
-      is_compiling = true;
+  if (is_compilation_enabled()) {
+    CompLevel next_osr_level = loop_event(imh(), level, thread);
+    CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
+    // At the very least compile the OSR version
+    if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
+      compile(imh, bci, next_osr_level, thread);
     }
 
-    // Do the OSR version
-    if (!is_compiling && next_osr_level != level) {
-      compile(mh, bci, next_osr_level, thread);
+    // Use loop event as an opportunity to also check if there's been
+    // enough calls.
+    CompLevel cur_level, next_level;
+    if (mh() != imh()) { // If there is an enclosing method
+      if (level == CompLevel_aot) {
+        // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
+        if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
+          compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread);
+        }
+      } else {
+        // Current loop event level is not AOT
+        guarantee(nm != NULL, "Should have nmethod here");
+        cur_level = comp_level(mh());
+        next_level = call_event(mh(), cur_level, thread);
+
+        if (max_osr_level == CompLevel_full_optimization) {
+          // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
+          bool make_not_entrant = false;
+          if (nm->is_osr_method()) {
+            // This is an osr method, just make it not entrant and recompile later if needed
+            make_not_entrant = true;
+          } else {
+            if (next_level != CompLevel_full_optimization) {
+              // next_level is not full opt, so we need to recompile the
+              // enclosing method without the inlinee
+              cur_level = CompLevel_none;
+              make_not_entrant = true;
+            }
+          }
+          if (make_not_entrant) {
+            if (PrintTieredEvents) {
+              int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
+              print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
+            }
+            nm->make_not_entrant();
+          }
+        }
+        // Fix up next_level if necessary to avoid deopts
+        if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) {
+          next_level = CompLevel_full_profile;
+        }
+        if (cur_level != next_level) {
+          if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
+            compile(mh, InvocationEntryBci, next_level, thread);
+          }
+        }
+      }
+    } else {
+      cur_level = comp_level(mh());
+      next_level = call_event(mh(), cur_level, thread);
+      if (next_level != cur_level) {
+        if (!maybe_switch_to_aot(mh, cur_level, next_level, thread) && !CompileBroker::compilation_is_in_queue(mh)) {
+          compile(mh, InvocationEntryBci, next_level, thread);
+        }
+      }
     }
   }
 }
--- a/src/hotspot/share/runtime/simpleThresholdPolicy.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/simpleThresholdPolicy.hpp	Tue May 15 10:13:52 2018 -0700
@@ -34,8 +34,136 @@
 
 class CompileTask;
 class CompileQueue;
+/*
+ *  The system supports 5 execution levels:
+ *  * level 0 - interpreter
+ *  * level 1 - C1 with full optimization (no profiling)
+ *  * level 2 - C1 with invocation and backedge counters
+ *  * level 3 - C1 with full profiling (level 2 + MDO)
+ *  * level 4 - C2
+ *
+ * Levels 0, 2 and 3 periodically notify the runtime about the current value of the counters
+ * (invocation counters and backedge counters). The frequency of these notifications is
+ * different at each level. These notifications are used by the policy to decide what transition
+ * to make.
+ *
+ * Execution starts at level 0 (interpreter), then the policy can decide either to compile the
+ * method at level 3 or level 2. The decision is based on the following factors:
+ *    1. The length of the C2 queue determines the next level. The observation is that level 2
+ * is generally faster than level 3 by about 30%, therefore we would want to minimize the time
+ * a method spends at level 3. We should only spend the time at level 3 that is necessary to get
+ * adequate profiling. So, if the C2 queue is long enough it is more beneficial to go first to
+ * level 2, because if we transitioned to level 3 we would be stuck there until our C2 compile
+ * request makes its way through the long queue. When the load on C2 recedes we are going to
+ * recompile at level 3 and start gathering profiling information.
+ *    2. The length of C1 queue is used to dynamically adjust the thresholds, so as to introduce
+ * additional filtering if the compiler is overloaded. The rationale is that by the time a
+ * method gets compiled it can become unused, so it doesn't make sense to put too much onto the
+ * queue.
+ *
+ * After profiling is completed at level 3 the transition is made to level 4. Again, the length
+ * of the C2 queue is used as a feedback to adjust the thresholds.
+ *
+ * After the first C1 compile some basic information is determined about the code like the number
+ * of the blocks and the number of the loops. Based on that it can be decided that a method
+ * is trivial and compiling it with C1 will yield the same code. In this case the method is
+ * compiled at level 1 instead of 4.
+ *
+ * We also support profiling at level 0. If C1 is slow enough to produce the level 3 version of
+ * the code and the C2 queue is sufficiently small we can decide to start profiling in the
+ * interpreter (and continue profiling in the compiled code once the level 3 version arrives).
+ * If the profiling at level 0 is fully completed before level 3 version is produced, a level 2
+ * version is compiled instead in order to run faster waiting for a level 4 version.
+ *
+ * Compile queues are implemented as priority queues - for each method in the queue we compute
+ * the event rate (the number of invocation and backedge counter increments per unit of time).
+ * When getting an element off the queue we pick the one with the largest rate. Maintaining the
+ * rate also allows us to remove stale methods (the ones that got on the queue but stopped
+ * being used shortly after that).
+*/
+
+/* Command line options:
+ * - Tier?InvokeNotifyFreqLog and Tier?BackedgeNotifyFreqLog control the frequency of method
+ *   invocation and backedge notifications. Basically every n-th invocation or backedge a mutator thread
+ *   makes a call into the runtime.
+ *
+ * - Tier?InvocationThreshold, Tier?CompileThreshold, Tier?BackEdgeThreshold, Tier?MinInvocationThreshold control
+ *   compilation thresholds.
+ *   Level 2 thresholds are not used and are provided for option-compatibility and potential future use.
+ *   Other thresholds work as follows:
+ *
+ *   Transition from interpreter (level 0) to C1 with full profiling (level 3) happens when
+ *   the following predicate is true (X is the level):
+ *
+ *   i > TierXInvocationThreshold * s || (i > TierXMinInvocationThreshold * s  && i + b > TierXCompileThreshold * s),
+ *
+ *   where $i$ is the number of method invocations, $b$ number of backedges and $s$ is the scaling
+ *   coefficient that will be discussed further.
+ *   The intuition is to equalize the time that is spend profiling each method.
+ *   The same predicate is used to control the transition from level 3 to level 4 (C2). It should be
+ *   noted though that the thresholds are relative. Moreover i and b for the 0->3 transition come
+ *   from Method* and for 3->4 transition they come from MDO (since profiled invocations are
+ *   counted separately). Finally, if a method does not contain anything worth profiling, a transition
+ *   from level 3 to level 4 occurs without considering thresholds (e.g., with fewer invocations than
+ *   what is specified by Tier4InvocationThreshold).
+ *
+ *   OSR transitions are controlled simply with b > TierXBackEdgeThreshold * s predicates.
+ *
+ * - Tier?LoadFeedback options are used to automatically scale the predicates described above depending
+ *   on the compiler load. The scaling coefficients are computed as follows:
+ *
+ *   s = queue_size_X / (TierXLoadFeedback * compiler_count_X) + 1,
+ *
+ *   where queue_size_X is the current size of the compiler queue of level X, and compiler_count_X
+ *   is the number of level X compiler threads.
+ *
+ *   Basically these parameters describe how many methods should be in the compile queue
+ *   per compiler thread before the scaling coefficient increases by one.
+ *
+ *   This feedback provides the mechanism to automatically control the flow of compilation requests
+ *   depending on the machine speed, mutator load and other external factors.
+ *
+ * - Tier3DelayOn and Tier3DelayOff parameters control another important feedback loop.
+ *   Consider the following observation: a method compiled with full profiling (level 3)
+ *   is about 30% slower than a method at level 2 (just invocation and backedge counters, no MDO).
+ *   Normally, the following transitions will occur: 0->3->4. The problem arises when the C2 queue
+ *   gets congested and the 3->4 transition is delayed. While the method is the C2 queue it continues
+ *   executing at level 3 for much longer time than is required by the predicate and at suboptimal speed.
+ *   The idea is to dynamically change the behavior of the system in such a way that if a substantial
+ *   load on C2 is detected we would first do the 0->2 transition allowing a method to run faster.
+ *   And then when the load decreases to allow 2->3 transitions.
+ *
+ *   Tier3Delay* parameters control this switching mechanism.
+ *   Tier3DelayOn is the number of methods in the C2 queue per compiler thread after which the policy
+ *   no longer does 0->3 transitions but does 0->2 transitions instead.
+ *   Tier3DelayOff switches the original behavior back when the number of methods in the C2 queue
+ *   per compiler thread falls below the specified amount.
+ *   The hysteresis is necessary to avoid jitter.
+ *
+ * - TieredCompileTaskTimeout is the amount of time an idle method can spend in the compile queue.
+ *   Basically, since we use the event rate d(i + b)/dt as a value of priority when selecting a method to
+ *   compile from the compile queue, we also can detect stale methods for which the rate has been
+ *   0 for some time in the same iteration. Stale methods can appear in the queue when an application
+ *   abruptly changes its behavior.
+ *
+ * - TieredStopAtLevel, is used mostly for testing. It allows to bypass the policy logic and stick
+ *   to a given level. For example it's useful to set TieredStopAtLevel = 1 in order to compile everything
+ *   with pure c1.
+ *
+ * - Tier0ProfilingStartPercentage allows the interpreter to start profiling when the inequalities in the
+ *   0->3 predicate are already exceeded by the given percentage but the level 3 version of the
+ *   method is still not ready. We can even go directly from level 0 to 4 if c1 doesn't produce a compiled
+ *   version in time. This reduces the overall transition to level 4 and decreases the startup time.
+ *   Note that this behavior is also guarded by the Tier3Delay mechanism: when the c2 queue is too long
+ *   these is not reason to start profiling prematurely.
+ *
+ * - TieredRateUpdateMinTime and TieredRateUpdateMaxTime are parameters of the rate computation.
+ *   Basically, the rate is not computed more frequently than TieredRateUpdateMinTime and is considered
+ *   to be zero if no events occurred in TieredRateUpdateMaxTime.
+ */
 
 class SimpleThresholdPolicy : public CompilationPolicy {
+  jlong _start_time;
   int _c1_count, _c2_count;
 
   // Check if the counter is big enough and set carry (effectively infinity).
@@ -49,7 +177,7 @@
   bool call_predicate(int i, int b, CompLevel cur_level, Method* method);
   bool loop_predicate(int i, int b, CompLevel cur_level, Method* method);
   // Common transition function. Given a predicate determines if a method should transition to another level.
-  CompLevel common(Predicate p, Method* method, CompLevel cur_level);
+  CompLevel common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback = false);
   // Transition functions.
   // call_event determines if a method should be compiled at a different
   // level with a regular invocation entry.
@@ -58,6 +186,35 @@
   // level.
   CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread* thread);
   void print_counters(const char* prefix, const methodHandle& mh);
+  // Has a method been long around?
+  // We don't remove old methods from the compile queue even if they have
+  // very low activity (see select_task()).
+  inline bool is_old(Method* method);
+  // Was a given method inactive for a given number of milliseconds.
+  // If it is, we would remove it from the queue (see select_task()).
+  inline bool is_stale(jlong t, jlong timeout, Method* m);
+  // Compute the weight of the method for the compilation scheduling
+  inline double weight(Method* method);
+  // Apply heuristics and return true if x should be compiled before y
+  inline bool compare_methods(Method* x, Method* y);
+  // Compute event rate for a given method. The rate is the number of event (invocations + backedges)
+  // per millisecond.
+  inline void update_rate(jlong t, Method* m);
+  // Compute threshold scaling coefficient
+  inline double threshold_scale(CompLevel level, int feedback_k);
+  // If a method is old enough and is still in the interpreter we would want to
+  // start profiling without waiting for the compiled method to arrive. This function
+  // determines whether we should do that.
+  inline bool should_create_mdo(Method* method, CompLevel cur_level);
+  // Create MDO if necessary.
+  void create_mdo(const methodHandle& mh, JavaThread* thread);
+  // Is method profiled enough?
+  bool is_method_profiled(Method* method);
+
+  double _increase_threshold_at_ratio;
+
+  bool maybe_switch_to_aot(const methodHandle& mh, CompLevel cur_level, CompLevel next_level, JavaThread* thread);
+
 protected:
   int c1_count() const     { return _c1_count; }
   int c2_count() const     { return _c2_count; }
@@ -67,7 +224,7 @@
   enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT };
   void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
   // Print policy-specific information if necessary
-  virtual void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level) { }
+  virtual void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level);
   // Check if the method can be compiled, change level if necessary
   void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
   // Submit a given method for compilation
@@ -87,8 +244,13 @@
                                        CompLevel level, CompiledMethod* nm, JavaThread* thread);
   virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
                                         int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
+
+  void set_increase_threshold_at_ratio() { _increase_threshold_at_ratio = 100 / (100 - (double)IncreaseFirstTierCompileThresholdAt); }
+  void set_start_time(jlong t) { _start_time = t;    }
+  jlong start_time() const     { return _start_time; }
+
 public:
-  SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
+  SimpleThresholdPolicy() : _start_time(0), _c1_count(0), _c2_count(0) { }
   virtual int compiler_count(CompLevel comp_level) {
     if (is_c1_compile(comp_level)) return c1_count();
     if (is_c2_compile(comp_level)) return c2_count();
@@ -107,11 +269,7 @@
   virtual bool is_mature(Method* method);
   // Initialize: set compiler thread count
   virtual void initialize();
-  virtual bool should_not_inline(ciEnv* env, ciMethod* callee) {
-    return (env->comp_level() == CompLevel_limited_profile ||
-            env->comp_level() == CompLevel_full_profile) &&
-            callee->has_loops();
-  }
+  virtual bool should_not_inline(ciEnv* env, ciMethod* callee);
 };
 
 #endif // TIERED
--- a/src/hotspot/share/runtime/thread.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/thread.cpp	Tue May 15 10:13:52 2018 -0700
@@ -114,9 +114,6 @@
 #include "utilities/macros.hpp"
 #include "utilities/preserveException.hpp"
 #include "utilities/vmError.hpp"
-#if INCLUDE_PARALLELGC
-#include "gc/parallel/pcTasks.hpp"
-#endif
 #if INCLUDE_JVMCI
 #include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciRuntime.hpp"
@@ -1470,7 +1467,6 @@
 
 void JavaThread::collect_counters(typeArrayOop array) {
   if (JVMCICounterSize > 0) {
-    MutexLocker tl(Threads_lock);
     JavaThreadIteratorWithHandle jtiwh;
     for (int i = 0; i < array->length(); i++) {
       array->long_at_put(i, _jvmci_old_thread_counters[i]);
@@ -3436,13 +3432,25 @@
   // If CompilerThreads ever become non-JavaThreads, add them here
 }
 
-// All JavaThreads + all non-JavaThreads (i.e., every thread in the system).
-void Threads::threads_do(ThreadClosure* tc) {
+// All JavaThreads
+void Threads::java_threads_do(ThreadClosure* tc) {
   assert_locked_or_safepoint(Threads_lock);
   // ALL_JAVA_THREADS iterates through all JavaThreads.
   ALL_JAVA_THREADS(p) {
     tc->do_thread(p);
   }
+}
+
+void Threads::java_threads_and_vm_thread_do(ThreadClosure* tc) {
+  assert_locked_or_safepoint(Threads_lock);
+  java_threads_do(tc);
+  tc->do_thread(VMThread::vm_thread());
+}
+
+// All JavaThreads + all non-JavaThreads (i.e., every thread in the system).
+void Threads::threads_do(ThreadClosure* tc) {
+  assert_locked_or_safepoint(Threads_lock);
+  java_threads_do(tc);
   non_java_threads_do(tc);
 }
 
@@ -4465,24 +4473,6 @@
   possibly_parallel_threads_do(is_par, &tc);
 }
 
-#if INCLUDE_PARALLELGC
-// Used by ParallelScavenge
-void Threads::create_thread_roots_tasks(GCTaskQueue* q) {
-  ALL_JAVA_THREADS(p) {
-    q->enqueue(new ThreadRootsTask(p));
-  }
-  q->enqueue(new ThreadRootsTask(VMThread::vm_thread()));
-}
-
-// Used by Parallel Old
-void Threads::create_thread_roots_marking_tasks(GCTaskQueue* q) {
-  ALL_JAVA_THREADS(p) {
-    q->enqueue(new ThreadRootsMarkingTask(p));
-  }
-  q->enqueue(new ThreadRootsMarkingTask(VMThread::vm_thread()));
-}
-#endif // INCLUDE_PARALLELGC
-
 void Threads::nmethods_do(CodeBlobClosure* cf) {
   ALL_JAVA_THREADS(p) {
     // This is used by the code cache sweeper to mark nmethods that are active
--- a/src/hotspot/share/runtime/thread.hpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/runtime/thread.hpp	Tue May 15 10:13:52 2018 -0700
@@ -2104,6 +2104,8 @@
   static void add(JavaThread* p, bool force_daemon = false);
   static void remove(JavaThread* p);
   static void non_java_threads_do(ThreadClosure* tc);
+  static void java_threads_do(ThreadClosure* tc);
+  static void java_threads_and_vm_thread_do(ThreadClosure* tc);
   static void threads_do(ThreadClosure* tc);
   static void possibly_parallel_threads_do(bool is_par, ThreadClosure* tc);
 
@@ -2142,10 +2144,6 @@
   static void oops_do(OopClosure* f, CodeBlobClosure* cf);
   // This version may be called by sequential or parallel code.
   static void possibly_parallel_oops_do(bool is_par, OopClosure* f, CodeBlobClosure* cf);
-  // This creates a list of GCTasks, one per thread.
-  static void create_thread_roots_tasks(GCTaskQueue* q);
-  // This creates a list of GCTasks, one per thread, for marking objects.
-  static void create_thread_roots_marking_tasks(GCTaskQueue* q);
 
   // Apply "f->do_oop" to roots in all threads that
   // are part of compiled frames
--- a/src/hotspot/share/services/threadService.cpp	Tue May 15 18:03:31 2018 +0530
+++ b/src/hotspot/share/services/threadService.cpp	Tue May 15 10:13:52 2018 -0700
@@ -122,6 +122,9 @@
 
 void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
   Atomic::dec(&_exiting_threads_count);
+  if (daemon) {
+    Atomic::dec(&_exiting_daemon_threads_count);
+  }
 
   if (thread->is_hidden_from_external_view() ||
       thread->is_jvmti_agent_thread()) {
@@ -129,10 +132,8 @@
   }
 
   _live_threads_count->set_value(_live_threads_count->get_value() - 1);
-
   if (daemon) {
     _daemon_threads_count->set_value(_daemon_threads_count->get_value() - 1);
-    Atomic::dec(&_exiting_daemon_threads_count);
   }
 }
 
--- a/src/java.base/share/classes/java/lang/String.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/String.java	Tue May 15 10:13:52 2018 -0700
@@ -2602,7 +2602,7 @@
      * Returns a string whose value is this string, with all leading
      * and trailing space removed, where space is defined
      * as any character whose codepoint is less than or equal to
-     * {@code '\u005Cu0020'} (the space character).
+     * {@code 'U+0020'} (the space character).
      * <p>
      * If this {@code String} object represents an empty character
      * sequence, or the first and last characters of character sequence
@@ -2637,6 +2637,98 @@
     }
 
     /**
+     * Returns a string whose value is this string, with all leading
+     * and trailing {@link Character#isWhitespace(int) white space}
+     * removed.
+     * <p>
+     * If this {@code String} object represents an empty string,
+     * or if all code points in this string are
+     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * is returned.
+     * <p>
+     * Otherwise, returns a substring of this string beginning with the first
+     * code point that is not a {@link Character#isWhitespace(int) white space}
+     * up to and including the last code point that is not a
+     * {@link Character#isWhitespace(int) white space}.
+     * <p>
+     * This method may be used to strip
+     * {@link Character#isWhitespace(int) white space} from
+     * the beginning and end of a string.
+     *
+     * @return  a string whose value is this string, with all leading
+     *          and trailing white space removed
+     *
+     * @see Character#isWhitespace(int)
+     *
+     * @since 11
+     */
+    public String strip() {
+        String ret = isLatin1() ? StringLatin1.strip(value)
+                                : StringUTF16.strip(value);
+        return ret == null ? this : ret;
+    }
+
+    /**
+     * Returns a string whose value is this string, with all leading
+     * {@link Character#isWhitespace(int) white space} removed.
+     * <p>
+     * If this {@code String} object represents an empty string,
+     * or if all code points in this string are
+     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * is returned.
+     * <p>
+     * Otherwise, returns a substring of this string beginning with the first
+     * code point that is not a {@link Character#isWhitespace(int) white space}
+     * up to to and including the last code point of this string.
+     * <p>
+     * This method may be used to trim
+     * {@link Character#isWhitespace(int) white space} from
+     * the beginning of a string.
+     *
+     * @return  a string whose value is this string, with all leading white
+     *          space removed
+     *
+     * @see Character#isWhitespace(int)
+     *
+     * @since 11
+     */
+    public String stripLeading() {
+        String ret = isLatin1() ? StringLatin1.stripLeading(value)
+                                : StringUTF16.stripLeading(value);
+        return ret == null ? this : ret;
+    }
+
+    /**
+     * Returns a string whose value is this string, with all trailing
+     * {@link Character#isWhitespace(int) white space} removed.
+     * <p>
+     * If this {@code String} object represents an empty string,
+     * or if all characters in this string are
+     * {@link Character#isWhitespace(int) white space}, then an empty string
+     * is returned.
+     * <p>
+     * Otherwise, returns a substring of this string beginning with the first
+     * code point of this string up to and including the last code point
+     * that is not a {@link Character#isWhitespace(int) white space}.
+     * <p>
+     * This method may be used to trim
+     * {@link Character#isWhitespace(int) white space} from
+     * the end of a string.
+     *
+     * @return  a string whose value is this string, with all trailing white
+     *          space removed
+     *
+     * @see Character#isWhitespace(int)
+     *
+     * @since 11
+     */
+    public String stripTrailing() {
+        String ret = isLatin1() ? StringLatin1.stripTrailing(value)
+                                : StringUTF16.stripTrailing(value);
+        return ret == null ? this : ret;
+    }
+
+    /**
      * This object (which is already a string!) is itself returned.
      *
      * @return  the string itself.
--- a/src/java.base/share/classes/java/lang/StringLatin1.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/StringLatin1.java	Tue May 15 10:13:52 2018 -0700
@@ -538,6 +538,57 @@
             newString(value, st, len - st) : null;
     }
 
+    public static int indexOfNonWhitespace(byte[] value) {
+        int length = value.length;
+        int left = 0;
+        while (left < length) {
+            char ch = (char)(value[left] & 0xff);
+            if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                break;
+            }
+            left++;
+        }
+        return left;
+    }
+
+    public static int lastIndexOfNonWhitespace(byte[] value) {
+        int length = value.length;
+        int right = length;
+        while (0 < right) {
+            char ch = (char)(value[right - 1] & 0xff);
+            if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
+                break;
+            }
+            right--;
+        }
+        return right;
+    }
+
+    public static String strip(byte[] value) {
+        int left = indexOfNonWhitespace(value);
+        if (left == value.length) {
+            return "";
+        }
+        int right = lastIndexOfNonWhitespace(value);
+        return ((left > 0) || (right < value.length)) ? newString(value, left, right - left) : null;
+    }
+
+    public static String stripLeading(byte[] value) {
+        int left = indexOfNonWhitespace(value);
+        if (left == value.length) {
+            return "";
+        }
+        return (left != 0) ? newString(value, left, value.length - left) : null;
+    }
+
+    public static String stripTrailing(byte[] value) {
+        int right = lastIndexOfNonWhitespace(value);
+        if (right == 0) {
+            return "";
+        }
+        return (right != value.length) ? newString(value, 0, right) : null;
+    }
+
     public static void putChar(byte[] val, int index, int c) {
         //assert (canEncode(c));
         val[index] = (byte)(c);
--- a/src/java.base/share/classes/java/lang/StringUTF16.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/StringUTF16.java	Tue May 15 10:13:52 2018 -0700
@@ -856,6 +856,61 @@
             null;
     }
 
+
+    public static int indexOfNonWhitespace(byte[] value) {
+        int length = value.length >> 1;
+        int left = 0;
+        while (left < length) {
+            int codepoint = codePointAt(value, left, length);
+            if (codepoint != ' ' && codepoint != '\t' && !Character.isWhitespace(codepoint)) {
+                break;
+            }
+            left += Character.charCount(codepoint);
+        }
+        return left;
+    }
+
+    public static int lastIndexOfNonWhitespace(byte[] value) {
+        int length = value.length >> 1;
+        int right = length;
+        while (0 < right) {
+            int codepoint = codePointBefore(value, right);
+            if (codepoint != ' ' && codepoint != '\t' && !Character.isWhitespace(codepoint)) {
+                break;
+            }
+            right -= Character.charCount(codepoint);
+        }
+        return right;
+    }
+
+    public static String strip(byte[] value) {
+        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;
+    }
+
+    public static String stripLeading(byte[] value) {
+        int length = value.length >> 1;
+        int left = indexOfNonWhitespace(value);
+        if (left == length) {
+            return "";
+        }
+        return (left != 0) ? newString(value, left, length - left) : null;
+    }
+
+    public static String stripTrailing(byte[] value) {
+        int length = value.length >> 1;
+        int right = lastIndexOfNonWhitespace(value);
+        if (right == 0) {
+            return "";
+        }
+        return (right != length) ? newString(value, 0, right) : null;
+    }
+
     private static void putChars(byte[] val, int index, char[] str, int off, int end) {
         while (off < end) {
             putChar(val, index++, str[off++]);
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Tue May 15 10:13:52 2018 -0700
@@ -564,7 +564,6 @@
         throw new AssertionError("All subclasses should override this method");
     }
 
-
     // Shared access checking logic.
 
     // For non-public members or members in package-private classes,
@@ -674,4 +673,13 @@
         }
         return printStackWhenAccessFails;
     }
+
+    /**
+     * Returns the root AccessibleObject; or null if this object is the root.
+     *
+     * All subclasses override this method.
+     */
+    AccessibleObject getRoot() {
+        throw new InternalError();
+    }
 }
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java	Tue May 15 10:13:52 2018 -0700
@@ -103,11 +103,8 @@
     // occur in annotation code.
     private Constructor<T>      root;
 
-    /**
-     * Used by Excecutable for annotation sharing.
-     */
     @Override
-    Executable getRoot() {
+    Constructor<T> getRoot() {
         return root;
     }
 
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/Executable.java	Tue May 15 10:13:52 2018 -0700
@@ -56,11 +56,6 @@
     abstract byte[] getAnnotationBytes();
 
     /**
-     * Accessor method to allow code sharing
-     */
-    abstract Executable getRoot();
-
-    /**
      * Does the Executable have generic information.
      */
     abstract boolean hasGenericInformation();
@@ -602,7 +597,7 @@
         if ((declAnnos = declaredAnnotations) == null) {
             synchronized (this) {
                 if ((declAnnos = declaredAnnotations) == null) {
-                    Executable root = getRoot();
+                    Executable root = (Executable)getRoot();
                     if (root != null) {
                         declAnnos = root.declaredAnnotations();
                     } else {
--- a/src/java.base/share/classes/java/lang/reflect/Field.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/Field.java	Tue May 15 10:13:52 2018 -0700
@@ -1128,6 +1128,11 @@
         }
     }
 
+    @Override
+    Field getRoot() {
+        return root;
+    }
+
     /**
      * @throws NullPointerException {@inheritDoc}
      * @since 1.5
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Tue May 15 10:13:52 2018 -0700
@@ -198,11 +198,8 @@
         checkCanSetAccessible(caller, clazz);
     }
 
-    /**
-     * Used by Excecutable for annotation sharing.
-     */
     @Override
-    Executable getRoot() {
+    Method getRoot() {
         return root;
     }
 
--- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java	Tue May 15 10:13:52 2018 -0700
@@ -154,4 +154,9 @@
     public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
         return arg.copy();
     }
+
+    @SuppressWarnings("unchecked")
+    public <T extends AccessibleObject> T getRoot(T obj) {
+        return (T) obj.getRoot();
+    }
 }
--- a/src/java.base/share/classes/java/math/BigInteger.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/math/BigInteger.java	Tue May 15 10:13:52 2018 -0700
@@ -52,19 +52,17 @@
  * and a few other miscellaneous operations.
  *
  * <p>Semantics of arithmetic operations exactly mimic those of Java's integer
- * arithmetic operators, as defined in <i>The Java Language Specification</i>.
+ * arithmetic operators, as defined in <i>The Java&trade; Language Specification</i>.
  * For example, division by zero throws an {@code ArithmeticException}, and
  * division of a negative by a positive yields a negative (or zero) remainder.
- * All of the details in the Spec concerning overflow are ignored, as
- * BigIntegers are made as large as necessary to accommodate the results of an
- * operation.
  *
  * <p>Semantics of shift operations extend those of Java's shift operators
  * to allow for negative shift distances.  A right-shift with a negative
  * shift distance results in a left shift, and vice-versa.  The unsigned
- * right shift operator ({@code >>>}) is omitted, as this operation makes
- * little sense in combination with the "infinite word size" abstraction
- * provided by this class.
+ * right shift operator ({@code >>>}) is omitted since this operation
+ * only makes sense for a fixed sized word and not for a
+ * representation conceptually having an infinite number of leading
+ * virtual sign bits.
  *
  * <p>Semantics of bitwise logical operations exactly mimic those of Java's
  * bitwise integer operators.  The binary operators ({@code and},
@@ -84,8 +82,8 @@
  * extended so that it contains the designated bit.  None of the single-bit
  * operations can produce a BigInteger with a different sign from the
  * BigInteger being operated on, as they affect only a single bit, and the
- * "infinite word size" abstraction provided by this class ensures that there
- * are infinitely many "virtual sign bits" preceding each BigInteger.
+ * arbitrarily large abstraction provided by this class ensures that conceptually
+ * there are infinitely many "virtual sign bits" preceding each BigInteger.
  *
  * <p>For the sake of brevity and clarity, pseudo-code is used throughout the
  * descriptions of BigInteger methods.  The pseudo-code expression
@@ -105,13 +103,18 @@
  * +2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive)
  * and may support values outside of that range.
  *
+ * An {@code ArithmeticException} is thrown when a BigInteger
+ * constructor or method would generate a value outside of the
+ * supported range.
+ *
  * The range of probable prime values is limited and may be less than
  * the full supported positive range of {@code BigInteger}.
  * The range must be at least 1 to 2<sup>500000000</sup>.
  *
  * @implNote
- * BigInteger constructors and operations throw {@code ArithmeticException} when
- * the result is out of the supported range of
+ * In the reference implementation, BigInteger constructors and
+ * operations throw {@code ArithmeticException} when the result is out
+ * of the supported range of
  * -2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive) to
  * +2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive).
  *
--- a/src/java.base/share/classes/java/util/Objects.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/java/util/Objects.java	Tue May 15 10:13:52 2018 -0700
@@ -35,16 +35,16 @@
  * on objects, or checking certain conditions before operation.  These utilities
  * include {@code null}-safe or {@code null}-tolerant methods for computing the
  * hash code of an object, returning a string for an object, comparing two
- * objects, and checking if indexes or sub-range values are out-of-bounds.
+ * objects, and checking if indexes or sub-range values are out of bounds.
  *
  * @apiNote
  * Static methods such as {@link Objects#checkIndex},
  * {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
  * provided for the convenience of checking if values corresponding to indexes
- * and sub-ranges are out-of-bounds.
+ * and sub-ranges are out of bounds.
  * Variations of these static methods support customization of the runtime
  * exception, and corresponding exception detail message, that is thrown when
- * values are out-of-bounds.  Such methods accept a functional interface
+ * values are out of bounds.  Such methods accept a functional interface
  * argument, instances of {@code BiFunction}, that maps out-of-bound values to a
  * runtime exception.  Care should be taken when using such methods in
  * combination with an argument that is a lambda expression, method reference or
@@ -352,7 +352,7 @@
      * Checks if the {@code index} is within the bounds of the range from
      * {@code 0} (inclusive) to {@code length} (exclusive).
      *
-     * <p>The {@code index} is defined to be out-of-bounds if any of the
+     * <p>The {@code index} is defined to be out of bounds if any of the
      * following inequalities is true:
      * <ul>
      *  <li>{@code index < 0}</li>
@@ -363,7 +363,7 @@
      * @param index the index
      * @param length the upper-bound (exclusive) of the range
      * @return {@code index} if it is within bounds of the range
-     * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
+     * @throws IndexOutOfBoundsException if the {@code index} is out of bounds
      * @since 9
      */
     @ForceInline
@@ -377,7 +377,7 @@
      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
      * (inclusive) to {@code length} (exclusive).
      *
-     * <p>The sub-range is defined to be out-of-bounds if any of the following
+     * <p>The sub-range is defined to be out of bounds if any of the following
      * inequalities is true:
      * <ul>
      *  <li>{@code fromIndex < 0}</li>
@@ -390,7 +390,7 @@
      * @param toIndex the upper-bound (exclusive) of the sub-range
      * @param length the upper-bound (exclusive) the range
      * @return {@code fromIndex} if the sub-range within bounds of the range
-     * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
+     * @throws IndexOutOfBoundsException if the sub-range is out of bounds
      * @since 9
      */
     public static
@@ -403,7 +403,7 @@
      * {@code fromIndex + size} (exclusive) is within the bounds of range from
      * {@code 0} (inclusive) to {@code length} (exclusive).
      *
-     * <p>The sub-range is defined to be out-of-bounds if any of the following
+     * <p>The sub-range is defined to be out of bounds if any of the following
      * inequalities is true:
      * <ul>
      *  <li>{@code fromIndex < 0}</li>
@@ -416,7 +416,7 @@
      * @param size the size of the sub-range
      * @param length the upper-bound (exclusive) of the range
      * @return {@code fromIndex} if the sub-range within bounds of the range
-     * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
+     * @throws IndexOutOfBoundsException if the sub-range is out of bounds
      * @since 9
      */
     public static
--- a/src/java.base/share/classes/jdk/internal/reflect/LangReflectAccess.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/jdk/internal/reflect/LangReflectAccess.java	Tue May 15 10:13:52 2018 -0700
@@ -115,4 +115,7 @@
 
     /** Makes a "child" copy of a Constructor */
     public <T> Constructor<T> copyConstructor(Constructor<T> arg);
+
+    /** Gets the root of the given AccessibleObject object; null if arg is the root */
+    public <T extends AccessibleObject> T getRoot(T obj);
 }
--- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Tue May 15 10:13:52 2018 -0700
@@ -39,7 +39,6 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
-import java.security.Permission;
 import java.security.PrivilegedAction;
 import java.util.Objects;
 import java.util.Properties;
@@ -172,6 +171,15 @@
      */
     public FieldAccessor newFieldAccessor(Field field, boolean override) {
         checkInitted();
+
+        Field root = langReflectAccess.getRoot(field);
+        if (root != null) {
+            // FieldAccessor will use the root unless the modifiers have
+            // been overrridden
+            if (root.getModifiers() == field.getModifiers() || !override) {
+                field = root;
+            }
+        }
         return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
     }
 
@@ -185,6 +193,12 @@
             }
         }
 
+        // use the root Method that will not cache caller class
+        Method root = langReflectAccess.getRoot(method);
+        if (root != null) {
+            method = root;
+        }
+
         if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
             return new MethodAccessorGenerator().
                 generateMethod(method.getDeclaringClass(),
@@ -214,6 +228,13 @@
             return new InstantiationExceptionConstructorAccessorImpl
                 ("Can not instantiate java.lang.Class");
         }
+
+        // use the root Constructor that will not cache caller class
+        Constructor<?> root = langReflectAccess.getRoot(c);
+        if (root != null) {
+            c = root;
+        }
+
         // Bootstrapping issue: since we use Class.newInstance() in
         // the ConstructorAccessor generation process, we have to
         // break the cycle here.
--- a/src/java.base/share/classes/jdk/internal/util/Preconditions.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/jdk/internal/util/Preconditions.java	Tue May 15 10:13:52 2018 -0700
@@ -185,13 +185,13 @@
         // Switch to default if fewer or more arguments than required are supplied
         switch ((args.size() != argSize) ? "" : checkKind) {
             case "checkIndex":
-                return String.format("Index %d out-of-bounds for length %d",
+                return String.format("Index %d out of bounds for length %d",
                                      args.get(0), args.get(1));
             case "checkFromToIndex":
-                return String.format("Range [%d, %d) out-of-bounds for length %d",
+                return String.format("Range [%d, %d) out of bounds for length %d",
                                      args.get(0), args.get(1), args.get(2));
             case "checkFromIndexSize":
-                return String.format("Range [%d, %<d + %d) out-of-bounds for length %d",
+                return String.format("Range [%d, %<d + %d) out of bounds for length %d",
                                      args.get(0), args.get(1), args.get(2));
             default:
                 return String.format("Range check failed: %s %s", checkKind, args);
@@ -202,7 +202,7 @@
      * Checks if the {@code index} is within the bounds of the range from
      * {@code 0} (inclusive) to {@code length} (exclusive).
      *
-     * <p>The {@code index} is defined to be out-of-bounds if any of the
+     * <p>The {@code index} is defined to be out of bounds if any of the
      * following inequalities is true:
      * <ul>
      *  <li>{@code index < 0}</li>
@@ -210,14 +210,14 @@
      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
      * </ul>
      *
-     * <p>If the {@code index} is out-of-bounds, then a runtime exception is
+     * <p>If the {@code index} is out of bounds, then a runtime exception is
      * thrown that is the result of applying the following arguments to the
      * exception formatter: the name of this method, {@code checkIndex};
      * and an unmodifiable list integers whose values are, in order, the
      * out-of-bounds arguments {@code index} and {@code length}.
      *
      * @param <X> the type of runtime exception to throw if the arguments are
-     *        out-of-bounds
+     *        out of bounds
      * @param index the index
      * @param length the upper-bound (exclusive) of the range
      * @param oobef the exception formatter that when applied with this
@@ -228,9 +228,9 @@
      *        instead (though it may be more efficient).
      *        Exceptions thrown by the formatter are relayed to the caller.
      * @return {@code index} if it is within bounds of the range
-     * @throws X if the {@code index} is out-of-bounds and the exception
+     * @throws X if the {@code index} is out of bounds and the exception
      *         formatter is non-{@code null}
-     * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
+     * @throws IndexOutOfBoundsException if the {@code index} is out of bounds
      *         and the exception formatter is {@code null}
      * @since 9
      *
@@ -254,7 +254,7 @@
      * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
      * (inclusive) to {@code length} (exclusive).
      *
-     * <p>The sub-range is defined to be out-of-bounds if any of the following
+     * <p>The sub-range is defined to be out of bounds if any of the following
      * inequalities is true:
      * <ul>
      *  <li>{@code fromIndex < 0}</li>
@@ -263,14 +263,14 @@
      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
      * </ul>
      *
-     * <p>If the sub-range  is out-of-bounds, then a runtime exception is
+     * <p>If the sub-range is out of bounds, then a runtime exception is
      * thrown that is the result of applying the following arguments to the
      * exception formatter: the name of this method, {@code checkFromToIndex};
      * and an unmodifiable list integers whose values are, in order, the
      * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
      *
      * @param <X> the type of runtime exception to throw if the arguments are
-     *        out-of-bounds
+     *        out of bounds
      * @param fromIndex the lower-bound (inclusive) of the sub-range
      * @param toIndex the upper-bound (exclusive) of the sub-range
      * @param length the upper-bound (exclusive) the range
@@ -282,9 +282,9 @@
      *        instead (though it may be more efficient).
      *        Exceptions thrown by the formatter are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
-     * @throws X if the sub-range is out-of-bounds and the exception factory
+     * @throws X if the sub-range is out of bounds and the exception factory
      *         function is non-{@code null}
-     * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+     * @throws IndexOutOfBoundsException if the sub-range is out of bounds and
      *         the exception factory function is {@code null}
      * @since 9
      */
@@ -301,7 +301,7 @@
      * {@code fromIndex + size} (exclusive) is within the bounds of range from
      * {@code 0} (inclusive) to {@code length} (exclusive).
      *
-     * <p>The sub-range is defined to be out-of-bounds if any of the following
+     * <p>The sub-range is defined to be out of bounds if any of the following
      * inequalities is true:
      * <ul>
      *  <li>{@code fromIndex < 0}</li>
@@ -310,7 +310,7 @@
      *  <li>{@code length < 0}, which is implied from the former inequalities</li>
      * </ul>
      *
-     * <p>If the sub-range  is out-of-bounds, then a runtime exception is
+     * <p>If the sub-range is out of bounds, then a runtime exception is
      * thrown that is the result of applying the following arguments to the
      * exception formatter: the name of this method, {@code checkFromIndexSize};
      * and an unmodifiable list integers whose values are, in order, the
@@ -318,7 +318,7 @@
      * {@code length}.
      *
      * @param <X> the type of runtime exception to throw if the arguments are
-     *        out-of-bounds
+     *        out of bounds
      * @param fromIndex the lower-bound (inclusive) of the sub-interval
      * @param size the size of the sub-range
      * @param length the upper-bound (exclusive) of the range
@@ -330,9 +330,9 @@
      *        instead (though it may be more efficient).
      *        Exceptions thrown by the formatter are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
-     * @throws X if the sub-range is out-of-bounds and the exception factory
+     * @throws X if the sub-range is out of bounds and the exception factory
      *         function is non-{@code null}
-     * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+     * @throws IndexOutOfBoundsException if the sub-range is out of bounds and
      *         the exception factory function is {@code null}
      * @since 9
      */
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue May 15 10:13:52 2018 -0700
@@ -867,11 +867,22 @@
         // set state to ST_KILLPENDING
         synchronized (stateLock) {
             assert state == ST_CLOSING;
-            // if connected, and the channel is registered with a Selector, we
-            // shutdown the output so that the peer reads EOF
+            // if connected and the channel is registered with a Selector then
+            // shutdown the output if possible so that the peer reads EOF. If
+            // SO_LINGER is enabled and set to a non-zero value then it needs to
+            // be disabled so that the Selector does not wait when it closes
+            // the socket.
             if (connected && isRegistered()) {
                 try {
-                    Net.shutdown(fd, Net.SHUT_WR);
+                    SocketOption<Integer> opt = StandardSocketOptions.SO_LINGER;
+                    int interval = (int) Net.getSocketOption(fd, Net.UNSPEC, opt);
+                    if (interval != 0) {
+                        if (interval > 0) {
+                            // disable SO_LINGER
+                            Net.setSocketOption(fd, Net.UNSPEC, opt, -1);
+                        }
+                        Net.shutdown(fd, Net.SHUT_WR);
+                    }
                 } catch (IOException ignore) { }
             }
             state = ST_KILLPENDING;
--- a/src/java.desktop/share/classes/javax/imageio/ImageWriteParam.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.desktop/share/classes/javax/imageio/ImageWriteParam.java	Tue May 15 10:13:52 2018 -0700
@@ -1243,7 +1243,7 @@
             throw new IllegalStateException("No compression type set!");
         }
         if (quality < 0.0F || quality > 1.0F) {
-            throw new IllegalArgumentException("Quality out-of-bounds!");
+            throw new IllegalArgumentException("Quality out of bounds!");
         }
         this.compressionQuality = quality;
     }
@@ -1341,7 +1341,7 @@
             throw new IllegalStateException("No compression type set!");
         }
         if (quality < 0.0F || quality > 1.0F) {
-            throw new IllegalArgumentException("Quality out-of-bounds!");
+            throw new IllegalArgumentException("Quality out of bounds!");
         }
         return -1.0F;
     }
--- a/src/java.net.http/share/classes/java/net/http/HttpRequest.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.net.http/share/classes/java/net/http/HttpRequest.java	Tue May 15 10:13:52 2018 -0700
@@ -598,7 +598,7 @@
          * @param length the number of bytes to use
          * @return a BodyPublisher
          * @throws IndexOutOfBoundsException if the sub-range is defined to be
-         *                                   out-of-bounds
+         *                                   out of bounds
          */
         public static BodyPublisher ofByteArray(byte[] buf, int offset, int length) {
             Objects.checkFromIndexSize(offset, length, buf.length);
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,6 +20,8 @@
 
 package com.sun.org.apache.xerces.internal.impl.dtd;
 
+import java.util.Iterator;
+
 import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
@@ -51,7 +53,6 @@
 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
-import java.util.Iterator;
 
 /**
  * The DTD validator. The validator implements a document
@@ -84,7 +85,7 @@
  * @author Jeffrey Rodriguez IBM
  * @author Neil Graham, IBM
  *
- * @LastModified: Nov 2017
+ * @LastModified: May 2018
  */
 public class XMLDTDValidator
         implements XMLComponent, XMLDocumentFilter, XMLDTDValidatorFilter, RevalidationHandler {
@@ -93,11 +94,6 @@
     // Constants
     //
 
-    /** Symbol: "&lt;&lt;datatypes>>". */
-
-    /** Top level scope (-1). */
-    private static final int TOP_LEVEL_SCOPE = -1;
-
     // feature identifiers
 
     /** Feature identifier: namespaces. */
@@ -120,9 +116,8 @@
     protected static final String WARN_ON_DUPLICATE_ATTDEF =
         Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
 
-        protected static final String PARSER_SETTINGS =
-                Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
-
+    protected static final String PARSER_SETTINGS =
+        Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
 
 
     // property identifiers
@@ -348,7 +343,7 @@
     private final QName fTempQName = new QName();
 
     /** Temporary string buffers. */
-    private final StringBuffer fBuffer = new StringBuffer();
+    private final StringBuilder fBuffer = new StringBuilder();
 
     // symbols: general
 
@@ -492,11 +487,6 @@
      *
      * @param featureId The feature identifier.
      * @param state     The state of the feature.
-     *
-     * @throws SAXNotRecognizedException The component should not throw
-     *                                   this exception.
-     * @throws SAXNotSupportedException The component should not throw
-     *                                  this exception.
      */
     public void setFeature(String featureId, boolean state)
     throws XMLConfigurationException {
@@ -520,11 +510,6 @@
      *
      * @param propertyId The property identifier.
      * @param value      The value of the property.
-     *
-     * @throws SAXNotRecognizedException The component should not throw
-     *                                   this exception.
-     * @throws SAXNotSupportedException The component should not throw
-     *                                  this exception.
      */
     public void setProperty(String propertyId, Object value)
     throws XMLConfigurationException {
@@ -1198,7 +1183,7 @@
 
                     // add attribute
                     fTempQName.setValues(attPrefix, attLocalpart, attRawName, fTempAttDecl.name.uri);
-                    int newAttr = attributes.addAttribute(fTempQName, attType, attValue);
+                    attributes.addAttribute(fTempQName, attType, attValue);
                 }
             }
             // get next att decl in the Grammar for this element
@@ -1232,14 +1217,12 @@
                     }
                 }
             }
-            int attDefIndex = -1;
             int position =
             fDTDGrammar.getFirstAttributeDeclIndex(elementIndex);
             while (position != -1) {
                 fDTDGrammar.getAttributeDecl(position, fTempAttDecl);
                 if (fTempAttDecl.name.rawname == attrRawName) {
                     // found the match att decl,
-                    attDefIndex = position;
                     declared = true;
                     break;
                 }
@@ -1385,7 +1368,7 @@
                     }
 
                 if (!found) {
-                    StringBuffer enumValueString = new StringBuffer();
+                    StringBuilder enumValueString = new StringBuilder();
                     if (enumVals != null)
                         for (int i = 0; i < enumVals.length; i++) {
                             enumValueString.append(enumVals[i]+" ");
@@ -1509,7 +1492,6 @@
         boolean spaceStart = false;
         boolean readingNonSpace = false;
         int count = 0;
-        int eaten = 0;
         String attrValue = attributes.getValue(index);
         char[] attValue = new char[attrValue.length()];
 
@@ -1530,33 +1512,7 @@
                     fBuffer.append(attValue[i]);
                     count++;
                 }
-                else {
-                    if (leadingSpace || !spaceStart) {
-                        eaten ++;
-                        /*** BUG #3512 ***
-                        int entityCount = attributes.getEntityCount(index);
-                        for (int j = 0;  j < entityCount; j++) {
-                            int offset = attributes.getEntityOffset(index, j);
-                            int length = attributes.getEntityLength(index, j);
-                            if (offset <= i-eaten+1) {
-                                if (offset+length >= i-eaten+1) {
-                                    if (length > 0)
-                                        length--;
-                                }
-                            }
-                            else {
-                                if (offset > 0)
-                                    offset--;
-                            }
-                            attributes.setEntityOffset(index, j, offset);
-                            attributes.setEntityLength(index, j, length);
-                        }
-                        /***/
-                    }
-                }
-
-            }
-            else {
+            } else {
                 readingNonSpace = true;
                 spaceStart = false;
                 leadingSpace = false;
@@ -1568,23 +1524,6 @@
         // check if the last appended character is a space.
         if (count > 0 && fBuffer.charAt(count-1) == ' ') {
             fBuffer.setLength(count-1);
-            /*** BUG #3512 ***
-            int entityCount = attributes.getEntityCount(index);
-            for (int j=0;  j < entityCount; j++) {
-                int offset = attributes.getEntityOffset(index, j);
-                int length = attributes.getEntityLength(index, j);
-                if (offset < count-1) {
-                    if (offset+length == count) {
-                        length--;
-                    }
-                }
-                else {
-                    offset--;
-                }
-                attributes.setEntityOffset(index, j, offset);
-                attributes.setEntityLength(index, j, length);
-            }
-            /***/
         }
         String newValue = fBuffer.toString();
         attributes.setValue(index, newValue);
@@ -1645,9 +1584,6 @@
 
         fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
 
-        // Get the element name index from the element
-        final String elementType = fCurrentElement.rawname;
-
         // Get out the content spec for this element
         final int contentType = fCurrentContentSpecType;
 
@@ -1711,18 +1647,6 @@
 
     } // checkContent(int,int,QName[]):int
 
-    /** Returns the content spec type for an element index. */
-    private int getContentSpecType(int elementIndex) {
-
-        int contentSpecType = -1;
-        if (elementIndex > -1) {
-            if (fDTDGrammar.getElementDecl(elementIndex,fTempElementDecl)) {
-                contentSpecType = fTempElementDecl.type;
-            }
-        }
-        return contentSpecType;
-    }
-
     /** Character data in content. */
     private void charDataInContent() {
 
@@ -1754,7 +1678,11 @@
                 return attrDecl.simpleType.list ? XMLSymbols.fENTITIESSymbol : XMLSymbols.fENTITYSymbol;
             }
         case XMLSimpleType.TYPE_ENUMERATION: {
-                StringBuffer buffer = new StringBuffer();
+                int totalLength = 2;
+                for (int i = 0; i < attrDecl.simpleType.enumeration.length; i++) {
+                    totalLength += attrDecl.simpleType.enumeration[i].length() + 1;
+                }
+                StringBuilder buffer = new StringBuilder(totalLength);
                 buffer.append('(');
                 for (int i=0; i<attrDecl.simpleType.enumeration.length ; i++) {
                     if (i > 0) {
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -528,7 +528,7 @@
         switch (osName) {
             case "Linux":
             case "SunOS":
-                JELFRelocObject elfobj = new JELFRelocObject(this, outputFileName);
+                JELFRelocObject elfobj = JELFRelocObject.newInstance(this, outputFileName);
                 elfobj.createELFRelocObject(relocationTable, symbolTable.values());
                 break;
             case "Mac OS X":
@@ -576,7 +576,7 @@
      * @param info relocation information to be added
      */
     public void addRelocation(Relocation info) {
-        // System.out.println("# Relocation [" + symName + "] [" + info.getOffset() + "] [" +
+        // System.out.println("# Relocation [" + info.getSymbol() + "] [" + info.getOffset() + "] [" +
         // info.getSection().getContainerName() + "] [" + info.getSymbol().getName() + "] [" +
         // info.getSymbol().getOffset() + " @ " + info.getSymbol().getSection().getContainerName() +
         // "]");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AArch64JELFRelocObject.java	Tue May 15 10:13:52 2018 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Red Hat Inc. 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.
+ */
+
+package jdk.tools.jaotc.binformat.elf;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import jdk.tools.jaotc.binformat.BinaryContainer;
+import jdk.tools.jaotc.binformat.ByteContainer;
+import jdk.tools.jaotc.binformat.CodeContainer;
+import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
+import jdk.tools.jaotc.binformat.Relocation;
+import jdk.tools.jaotc.binformat.Relocation.RelocType;
+import jdk.tools.jaotc.binformat.Symbol;
+import jdk.tools.jaotc.binformat.Symbol.Binding;
+import jdk.tools.jaotc.binformat.Symbol.Kind;
+
+import jdk.tools.jaotc.binformat.elf.ElfSymbol;
+import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
+
+
+public class AArch64JELFRelocObject extends JELFRelocObject {
+
+    AArch64JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
+        super(binContainer, outputFileName);
+    }
+
+    void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
+        RelocType relocType = reloc.getType();
+
+        int elfRelocType = getELFRelocationType(relocType);
+        ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
+        int symno = sym.getIndex();
+        int sectindex = reloc.getSection().getSectionId();
+        int offset = reloc.getOffset();
+        int addend = 0;
+
+        switch (relocType) {
+        case STUB_CALL_DIRECT:
+        case JAVA_CALL_DIRECT: {
+            break;
+        }
+        case EXTERNAL_PLT_TO_GOT:
+            offset -= 16;
+            elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
+            elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
+            return;
+
+        case FOREIGN_CALL_INDIRECT_GOT: {
+            break;
+        }
+        case METASPACE_GOT_REFERENCE: {
+            offset -= 4;
+
+            elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
+            elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
+            return;
+        }
+            // break;
+        case JAVA_CALL_INDIRECT: {
+            addend = -4;
+            offset = offset + addend;
+            break;
+        }
+        case EXTERNAL_GOT_TO_PLT: {
+            // this is load time relocations
+            break;
+        }
+        default:
+            throw new InternalError("Unhandled relocation type: " + relocType);
+        }
+
+        elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
+    }
+
+    int getELFRelocationType(RelocType relocType) {
+        int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
+        switch (ElfTargetInfo.getElfArch()) {
+            case Elf64_Ehdr.EM_AARCH64:
+                // Return R_X86_64_* entries based on relocType
+                if (relocType == RelocType.JAVA_CALL_DIRECT ||
+                    relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
+                    elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
+                } else if (relocType == RelocType.STUB_CALL_DIRECT) {
+                    elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
+                } else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
+                    elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
+                } else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
+                           relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
+                    elfRelocType = Elf64_Rela.R_AARCH64_NONE;
+                } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
+                    elfRelocType = Elf64_Rela.R_AARCH64_ABS64;
+                } else {
+                    assert false : "Unhandled relocation type: " + relocType;
+                }
+                break;
+
+            default:
+                System.out.println("Relocation Type mapping: Unhandled architecture: "
+                                   + ElfTargetInfo.getElfArch());
+        }
+        return elfRelocType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AMD64JELFRelocObject.java	Tue May 15 10:13:52 2018 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.tools.jaotc.binformat.elf;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import jdk.tools.jaotc.binformat.BinaryContainer;
+import jdk.tools.jaotc.binformat.ByteContainer;
+import jdk.tools.jaotc.binformat.CodeContainer;
+import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
+import jdk.tools.jaotc.binformat.Relocation;
+import jdk.tools.jaotc.binformat.Relocation.RelocType;
+import jdk.tools.jaotc.binformat.Symbol;
+import jdk.tools.jaotc.binformat.Symbol.Binding;
+import jdk.tools.jaotc.binformat.Symbol.Kind;
+
+import jdk.tools.jaotc.binformat.elf.ElfSymbol;
+import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
+import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
+
+
+public class AMD64JELFRelocObject extends JELFRelocObject {
+
+    AMD64JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
+        super(binContainer, outputFileName);
+    }
+
+    protected void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
+        RelocType relocType = reloc.getType();
+
+        int elfRelocType = getELFRelocationType(relocType);
+        ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
+        int symno = sym.getIndex();
+        int sectindex = reloc.getSection().getSectionId();
+        int offset = reloc.getOffset();
+        int addend = 0;
+
+        switch (relocType) {
+        case JAVA_CALL_DIRECT:
+        case STUB_CALL_DIRECT:
+        case FOREIGN_CALL_INDIRECT_GOT: {
+            // Create relocation entry
+            addend = -4; // Size in bytes of the patch location
+            // Relocation should be applied at the location after call operand
+            offset = offset + reloc.getSize() + addend;
+            break;
+        }
+        case JAVA_CALL_INDIRECT:
+        case METASPACE_GOT_REFERENCE:
+        case EXTERNAL_PLT_TO_GOT: {
+            addend = -4; // Size of 32-bit address of the GOT
+            /*
+             * Relocation should be applied before the test instruction to the move instruction.
+             * reloc.getOffset() points to the test instruction after the instruction that loads the address of
+             * polling page. So set the offset appropriately.
+             */
+            offset = offset + addend;
+            break;
+        }
+        case EXTERNAL_GOT_TO_PLT: {
+            // this is load time relocations
+            break;
+        }
+        default:
+            throw new InternalError("Unhandled relocation type: " + relocType);
+        }
+        elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
+    }
+
+    private int getELFRelocationType(RelocType relocType) {
+        int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
+        switch (ElfTargetInfo.getElfArch()) {
+        case Elf64_Ehdr.EM_X86_64:
+            // Return R_X86_64_* entries based on relocType
+            if (relocType == RelocType.JAVA_CALL_DIRECT ||
+                relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
+                elfRelocType = Elf64_Rela.R_X86_64_PLT32;
+            } else if (relocType == RelocType.STUB_CALL_DIRECT) {
+                elfRelocType = Elf64_Rela.R_X86_64_PC32;
+            } else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
+                elfRelocType = Elf64_Rela.R_X86_64_NONE;
+            } else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
+                       relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
+                elfRelocType = Elf64_Rela.R_X86_64_PC32;
+            } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
+                elfRelocType = Elf64_Rela.R_X86_64_64;
+            } else {
+                assert false : "Unhandled relocation type: " + relocType;
+            }
+            break;
+
+        default:
+            System.out.println("Relocation Type mapping: Unhandled architecture: "
+                               + ElfTargetInfo.getElfArch());
+        }
+        return elfRelocType;
+    }
+}
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/Elf.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/Elf.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -208,12 +209,26 @@
         /**
          * Relocation types
          */
+
         static final int R_X86_64_NONE     = 0x0;
         static final int R_X86_64_64       = 0x1;
         static final int R_X86_64_PC32     = 0x2;
         static final int R_X86_64_PLT32    = 0x4;
         static final int R_X86_64_GOTPCREL = 0x9;
 
+        static final int R_AARCH64_NONE     = 256;
+        static final int R_AARCH64_ABS64    = 257;
+        static final int R_AARCH64_CALL26   = 283;
+        static final int R_AARCH64_ADR_GOT_PAGE = 311;
+        static final int R_AARCH64_LD64_GOT_LO12_NC = 312;
+
+        static final int R_AARCH64_MOVW_UABS_G0_NC = 264;
+        static final int R_AARCH64_MOVW_UABS_G1_NC = 266;
+        static final int R_AARCH64_MOVW_UABS_G2_NC = 268;
+
+        static final int R_AARCH64_ADR_PREL_PG_HI21 = 275;
+        static final int R_AARCH64_ADD_ABS_LO12_NC = 277;
+        static final int R_AARCH64_LDST64_ABS_LO12_NC = 286;
     }
 
     /**
@@ -240,6 +255,20 @@
         static final int R_X86_64_PLT32    = 0x4;
         static final int R_X86_64_GOTPCREL = 0x9;
 
+        static final int R_AARCH64_NONE     = 256;
+        static final int R_AARCH64_ABS64    = 257;
+        static final int R_AARCH64_CALL26   = 283;
+        static final int R_AARCH64_ADR_GOT_PAGE = 311;
+        static final int R_AARCH64_LD64_GOT_LO12_NC = 312;
+
+        static final int R_AARCH64_MOVW_UABS_G0_NC = 264;
+        static final int R_AARCH64_MOVW_UABS_G1_NC = 266;
+        static final int R_AARCH64_MOVW_UABS_G2_NC = 268;
+
+        static final int R_AARCH64_ADR_PREL_PG_HI21 = 275;
+        static final int R_AARCH64_ADD_ABS_LO12_NC = 277;
+        static final int R_AARCH64_LDST64_ABS_LO12_NC = 286;
+
         static long ELF64_R_INFO(int symidx, int type) {
             return (((long)symidx << 32) + type);
         }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfTargetInfo.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfTargetInfo.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -55,6 +55,8 @@
 
         if (archStr.equals("amd64") || archStr.equals("x86_64")) {
             arch = Elf64_Ehdr.EM_X86_64;
+        } else if (archStr.equals("aarch64")) {
+            arch = Elf64_Ehdr.EM_AARCH64;
         } else {
             System.out.println("Unsupported architecture " + archStr);
             arch = Elf64_Ehdr.EM_NONE;
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -46,7 +46,7 @@
 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
 import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
 
-public class JELFRelocObject {
+public abstract class JELFRelocObject {
 
     private final BinaryContainer binContainer;
 
@@ -54,12 +54,22 @@
 
     private final int segmentSize;
 
-    public JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
+    protected JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
         this.binContainer = binContainer;
         this.elfContainer = new ElfContainer(outputFileName);
         this.segmentSize = binContainer.getCodeSegmentSize();
     }
 
+    public static JELFRelocObject newInstance(BinaryContainer binContainer, String outputFileName) {
+        String archStr = System.getProperty("os.arch").toLowerCase();
+        if (archStr.equals("amd64") || archStr.equals("x86_64")) {
+            return new AMD64JELFRelocObject(binContainer, outputFileName);
+        } else  if (archStr.equals("aarch64")) {
+            return new AArch64JELFRelocObject(binContainer, outputFileName);
+        }
+        throw new InternalError("Unsupported platform: " + archStr);
+    }
+
     private static ElfSection createByteSection(ArrayList<ElfSection> sections,
                                                 String sectName,
                                                 byte[] scnData,
@@ -295,75 +305,6 @@
         return (elfRelocTable);
     }
 
-    private static void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
-        RelocType relocType = reloc.getType();
-
-        int elfRelocType = getELFRelocationType(relocType);
-        ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
-        int symno = sym.getIndex();
-        int sectindex = reloc.getSection().getSectionId();
-        int offset = reloc.getOffset();
-        int addend = 0;
-
-        switch (relocType) {
-            case JAVA_CALL_DIRECT:
-            case STUB_CALL_DIRECT:
-            case FOREIGN_CALL_INDIRECT_GOT: {
-                // Create relocation entry
-                addend = -4; // Size in bytes of the patch location
-                // Relocation should be applied at the location after call operand
-                offset = offset + reloc.getSize() + addend;
-                break;
-            }
-            case JAVA_CALL_INDIRECT:
-            case METASPACE_GOT_REFERENCE:
-            case EXTERNAL_PLT_TO_GOT: {
-                addend = -4; // Size of 32-bit address of the GOT
-                /*
-                 * Relocation should be applied before the test instruction to the move instruction.
-                 * reloc.getOffset() points to the test instruction after the instruction that loads the address of
-                 * polling page. So set the offset appropriately.
-                 */
-                offset = offset + addend;
-                break;
-            }
-            case EXTERNAL_GOT_TO_PLT: {
-                // this is load time relocations
-                break;
-            }
-            default:
-                throw new InternalError("Unhandled relocation type: " + relocType);
-        }
-        elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
-    }
-
-    private static int getELFRelocationType(RelocType relocType) {
-        int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
-        switch (ElfTargetInfo.getElfArch()) {
-            case Elf64_Ehdr.EM_X86_64:
-                // Return R_X86_64_* entries based on relocType
-                if (relocType == RelocType.JAVA_CALL_DIRECT ||
-                    relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
-                    elfRelocType = Elf64_Rela.R_X86_64_PLT32;
-                } else if (relocType == RelocType.STUB_CALL_DIRECT) {
-                    elfRelocType = Elf64_Rela.R_X86_64_PC32;
-                } else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
-                    elfRelocType = Elf64_Rela.R_X86_64_NONE;
-                } else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
-                           relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
-                    elfRelocType = Elf64_Rela.R_X86_64_PC32;
-                } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
-                    elfRelocType = Elf64_Rela.R_X86_64_64;
-                } else {
-                    assert false : "Unhandled relocation type: " + relocType;
-                }
-                break;
-            default:
-                System.out.println("Relocation Type mapping: Unhandled architecture");
-        }
-        return elfRelocType;
-    }
-
     private static void createElfRelocSections(ArrayList<ElfSection> sections,
                                                ElfRelocTable elfRelocTable,
                                                int symtabsectidx) {
@@ -383,4 +324,7 @@
             }
         }
     }
+
+    abstract void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable);
+
 }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeSectionProcessor.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeSectionProcessor.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -32,6 +32,8 @@
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
 
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.code.site.Call;
 import jdk.vm.ci.code.site.Infopoint;
@@ -72,7 +74,8 @@
             for (Infopoint infopoint : compResult.getInfopoints()) {
                 if (infopoint.reason == InfopointReason.CALL) {
                     final Call callInfopoint = (Call) infopoint;
-                    if (callInfopoint.target instanceof HotSpotForeignCallLinkage) {
+                    if (callInfopoint.target instanceof HotSpotForeignCallLinkage &&
+                        target.arch instanceof AMD64) {
                         // TODO 4 is x86 size of relative displacement.
                         // For SPARC need something different.
                         int destOffset = infopoint.pcOffset + callInfopoint.size - 4;
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -39,6 +39,8 @@
 
 final class CompiledMethodInfo {
 
+    static final String archStr = System.getProperty("os.arch").toLowerCase();
+
     private static final int UNINITIALIZED_OFFSET = -1;
 
     private static class AOTMethodOffsets {
@@ -304,10 +306,17 @@
 
     boolean hasMark(Site call, MarkId id) {
         for (Mark m : compilationResult.getMarks()) {
-            // TODO: X64-specific code.
-            // Call instructions are aligned to 8
-            // bytes - 1 on x86 to patch address atomically,
-            int adjOffset = (m.pcOffset & (-8)) + 7;
+            int adjOffset = m.pcOffset;
+            if (archStr.equals("aarch64")) {
+                // The mark is at the end of a group of three instructions:
+                // adrp; add; ldr
+                adjOffset += 12;
+            } else {
+                // X64-specific code.
+                // Call instructions are aligned to 8
+                // bytes - 1 on x86 to patch address atomically,
+                adjOffset = (adjOffset & (-8)) + 7;
+            }
             // Mark points before aligning nops.
             if ((call.pcOffset == adjOffset) && MarkId.getEnum((int) m.id) == id) {
                 return true;
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ELFMacroAssembler.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ELFMacroAssembler.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -25,8 +25,10 @@
 
 import jdk.tools.jaotc.StubInformation;
 import jdk.tools.jaotc.amd64.AMD64ELFMacroAssembler;
+import jdk.tools.jaotc.aarch64.AArch64ELFMacroAssembler;
 
 import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.aarch64.AArch64;
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.TargetDescription;
 
@@ -36,6 +38,8 @@
         Architecture architecture = target.arch;
         if (architecture instanceof AMD64) {
             return new AMD64ELFMacroAssembler(target);
+        } else if (architecture instanceof AArch64) {
+            return new AArch64ELFMacroAssembler(target);
         } else {
             throw new InternalError("Unsupported architecture " + architecture);
         }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InstructionDecoder.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InstructionDecoder.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -24,8 +24,10 @@
 package jdk.tools.jaotc;
 
 import jdk.tools.jaotc.amd64.AMD64InstructionDecoder;
+import jdk.tools.jaotc.aarch64.AArch64InstructionDecoder;
 
 import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.aarch64.AArch64;
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.TargetDescription;
 
@@ -35,6 +37,8 @@
         Architecture architecture = target.arch;
         if (architecture instanceof AMD64) {
             return new AMD64InstructionDecoder(target);
+        } else if (architecture instanceof AArch64) {
+            return new AArch64InstructionDecoder(target);
         } else {
             throw new InternalError("Unsupported architecture " + architecture);
         }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -38,7 +38,19 @@
 
     private static final byte[] zeroSlot = new byte[8];
     // -1 represents Universe::non_oop_word() value
-    private static final byte[] minusOneSlot = {-1, -1, -1, -1, -1, -1, -1, -1};
+    private static final byte[] minusOneSlot;
+
+    static {
+        String archStr = System.getProperty("os.arch").toLowerCase();
+        if (archStr.equals("aarch64")) {
+            // AArch64 is a special case: it uses 48-bit addresses.
+            byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, 0, 0};
+            minusOneSlot = non_oop_word;
+        } else {
+            byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, -1, -1};
+            minusOneSlot = non_oop_word;
+        }
+    }
 
     JavaCallSiteRelocationSymbol(CompiledMethodInfo mi, Call call, CallSiteRelocationInfo callSiteRelocation, BinaryContainer binaryContainer) {
         super(createPltEntrySymbol(binaryContainer, mi, call, callSiteRelocation));
@@ -123,6 +135,7 @@
      */
     private static String getResolveSymbolName(CompiledMethodInfo mi, Call call) {
         String resolveSymbolName;
+        String name = call.target.toString();
         if (CallInfo.isStaticCall(call)) {
             assert mi.hasMark(call, MarkId.INVOKESTATIC);
             resolveSymbolName = BinaryContainer.getResolveStaticEntrySymbolName();
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 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
@@ -69,6 +69,7 @@
                 if (name.endsWith(".so")) {
                     objectFileName = name.substring(0, name.length() - ".so".length());
                 }
+                objectFileName = objectFileName + ".o";
                 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
                 linkerCmd = linkerPath + " -shared -z noexecstack -o " + libraryFileName + " " + objectFileName;
                 linkerCheck = linkerPath + " -v";
@@ -130,7 +131,8 @@
             throw new InternalError(errorMessage);
         }
         File objFile = new File(objectFileName);
-        if (objFile.exists()) {
+        boolean keepObjFile = Boolean.parseBoolean(System.getProperty("aot.keep.objFile", "false"));
+        if (objFile.exists() && !keepObjFile) {
             if (!objFile.delete()) {
                 throw new InternalError("Failed to delete " + objectFileName + " file");
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64ELFMacroAssembler.java	Tue May 15 10:13:52 2018 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Red Hat Inc. 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.
+ */
+
+package jdk.tools.jaotc.aarch64;
+
+import jdk.tools.jaotc.StubInformation;
+import jdk.tools.jaotc.ELFMacroAssembler;
+
+import org.graalvm.compiler.asm.aarch64.AArch64Address;
+import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+
+
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.Register;
+
+import static jdk.vm.ci.aarch64.AArch64.*;
+
+public final class AArch64ELFMacroAssembler extends AArch64MacroAssembler implements ELFMacroAssembler {
+
+    private int currentEndOfInstruction;
+
+    public AArch64ELFMacroAssembler(TargetDescription target) {
+        super(target);
+    }
+
+    @Override
+    public int currentEndOfInstruction() {
+        return currentEndOfInstruction;
+    }
+
+    @Override
+    public byte[] getPLTJumpCode() {
+        // The main dispatch instruction
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+
+        currentEndOfInstruction = position();
+
+        align(8);
+
+        return close(true);
+    }
+
+    @Override
+    public byte[] getPLTStaticEntryCode(StubInformation stub) {
+        // The main dispatch instruction
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+        stub.setDispatchJumpOffset(position());
+
+        // C2I stub used to call interpreter.  First load r12
+        // (i.e. rmethod) with a pointer to the Method structure ...
+        addressOf(r12);
+        ldr(64, r12, AArch64Address.createBaseRegisterOnlyAddress(r12));
+        nop();
+        stub.setMovOffset(position());
+
+        // ... then jump to the interpreter.
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+        stub.setC2IJumpOffset(position());
+
+        // Call to VM runtime to resolve the call.
+        stub.setResolveJumpStart(position());
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+        stub.setResolveJumpOffset(position());
+        currentEndOfInstruction = position();
+
+        align(8);
+        stub.setSize(position());
+
+        return close(true);
+    }
+
+    @Override
+    public byte[] getPLTVirtualEntryCode(StubInformation stub) {
+        // Fixup an inline cache.
+        // Load r9 with a pointer to the Klass.
+        addressOf(r17);
+        ldr(64, r9, AArch64Address.createBaseRegisterOnlyAddress(r17));
+        nop();
+        stub.setMovOffset(position());
+
+        // Jump to the method.
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+        stub.setDispatchJumpOffset(position());
+
+        // Call to VM runtime to resolve the call.
+        stub.setResolveJumpStart(position());
+        addressOf(r16);
+        ldr(64, r16, AArch64Address.createBaseRegisterOnlyAddress(r16));
+        jmp(r16);
+        stub.setResolveJumpOffset(position());
+        currentEndOfInstruction = position();
+
+        align(8);
+        stub.setSize(position());
+
+        return close(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64InstructionDecoder.java	Tue May 15 10:13:52 2018 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Red Hat Inc. 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.
+ */
+
+package jdk.tools.jaotc.aarch64;
+
+import jdk.tools.jaotc.InstructionDecoder;
+
+import jdk.vm.ci.code.TargetDescription;
+
+public final class AArch64InstructionDecoder extends InstructionDecoder {
+
+    private int currentEndOfInstruction;
+
+    public AArch64InstructionDecoder(TargetDescription target) {
+    }
+
+    @Override
+    public int currentEndOfInstruction() {
+        return currentEndOfInstruction;
+    }
+
+    @Override
+    public void decodePosition(final byte[] code, int pcOffset) {
+        currentEndOfInstruction = pcOffset + 4;
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 15 10:13:52 2018 -0700
@@ -2705,6 +2705,9 @@
                 Type target = null;
                 for (Type bound : ict.getExplicitComponents()) {
                     TypeSymbol boundSym = bound.tsym;
+                    if (bound.tsym == syms.objectType.tsym) {
+                        continue;
+                    }
                     if (types.isFunctionalInterface(boundSym) &&
                             types.findDescriptorSymbol(boundSym) == desc) {
                         target = bound;
@@ -3032,14 +3035,14 @@
                         targetError = false;
                 }
 
-                JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol()).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
+                JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol())
+                        .getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
                                 that, exprType.tsym, exprType, that.name, argtypes, typeargtypes);
 
-                JCDiagnostic.DiagnosticType diagKind = targetError ?
-                        JCDiagnostic.DiagnosticType.FRAGMENT : JCDiagnostic.DiagnosticType.ERROR;
-
-                JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
-                        "invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
+                JCDiagnostic diag = diags.create(log.currentSource(), that,
+                        targetError ?
+                            Fragments.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag) :
+                            Errors.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag));
 
                 if (targetError && currentTarget == Type.recoveryType) {
                     //a target error doesn't make sense during recovery stage
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue May 15 10:13:52 2018 -0700
@@ -278,7 +278,7 @@
     invalid {0} reference\n\
     {1}
 
-# 0: symbol kind, 1: message segment
+# 0: kind name, 1: message segment
 compiler.misc.invalid.mref=\
     invalid {0} reference\n\
     {1}
@@ -2469,6 +2469,11 @@
     cannot find symbol\n\
     symbol: {0} {1}({3})
 
+# 0: kind name, 1: name, 2: unused, 3: list of type
+compiler.misc.cant.resolve.args=\
+    cannot find symbol\n\
+    symbol: {0} {1}({3})
+
 # 0: kind name, 1: name, 2: list of type, 3: list of type
 compiler.err.cant.resolve.args.params=\
     cannot find symbol\n\
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -563,7 +563,7 @@
       nameAddr = entryAddr.getAddressAt(longConstantEntryNameOffset);
       if (nameAddr != null) {
         String name = CStringUtilities.getString(nameAddr);
-        int value = (int) entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
+        long value = entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
 
         // Be a little resilient
         Long oldValue = lookupLongConstant(name, false);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Tue May 15 18:03:31 2018 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Tue May 15 10:13:52 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -274,9 +274,15 @@
   public static final int _fast_aldc_w          = 231;
   public static final int _return_register_finalizer = 232;
   public static final int _invokehandle         = 233;
-  public static final int _shouldnotreachhere   = 234; // For debugging
 
-  public static final int number_of_codes       = 235;
+  // Bytecodes rewritten at CDS dump time
+  public static final int _nofast_getfield      = 234;
+  public static final int _nofast_putfield      = 235;
+  public static final int _nofast_aload_0       = 236;
+  public static final int _nofast_iload         = 237;