changeset 43592:14c12a5689d3

Merge
author duke
date Wed, 05 Jul 2017 22:48:30 +0200
parents 62824732af55 0cdf61c416d4
children 06bce0388880
files hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionTest.java hotspot/test/compiler/aot/fingerprint/CDSDumper.java hotspot/test/compiler/aot/fingerprint/CDSRunner.java hotspot/test/compiler/aot/fingerprint/SelfChanged.java hotspot/test/compiler/aot/fingerprint/SelfChangedCDS.java hotspot/test/compiler/aot/fingerprint/SuperChanged.java hotspot/test/compiler/c2/cr7200264/Test7200264.sh hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java jaxws/src/java.annotations.common/share/classes/javax/annotation/Generated.java jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java jaxws/src/java.annotations.common/share/classes/javax/annotation/Resource.java jaxws/src/java.annotations.common/share/classes/javax/annotation/Resources.java jaxws/src/java.annotations.common/share/classes/module-info.java jdk/make/copy/Copy-java.management.gmk jdk/make/gensrc/Gensrc-java.management.gmk jdk/make/rmic/Rmic-java.management.gmk jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ProxyRef.java jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/RMIExporter.java jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/Unmarshal.java jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ClientProvider.java jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ServerProvider.java jdk/src/java.management/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnection.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServer.java jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServerImpl.java jdk/src/java.management/share/classes/javax/management/remote/rmi/package.html jdk/src/java.management/share/classes/sun/management/Agent.java jdk/src/java.management/share/classes/sun/management/AgentConfigurationError.java jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java jdk/src/java.management/share/classes/sun/management/FileSystem.java jdk/src/java.management/share/classes/sun/management/jdp/JdpBroadcaster.java jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java jdk/src/java.management/share/classes/sun/management/jdp/JdpException.java jdk/src/java.management/share/classes/sun/management/jdp/JdpGenericPacket.java jdk/src/java.management/share/classes/sun/management/jdp/JdpJmxPacket.java jdk/src/java.management/share/classes/sun/management/jdp/JdpPacket.java jdk/src/java.management/share/classes/sun/management/jdp/JdpPacketReader.java jdk/src/java.management/share/classes/sun/management/jdp/JdpPacketWriter.java jdk/src/java.management/share/classes/sun/management/jdp/package-info.java jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java jdk/src/java.management/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java jdk/src/java.management/share/classes/sun/management/jmxremote/SingleEntryRegistry.java jdk/src/java.management/share/classes/sun/management/jmxremote/package.html jdk/src/java.management/share/classes/sun/management/resources/agent.properties jdk/src/java.management/share/classes/sun/management/resources/agent_de.properties jdk/src/java.management/share/classes/sun/management/resources/agent_es.properties jdk/src/java.management/share/classes/sun/management/resources/agent_fr.properties jdk/src/java.management/share/classes/sun/management/resources/agent_it.properties jdk/src/java.management/share/classes/sun/management/resources/agent_ja.properties jdk/src/java.management/share/classes/sun/management/resources/agent_ko.properties jdk/src/java.management/share/classes/sun/management/resources/agent_pt_BR.properties jdk/src/java.management/share/classes/sun/management/resources/agent_sv.properties jdk/src/java.management/share/classes/sun/management/resources/agent_zh_CN.properties jdk/src/java.management/share/classes/sun/management/resources/agent_zh_TW.properties jdk/src/java.management/share/classes/sun/management/spi/AgentProvider.java jdk/src/java.management/share/conf/jmxremote.access jdk/src/java.management/share/conf/jmxremote.password.template jdk/src/java.management/share/conf/management.properties jdk/src/java.management/share/conf/snmp.acl.template jdk/src/java.management/unix/classes/sun/management/FileSystemImpl.java jdk/src/java.management/unix/native/libmanagement/FileSystemImpl.c jdk/src/java.management/windows/classes/sun/management/FileSystemImpl.java jdk/src/java.management/windows/native/libmanagement/FileSystemImpl.c jdk/src/jdk.jvmstat/share/classes/module-info.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/AbstractMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/BufferedMonitoredVm.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/ByteArrayMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/IntegerMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/LongMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Monitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitorException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVmUtil.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/StringMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Units.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Variability.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/VmIdentifier.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/HostEvent.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/HostListener.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/MonitorStatusChangeEvent.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmEvent.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmListener.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmStatusChangeEvent.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/package.html jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/package.html jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBufferPrologue.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AliasFileParser.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTask.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTaskUtils.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorDataException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorStatus.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorStructureException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorTypeException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorVersionException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfIntegerMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfLongMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringConstantMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringVariableMonitor.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/SyntaxException.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/package.html jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/FileMonitoredVm.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostFileService.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/PerfDataBuffer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/package.html jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalEventTimer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalMonitoredVm.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/MonitoredHostLocalService.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/MonitoredHostProvider.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/BasicType.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBufferPrologue.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBufferPrologue.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/TypeCode.java jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap jdk/test/sun/management/AgentCMETest.java jdk/test/sun/management/AgentCheckTest.java
diffstat 937 files changed, 36272 insertions(+), 29904 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Mon Feb 06 17:19:06 2017 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 22:48:30 2017 +0200
@@ -397,3 +397,4 @@
 ef056360ddf3977d7d2ddbeb456a4d612d19ea05 jdk-9+152
 816a6d03a7c44edfbd8780110529f1bdc3964fb9 jdk-9+153
 8d26916eaa21b689835ffc1c0dbf12470aa9be61 jdk-9+154
+688a3863c00ebc089ab17ee1fc46272cbbd96815 jdk-9+155
--- a/common/autoconf/basics.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/basics.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -746,7 +746,8 @@
     fi
 
     # set SDKROOT too, Xcode tools will pick it up
-    AC_SUBST(SDKROOT,$SYSROOT)
+    SDKROOT="$SYSROOT"
+    AC_SUBST(SDKROOT)
   fi
 
   # Prepend the extra path to the global path
@@ -831,9 +832,10 @@
   CONFIGURESUPPORT_OUTPUTDIR="$OUTPUT_ROOT/configure-support"
   $MKDIR -p "$CONFIGURESUPPORT_OUTPUTDIR"
 
-  AC_SUBST(SPEC, $OUTPUT_ROOT/spec.gmk)
-  AC_SUBST(CONF_NAME, $CONF_NAME)
-  AC_SUBST(OUTPUT_ROOT, $OUTPUT_ROOT)
+  SPEC="$OUTPUT_ROOT/spec.gmk"
+  AC_SUBST(SPEC)
+  AC_SUBST(CONF_NAME)
+  AC_SUBST(OUTPUT_ROOT)
   AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR)
 
   # The spec.gmk file contains all variables for the make system.
--- a/common/autoconf/boot-jdk.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/boot-jdk.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -325,7 +325,6 @@
   fi
   AC_MSG_CHECKING([if Boot JDK is 32 or 64 bits])
   AC_MSG_RESULT([$BOOT_JDK_BITS])
-  AC_SUBST(BOOT_JDK_BITS)
 ])
 
 AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
--- a/common/autoconf/build-performance.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/build-performance.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -224,7 +224,7 @@
         AC_MSG_ERROR([On macosx, ccache 3.2 or later is required, found $CCACHE_VERSION])
       fi
     fi
-    if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+    if test "x$USE_PRECOMPILED_HEADER" = "xtrue"; then
       HAS_BAD_CCACHE=[`$ECHO $CCACHE_VERSION | \
           $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`]
       if test "x$HAS_BAD_CCACHE" != "x"; then
@@ -362,20 +362,20 @@
       [disable using precompiled headers when compiling C++ @<:@enabled@:>@])],
       [ENABLE_PRECOMPH=${enable_precompiled_headers}], [ENABLE_PRECOMPH=yes])
 
-  USE_PRECOMPILED_HEADER=1
+  USE_PRECOMPILED_HEADER=true
   AC_MSG_CHECKING([If precompiled header is enabled])
   if test "x$ENABLE_PRECOMPH" = xno; then
     AC_MSG_RESULT([no, forced])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$ICECC" != "x"; then
     AC_MSG_RESULT([no, does not work effectively with icecc])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     AC_MSG_RESULT([no, does not work with Solaris Studio])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     AC_MSG_RESULT([no, does not work with xlc])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   else
     AC_MSG_RESULT([yes])
   fi
@@ -387,7 +387,7 @@
       echo "int alfa();" > conftest.h
       $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
       if test ! -f conftest.hpp.gch; then
-        USE_PRECOMPILED_HEADER=0
+        USE_PRECOMPILED_HEADER=false
         AC_MSG_RESULT([no])
       else
         AC_MSG_RESULT([yes])
--- a/common/autoconf/flags.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/flags.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -808,7 +808,7 @@
     						 IF_FALSE: [$2CXXSTD_CXXFLAG=""])
     $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2CXXSTD_CXXFLAG}"
     $2JVM_CFLAGS="${$2JVM_CFLAGS} ${$2CXXSTD_CXXFLAG}"
-    AC_SUBST([$2CXXSTD_CXXFLAG])
+    AC_SUBST($2CXXSTD_CXXFLAG)
   fi
   if test "x$OPENJDK_TARGET_OS" = xsolaris; then
     $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
@@ -1440,18 +1440,6 @@
 
 AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
 [
-  # Some Zero and Shark settings.
-  # ZERO_ARCHFLAG tells the compiler which mode to build for
-  case "${OPENJDK_TARGET_CPU}" in
-    s390)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}31"
-      ;;
-    *)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
-  esac
-  FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$ZERO_ARCHFLAG], IF_FALSE: [ZERO_ARCHFLAG=""])
-  AC_SUBST(ZERO_ARCHFLAG)
-
   # Check that the compiler supports -mX (or -qX on AIX) flags
   # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
   FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}],
@@ -1476,15 +1464,7 @@
     AC_MSG_ERROR([--enable-warnings-as-errors accepts no argument])
   fi
 
-  if test "x$WARNINGS_AS_ERRORS" = "xfalse"; then
-    # Set legacy hotspot variable
-    HOTSPOT_SET_WARNINGS_AS_ERRORS="WARNINGS_ARE_ERRORS="
-  else
-    HOTSPOT_SET_WARNINGS_AS_ERRORS=""
-  fi
-
   AC_SUBST(WARNINGS_AS_ERRORS)
-  AC_SUBST(HOTSPOT_SET_WARNINGS_AS_ERRORS)
 
   case "${TOOLCHAIN_TYPE}" in
     microsoft)
--- a/common/autoconf/generated-configure.sh	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 22:48:30 2017 +0200
@@ -704,7 +704,6 @@
 FIXPATH
 BUILD_GTEST
 ENABLE_AOT
-INCLUDE_DTRACE
 GCOV_ENABLED
 ZIP_EXTERNAL_DEBUG_SYMBOLS
 COPY_DEBUG_SYMBOLS
@@ -712,10 +711,8 @@
 CFLAGS_WARNINGS_ARE_ERRORS
 BUILD_CC_DISABLE_WARNING_PREFIX
 DISABLE_WARNING_PREFIX
-HOTSPOT_SET_WARNINGS_AS_ERRORS
 WARNINGS_AS_ERRORS
 COMPILER_SUPPORTS_TARGET_BITS_FLAG
-ZERO_ARCHFLAG
 LDFLAGS_TESTEXE
 LDFLAGS_TESTLIB
 CXXFLAGS_TESTEXE
@@ -884,7 +881,6 @@
 CREATE_BUILDJDK
 JLINK
 JMOD
-BOOT_JDK_BITS
 JAVAC_FLAGS
 BOOT_JDK_MODULAR
 BOOT_JDK_SOURCETARGET
@@ -974,15 +970,12 @@
 ORIGINAL_TOPDIR
 TOPDIR
 PATH_SEP
-ZERO_ARCHDEF
 HOTSPOT_BUILD_CPU_DEFINE
 HOTSPOT_BUILD_CPU_ARCH
 HOTSPOT_BUILD_CPU
 HOTSPOT_BUILD_OS_TYPE
 HOTSPOT_BUILD_OS
 OPENJDK_BUILD_BUNDLE_PLATFORM
-OPENJDK_BUILD_CPU_BUNDLE
-OPENJDK_BUILD_OS_BUNDLE
 OPENJDK_BUILD_OS_EXPORT_DIR
 OPENJDK_BUILD_CPU_OSARCH
 OPENJDK_BUILD_CPU_ISADIR
@@ -994,10 +987,7 @@
 HOTSPOT_TARGET_OS_TYPE
 HOTSPOT_TARGET_OS
 DEFINE_CROSS_COMPILE_ARCH
-LP64
 OPENJDK_TARGET_BUNDLE_PLATFORM
-OPENJDK_TARGET_CPU_BUNDLE
-OPENJDK_TARGET_OS_BUNDLE
 OPENJDK_TARGET_OS_EXPORT_DIR
 OPENJDK_TARGET_CPU_OSARCH
 OPENJDK_TARGET_CPU_ISADIR
@@ -3818,7 +3808,7 @@
 
 # ... then the rest
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -3998,7 +3988,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -4273,7 +4263,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -4561,7 +4551,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -4841,7 +4831,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -5180,7 +5170,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1485508515
+DATE_WHEN_GENERATED=1486175373
 
 ###############################################################################
 #
@@ -15936,18 +15926,14 @@
   OPENJDK_TARGET_BUNDLE_PLATFORM="${OPENJDK_TARGET_OS_BUNDLE}-${OPENJDK_TARGET_CPU_BUNDLE}"
 
 
-
-
   if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
       OPENJDK_TARGET_ADD_LP64="-D_LP64=1"
     fi
   fi
-  LP64=$A_LP64
-
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
@@ -16092,18 +16078,14 @@
   OPENJDK_BUILD_BUNDLE_PLATFORM="${OPENJDK_BUILD_OS_BUNDLE}-${OPENJDK_BUILD_CPU_BUNDLE}"
 
 
-
-
   if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
       OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
     fi
   fi
-  LP64=$A_LP64
-
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
@@ -16173,12 +16155,6 @@
 
 
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code.
-  # This is used in legacy hotspot build.
-  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
-
-
-
 
 
 # Continue setting up basic stuff. Most remaining code require fundamental tools.
@@ -17280,7 +17256,7 @@
     fi
 
     # set SDKROOT too, Xcode tools will pick it up
-    SDKROOT=$SYSROOT
+    SDKROOT="$SYSROOT"
 
   fi
 
@@ -17528,11 +17504,9 @@
   CONFIGURESUPPORT_OUTPUTDIR="$OUTPUT_ROOT/configure-support"
   $MKDIR -p "$CONFIGURESUPPORT_OUTPUTDIR"
 
-  SPEC=$OUTPUT_ROOT/spec.gmk
-
-  CONF_NAME=$CONF_NAME
-
-  OUTPUT_ROOT=$OUTPUT_ROOT
+  SPEC="$OUTPUT_ROOT/spec.gmk"
+
+
 
 
 
@@ -30730,7 +30704,6 @@
 
 
 
-
 # Check whether --with-build-jdk was given.
 if test "${with_build_jdk+set}" = set; then :
   withval=$with_build_jdk;
@@ -51480,282 +51453,6 @@
 
 
 
-  # Some Zero and Shark settings.
-  # ZERO_ARCHFLAG tells the compiler which mode to build for
-  case "${OPENJDK_TARGET_CPU}" in
-    s390)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}31"
-      ;;
-    *)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
-  esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C compiler supports \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if the C compiler supports \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=yes
-
-  saved_cflags="$CFLAGS"
-  CFLAGS="$CFLAGS $ZERO_ARCHFLAG"
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int i;
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  supports=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  CFLAGS="$saved_cflags"
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-    C_COMP_SUPPORTS="yes"
-  else
-    :
-    C_COMP_SUPPORTS="no"
-  fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C++ compiler supports \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if the C++ compiler supports \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=yes
-
-  saved_cxxflags="$CXXFLAGS"
-  CXXFLAGS="$CXXFLAG $ZERO_ARCHFLAG"
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int i;
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
-  supports=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  CXXFLAGS="$saved_cxxflags"
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-    CXX_COMP_SUPPORTS="yes"
-  else
-    :
-    CXX_COMP_SUPPORTS="no"
-  fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if both compilers support \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if both compilers support \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=no
-  if test "x$C_COMP_SUPPORTS" = "xyes" -a "x$CXX_COMP_SUPPORTS" = "xyes"; then supports=yes; fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-
-  else
-    :
-    ZERO_ARCHFLAG=""
-  fi
-
-
-
-
-
-
-
-
   # Check that the compiler supports -mX (or -qX on AIX) flags
   # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
 
@@ -52054,14 +51751,6 @@
     as_fn_error $? "--enable-warnings-as-errors accepts no argument" "$LINENO" 5
   fi
 
-  if test "x$WARNINGS_AS_ERRORS" = "xfalse"; then
-    # Set legacy hotspot variable
-    HOTSPOT_SET_WARNINGS_AS_ERRORS="WARNINGS_ARE_ERRORS="
-  else
-    HOTSPOT_SET_WARNINGS_AS_ERRORS=""
-  fi
-
-
 
 
   case "${TOOLCHAIN_TYPE}" in
@@ -52916,7 +52605,6 @@
   fi
 
 
-
   # Check whether --enable-aot was given.
 if test "${enable_aot+set}" = set; then :
   enableval=$enable_aot;
@@ -63694,12 +63382,14 @@
   DEFAULT_LIBPNG=bundled
   # if user didn't specify, use DEFAULT_LIBPNG
   if test "x${with_libpng}" = "x"; then
-      with_libpng=${DEFAULT_LIBPNG}
+    with_libpng=${DEFAULT_LIBPNG}
   fi
 
   if test "x${with_libpng}" = "xbundled"; then
-      USE_EXTERNAL_LIBPNG=false
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
+    USE_EXTERNAL_LIBPNG=false
+    PNG_CFLAGS=""
+    PNG_LIBS=""
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
 $as_echo "bundled" >&6; }
   elif test "x${with_libpng}" = "xsystem"; then
 
@@ -63759,28 +63449,31 @@
 
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-                 LIBPNG_FOUND=no
+                LIBPNG_FOUND=no
 elif test $pkg_failed = untried; then
-	 LIBPNG_FOUND=no
+	LIBPNG_FOUND=no
 else
 	PNG_CFLAGS=$pkg_cv_PNG_CFLAGS
 	PNG_LIBS=$pkg_cv_PNG_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-	 LIBPNG_FOUND=yes
-fi
-      if test "x${LIBPNG_FOUND}" = "xyes"; then
-          USE_EXTERNAL_LIBPNG=true
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
+	LIBPNG_FOUND=yes
+fi
+    if test "x${LIBPNG_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
+      USE_EXTERNAL_LIBPNG=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
 $as_echo "system" >&6; }
-      else
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
 $as_echo "system not found" >&6; }
-          as_fn_error $? "--with-libpng=system specified, but no libpng found!" "$LINENO" 5
-      fi
-  else
-      as_fn_error $? "Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'" "$LINENO" 5
-  fi
+      as_fn_error $? "--with-libpng=system specified, but no libpng found!" "$LINENO" 5
+    fi
+  else
+    as_fn_error $? "Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'" "$LINENO" 5
+  fi
+
+
 
 
 
@@ -63888,11 +63581,13 @@
   DEFAULT_LCMS=bundled
   # If user didn't specify, use DEFAULT_LCMS
   if test "x${with_lcms}" = "x"; then
-      with_lcms=${DEFAULT_LCMS}
+    with_lcms=${DEFAULT_LCMS}
   fi
 
   if test "x${with_lcms}" = "xbundled"; then
     USE_EXTERNAL_LCMS=false
+    LCMS_CFLAGS=""
+    LCMS_LIBS=""
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
 $as_echo "bundled" >&6; }
   elif test "x${with_lcms}" = "xsystem"; then
@@ -63966,6 +63661,7 @@
 	LCMS_FOUND=yes
 fi
     if test "x${LCMS_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set LCMS_CFLAGS and LCMS_LIBS
       USE_EXTERNAL_LCMS=true
     else
       as_fn_error $? "--with-lcms=system specified, but no lcms found!" "$LINENO" 5
@@ -63984,6 +63680,8 @@
 
 
 
+
+
   # Setup libm (the maths library)
   if test "x$OPENJDK_TARGET_OS" != "xwindows"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
@@ -64768,11 +64466,11 @@
 $as_echo_n "checking if elliptic curve crypto implementation is present... " >&6; }
 
   if test -d "${SRC_ROOT}/jdk/src/jdk.crypto.ec/share/native/libsunec/impl"; then
-    ENABLE_INTREE_EC=yes
+    ENABLE_INTREE_EC=true
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
   else
-    ENABLE_INTREE_EC=no
+    ENABLE_INTREE_EC=false
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
   fi
@@ -66139,25 +65837,25 @@
 fi
 
 
-  USE_PRECOMPILED_HEADER=1
+  USE_PRECOMPILED_HEADER=true
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking If precompiled header is enabled" >&5
 $as_echo_n "checking If precompiled header is enabled... " >&6; }
   if test "x$ENABLE_PRECOMPH" = xno; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
 $as_echo "no, forced" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$ICECC" != "x"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5
 $as_echo "no, does not work effectively with icecc" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with Solaris Studio" >&5
 $as_echo "no, does not work with Solaris Studio" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with xlc" >&5
 $as_echo "no, does not work with xlc" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -66171,7 +65869,7 @@
       echo "int alfa();" > conftest.h
       $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&5 >&5
       if test ! -f conftest.hpp.gch; then
-        USE_PRECOMPILED_HEADER=0
+        USE_PRECOMPILED_HEADER=false
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
       else
@@ -66458,7 +66156,7 @@
         as_fn_error $? "On macosx, ccache 3.2 or later is required, found $CCACHE_VERSION" "$LINENO" 5
       fi
     fi
-    if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+    if test "x$USE_PRECOMPILED_HEADER" = "xtrue"; then
       HAS_BAD_CCACHE=`$ECHO $CCACHE_VERSION | \
           $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`
       if test "x$HAS_BAD_CCACHE" != "x"; then
--- a/common/autoconf/hotspot.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/hotspot.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -189,7 +189,6 @@
   else
     AC_MSG_ERROR([Invalid value for --enable-dtrace: $enable_dtrace])
   fi
-  AC_SUBST(INCLUDE_DTRACE)
 ])
 
 ################################################################################
--- a/common/autoconf/jdk-options.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/jdk-options.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -210,10 +210,10 @@
   AC_MSG_CHECKING([if elliptic curve crypto implementation is present])
 
   if test -d "${SRC_ROOT}/jdk/src/jdk.crypto.ec/share/native/libsunec/impl"; then
-    ENABLE_INTREE_EC=yes
+    ENABLE_INTREE_EC=true
     AC_MSG_RESULT([yes])
   else
-    ENABLE_INTREE_EC=no
+    ENABLE_INTREE_EC=false
     AC_MSG_RESULT([no])
   fi
 
@@ -479,5 +479,5 @@
     AC_MSG_ERROR([Invalid value for --enable-generate-classlist: $enable_generate_classlist])
   fi
 
-  AC_SUBST([ENABLE_GENERATE_CLASSLIST])
+  AC_SUBST(ENABLE_GENERATE_CLASSLIST)
 ])
--- a/common/autoconf/lib-bundled.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/lib-bundled.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -119,28 +119,31 @@
   DEFAULT_LIBPNG=bundled
   # if user didn't specify, use DEFAULT_LIBPNG
   if test "x${with_libpng}" = "x"; then
-      with_libpng=${DEFAULT_LIBPNG}
+    with_libpng=${DEFAULT_LIBPNG}
   fi
 
   if test "x${with_libpng}" = "xbundled"; then
-      USE_EXTERNAL_LIBPNG=false
-      AC_MSG_RESULT([bundled])
+    USE_EXTERNAL_LIBPNG=false
+    PNG_CFLAGS=""
+    PNG_LIBS=""
+    AC_MSG_RESULT([bundled])
   elif test "x${with_libpng}" = "xsystem"; then
-      PKG_CHECK_MODULES(PNG, libpng,
-                   [ LIBPNG_FOUND=yes ],
-                   [ LIBPNG_FOUND=no ])
-      if test "x${LIBPNG_FOUND}" = "xyes"; then
-          USE_EXTERNAL_LIBPNG=true
-          AC_MSG_RESULT([system])
-      else
-          AC_MSG_RESULT([system not found])
-          AC_MSG_ERROR([--with-libpng=system specified, but no libpng found!])
-      fi
+    PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no])
+    if test "x${LIBPNG_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
+      USE_EXTERNAL_LIBPNG=true
+      AC_MSG_RESULT([system])
+    else
+      AC_MSG_RESULT([system not found])
+      AC_MSG_ERROR([--with-libpng=system specified, but no libpng found!])
+    fi
   else
-      AC_MSG_ERROR([Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'])
+    AC_MSG_ERROR([Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'])
   fi
 
   AC_SUBST(USE_EXTERNAL_LIBPNG)
+  AC_SUBST(PNG_CFLAGS)
+  AC_SUBST(PNG_LIBS)
 ])
 
 ################################################################################
@@ -204,16 +207,19 @@
   DEFAULT_LCMS=bundled
   # If user didn't specify, use DEFAULT_LCMS
   if test "x${with_lcms}" = "x"; then
-      with_lcms=${DEFAULT_LCMS}
+    with_lcms=${DEFAULT_LCMS}
   fi
 
   if test "x${with_lcms}" = "xbundled"; then
     USE_EXTERNAL_LCMS=false
+    LCMS_CFLAGS=""
+    LCMS_LIBS=""
     AC_MSG_RESULT([bundled])
   elif test "x${with_lcms}" = "xsystem"; then
     AC_MSG_RESULT([system])
     PKG_CHECK_MODULES([LCMS], [lcms2], [LCMS_FOUND=yes], [LCMS_FOUND=no])
     if test "x${LCMS_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set LCMS_CFLAGS and LCMS_LIBS
       USE_EXTERNAL_LCMS=true
     else
       AC_MSG_ERROR([--with-lcms=system specified, but no lcms found!])
@@ -223,4 +229,6 @@
   fi
 
   AC_SUBST(USE_EXTERNAL_LCMS)
+  AC_SUBST(LCMS_CFLAGS)
+  AC_SUBST(LCMS_LIBS)
 ])
--- a/common/autoconf/platform.m4	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/platform.m4	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -276,12 +276,6 @@
 [
   PLATFORM_SETUP_LEGACY_VARS_HELPER([TARGET])
   PLATFORM_SETUP_LEGACY_VARS_HELPER([BUILD])
-
-  # ZERO_ARCHDEF is used to enable architecture-specific code.
-  # This is used in legacy hotspot build.
-  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
-  AC_SUBST(ZERO_ARCHDEF)
-
 ])
 
 # $1 - Either TARGET or BUILD to setup the variables for.
@@ -360,19 +354,16 @@
     OPENJDK_$1_CPU_BUNDLE="$OPENJDK_$1_CPU"
   fi
   OPENJDK_$1_BUNDLE_PLATFORM="${OPENJDK_$1_OS_BUNDLE}-${OPENJDK_$1_CPU_BUNDLE}"
-  AC_SUBST(OPENJDK_$1_OS_BUNDLE)
-  AC_SUBST(OPENJDK_$1_CPU_BUNDLE)
   AC_SUBST(OPENJDK_$1_BUNDLE_PLATFORM)
 
   if test "x$OPENJDK_$1_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_$1_OS" = xlinux || test "x$OPENJDK_$1_OS" = xmacosx; then
       OPENJDK_$1_ADD_LP64="-D_LP64=1"
     fi
   fi
-  AC_SUBST(LP64,$A_LP64)
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
--- a/common/autoconf/spec.gmk.in	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -87,9 +87,8 @@
 HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
 HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
 
-OPENJDK_TARGET_CPU_BUNDLE:=@OPENJDK_TARGET_CPU_BUNDLE@
-OPENJDK_TARGET_OS_BUNDLE:=@OPENJDK_TARGET_OS_BUNDLE@
 OPENJDK_TARGET_BUNDLE_PLATFORM:=@OPENJDK_TARGET_BUNDLE_PLATFORM@
+JDK_ARCH_ABI_PROP_NAME := @JDK_ARCH_ABI_PROP_NAME@
 
 # We are building on this build system.
 # When not cross-compiling, it is the same as the target.
@@ -683,8 +682,7 @@
 
 # Build setup
 ENABLE_AOT:=@ENABLE_AOT@
-ENABLE_JFR=@ENABLE_JFR@
-ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
+ENABLE_INTREE_EC:=@ENABLE_INTREE_EC@
 USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@
 USE_EXTERNAL_LIBGIF:=@USE_EXTERNAL_LIBGIF@
 USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@
--- a/common/bin/hgforest.sh	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/bin/hgforest.sh	Wed Jul 05 22:48:30 2017 +0200
@@ -309,8 +309,8 @@
 
       echo "serving root repo ${serving}" > ${status_output}
 
-      echo "hg${global_opts} serve" > ${status_output}
-      (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
+      echo "hg${global_opts} serve ${@}" > ${status_output}
+      (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf "${@}"; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
     ) 2>&1 | sed -e "s@^@serve:   @" > ${status_output}
   ) &
 else
--- a/common/bin/unshuffle_list.txt	Mon Feb 06 17:19:06 2017 -0800
+++ b/common/bin/unshuffle_list.txt	Wed Jul 05 22:48:30 2017 +0200
@@ -60,7 +60,7 @@
 jaxws/src/java.activation/share/classes/com/sun/activation/registries : jaxws/src/share/jaf_classes/com/sun/activation/registries
 jaxws/src/java.activation/share/classes/javax/activation : jaxws/src/share/jaf_classes/javax/activation
 jaxws/src/java.activation/share/classes/META-INF : jaxws/src/share/jaf_classes/META-INF
-jaxws/src/java.annotations.common/share/classes/javax/annotation : jaxws/src/share/jaxws_classes/javax/annotation
+jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation : jaxws/src/share/jaxws_classes/javax/annotation
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal : jaxws/src/share/jaxws_classes/com/sun/istack/internal
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal/localization : jaxws/src/share/jaxws_classes/com/sun/istack/internal/localization
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal/logging/Logger.java : jaxws/src/share/jaxws_classes/com/sun/istack/internal/logging/Logger.java
@@ -1163,9 +1163,6 @@
 jdk/src/java.management/share/classes/sun/management/counter : jdk/src/share/classes/sun/management/counter
 jdk/src/java.management/share/classes/sun/management/counter/perf : jdk/src/share/classes/sun/management/counter/perf
 jdk/src/java.management/share/classes/sun/management : jdk/src/share/classes/sun/management
-jdk/src/java.management/share/classes/sun/management/jdp : jdk/src/share/classes/sun/management/jdp
-jdk/src/java.management/share/classes/sun/management/jmxremote : jdk/src/share/classes/sun/management/jmxremote
-jdk/src/java.management/share/classes/sun/management/resources : jdk/src/share/classes/sun/management/resources
 jdk/src/java.management/share/conf : jdk/src/share/lib/management
 jdk/src/java.management/share/native/include/jmm.h : jdk/src/share/javavm/export/jmm.h
 jdk/src/java.management/share/native/libmanagement : jdk/src/share/native/sun/management
@@ -1173,6 +1170,11 @@
 jdk/src/java.management/unix/native/libmanagement : jdk/src/solaris/native/sun/management
 jdk/src/java.management/windows/classes/sun/management : jdk/src/windows/classes/sun/management
 jdk/src/java.management/windows/native/libmanagement : jdk/src/windows/native/sun/management
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/ProxyRef.java : jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java : jdk/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/Unmarshal.java : jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/protocol/rmi : jdk/src/share/classes/com/sun/jmx/remote/protocol/rmi
+jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi : jdk/src/share/classes/javax/management/remote/rmi
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext : jdk/src/share/classes/com/sun/jndi/ldap/ext
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap : jdk/src/share/classes/com/sun/jndi/ldap
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap/pool : jdk/src/share/classes/com/sun/jndi/ldap/pool
@@ -1330,9 +1332,9 @@
 jdk/src/jdk.jdwp.agent/unix/native/libjdwp : jdk/src/solaris/back
 jdk/src/jdk.jdwp.agent/windows/native/libdt_socket : jdk/src/windows/transport/socket
 jdk/src/jdk.jdwp.agent/windows/native/libjdwp : jdk/src/windows/back
-jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor : jdk/src/share/classes/sun/jvmstat/monitor
-jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata : jdk/src/share/classes/sun/jvmstat/perfdata
-jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd : jdk/src/share/classes/sun/tools/jstatd
+jdk/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor : jdk/src/share/classes/sun/jvmstat/monitor
+jdk/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata : jdk/src/share/classes/sun/jvmstat/perfdata
+jdk/src/jdk.internal.jvmstat/share/classes/sun/tools/jstatd : jdk/src/share/classes/sun/tools/jstatd
 jdk/src/jdk.localedata/share/classes/sun/text/resources/ar : jdk/src/share/classes/sun/text/resources/ar
 jdk/src/jdk.localedata/share/classes/sun/text/resources/be : jdk/src/share/classes/sun/text/resources/be
 jdk/src/jdk.localedata/share/classes/sun/text/resources/bg : jdk/src/share/classes/sun/text/resources/bg
@@ -1421,6 +1423,9 @@
 jdk/src/jdk.localedata/share/classes/sun/util/resources/vi : jdk/src/share/classes/sun/util/resources/vi
 jdk/src/jdk.localedata/share/classes/sun/util/resources/zh : jdk/src/share/classes/sun/util/resources/zh
 jdk/src/jdk.management/share/classes/com/sun/management : jdk/src/share/classes/com/sun/management
+jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources : jdk/src/share/classes/sun/management/resources
+jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote : jdk/src/share/classes/sun/management/jmxremote
+jdk/src/jdk.management.agent/share/classes/sun/management/jdp : jdk/src/share/classes/sun/management/jdp
 jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns : jdk/src/share/classes/com/sun/jndi/dns
 jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/url/dns : jdk/src/share/classes/com/sun/jndi/url/dns
 jdk/src/jdk.naming.dns/share/classes/META-INF/services : jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services
--- a/corba/.hgtags	Mon Feb 06 17:19:06 2017 -0800
+++ b/corba/.hgtags	Wed Jul 05 22:48:30 2017 +0200
@@ -397,3 +397,4 @@
 ff8cb43c07c069b1debdee44cb88ca22db1ec757 jdk-9+152
 68a8e8658511093b322a46ed04b2a321e1da2a43 jdk-9+153
 078ebe23b584466dc8346e620d7821d91751e5a9 jdk-9+154
+a545f54babfa31aa7eb611f36031609acd617cbc jdk-9+155
--- a/hotspot/.hgtags	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 22:48:30 2017 +0200
@@ -557,3 +557,4 @@
 31f1d26c60df7b2e516a4f84160d76ba017d4e09 jdk-9+152
 217ba81b9a4ce8698200370175aa2db86a39f66c jdk-9+153
 a9fdfd55835ef9dccb7f317b07249bd66653b874 jdk-9+154
+f3b3d77a1751897413aae43ac340a130b6fa2ae1 jdk-9+155
--- a/hotspot/make/ide/CreateVSProject.gmk	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/make/ide/CreateVSProject.gmk	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 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
@@ -121,7 +121,7 @@
       -buildBase $(call FixPath, $(IDE_OUTPUTDIR)/vs-output) \
       -buildSpace $(call FixPath, $(IDE_OUTPUTDIR)) \
       -makeBinary $(call FixPath, $(MAKE)) \
-      -makeOutput $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-%f/libjvm) \
+      -makeOutput $(call FixPath, $(JDK_OUTPUTDIR)/bin/server) \
       -absoluteInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
       -absoluteSrcInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
       $(EXTRACTED_DEFINES_client) \
--- a/hotspot/make/lib/CompileJvm.gmk	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/make/lib/CompileJvm.gmk	Wed Jul 05 22:48:30 2017 +0200
@@ -63,7 +63,7 @@
 # INCLUDE_SUFFIX_* is only meant for including the proper
 # platform files. Don't use it to guard code. Use the value of
 # HOTSPOT_TARGET_CPU_DEFINE etc. instead.
-# Remaining TARGET_ARCH_* is needed to select the cpu specific 
+# Remaining TARGET_ARCH_* is needed to select the cpu specific
 # sources for 64-bit ARM ports (arm versus aarch64).
 JVM_CFLAGS_TARGET_DEFINES += \
     -DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
@@ -132,7 +132,7 @@
     #
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
-ifeq ($(USE_PRECOMPILED_HEADER), 0)
+ifeq ($(USE_PRECOMPILED_HEADER), false)
   JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
 endif
 
@@ -145,7 +145,7 @@
   JVM_EXCLUDE_PATTERNS += arm_64
 
 else ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), linux-aarch64)
-  # For 64-bit arm builds, we use the 64 bit hotspot/src/cpu/arm 
+  # For 64-bit arm builds, we use the 64 bit hotspot/src/cpu/arm
   # hotspot sources if HOTSPOT_TARGET_CPU_ARCH is set to arm.
   # Exclude the aarch64 and 32 bit arm files for this build.
   ifeq ($(HOTSPOT_TARGET_CPU_ARCH), arm)
--- a/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,8 +114,8 @@
             tag(cfg, "CodeAnalysisRuleAssemblies");
         }
         for (BuildConfig cfg : allConfigs) {
-            tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile import-hotspot LOG=info");
-            tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot import-hotspot LOG=info");
+            tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile hotspot LOG=info");
+            tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot hotspot LOG=info");
             tagData(cfg, "NMakeCleanCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot LOG=info");
             tagData(cfg, "NMakeOutput", cfg.get("MakeOutput") + Util.sep + "jvm.dll");
             tagData(cfg, "NMakePreprocessorDefinitions", Util.join(";", cfg.getDefines()));
--- a/hotspot/make/symbols/symbols-unix	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/make/symbols/symbols-unix	Wed Jul 05 22:48:30 2017 +0200
@@ -192,4 +192,3 @@
 JVM_AddReadsModule
 JVM_DefineModule
 JVM_SetBootLoaderUnnamedModule
-JVM_GetModuleByPackageName
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Wed Jul 05 22:48:30 2017 +0200
@@ -1042,8 +1042,10 @@
   bool is_card_mark_membar(const MemBarNode *barrier);
   bool is_CAS(int opcode);
 
-  MemBarNode *leading_to_trailing(MemBarNode *leading);
-  MemBarNode *card_mark_to_leading(const MemBarNode *barrier);
+  MemBarNode *leading_to_normal(MemBarNode *leading);
+  MemBarNode *normal_to_leading(const MemBarNode *barrier);
+  MemBarNode *card_mark_to_trailing(const MemBarNode *barrier);
+  MemBarNode *trailing_to_card_mark(const MemBarNode *trailing);
   MemBarNode *trailing_to_leading(const MemBarNode *trailing);
 
   // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
@@ -1420,28 +1422,23 @@
   // leading MemBarRelease and a trailing MemBarVolatile as follows
   //
   //   MemBarRelease
-  //  {    ||        } -- optional
+  //  {      ||      } -- optional
   //  {MemBarCPUOrder}
-  //       ||       \\
-  //       ||     StoreX[mo_release]
-  //       | \ Bot    / ???
-  //       | MergeMem
-  //       | /
+  //         ||     \\
+  //         ||     StoreX[mo_release]
+  //         | \     /
+  //         | MergeMem
+  //         | /
   //   MemBarVolatile
   //
   // where
   //  || and \\ represent Ctl and Mem feeds via Proj nodes
   //  | \ and / indicate further routing of the Ctl and Mem feeds
   //
-  // Note that the memory feed from the CPUOrder membar to the
-  // MergeMem node is an AliasIdxBot slice while the feed from the
-  // StoreX is for a slice determined by the type of value being
-  // written.
-  //
-  // the diagram above shows the graph we see for non-object stores.
-  // for a volatile Object store (StoreN/P) we may see other nodes
-  // below the leading membar because of the need for a GC pre- or
-  // post-write barrier.
+  // this is the graph we see for non-object stores. however, for a
+  // volatile Object store (StoreN/P) we may see other nodes below the
+  // leading membar because of the need for a GC pre- or post-write
+  // barrier.
   //
   // with most GC configurations we with see this simple variant which
   // includes a post-write barrier card mark.
@@ -1449,7 +1446,7 @@
   //   MemBarRelease______________________________
   //         ||    \\               Ctl \        \\
   //         ||    StoreN/P[mo_release] CastP2X  StoreB/CM
-  //         | \ Bot  / oop                 . . .  /
+  //         | \     /                       . . .  /
   //         | MergeMem
   //         | /
   //         ||      /
@@ -1459,142 +1456,152 @@
   // the object address to an int used to compute the card offset) and
   // Ctl+Mem to a StoreB node (which does the actual card mark).
   //
-  // n.b. a StoreCM node is only ever used when CMS (with or without
-  // CondCardMark) or G1 is configured. This abstract instruction
-  // differs from a normal card mark write (StoreB) because it implies
-  // a requirement to order visibility of the card mark (StoreCM)
-  // after that of the object put (StoreP/N) using a StoreStore memory
-  // barrier. Note that this is /not/ a requirement to order the
-  // instructions in the generated code (that is already guaranteed by
-  // the order of memory dependencies). Rather it is a requirement to
-  // ensure visibility order which only applies on architectures like
-  // AArch64 which do not implement TSO. This ordering is required for
-  // both non-volatile and volatile puts.
-  //
-  // That implies that we need to translate a StoreCM using the
-  // sequence
+  // n.b. a StoreCM node will only appear in this configuration when
+  // using CMS. StoreCM differs from a normal card mark write (StoreB)
+  // because it implies a requirement to order visibility of the card
+  // mark (StoreCM) relative to the object put (StoreP/N) using a
+  // StoreStore memory barrier (arguably this ought to be represented
+  // explicitly in the ideal graph but that is not how it works). This
+  // ordering is required for both non-volatile and volatile
+  // puts. Normally that means we need to translate a StoreCM using
+  // the sequence
   //
   //   dmb ishst
   //   stlrb
   //
-  // This dmb cannot be omitted even when the associated StoreX or
-  // CompareAndSwapX is implemented using stlr. However, as described
-  // below there are circumstances where a specific GC configuration
-  // requires a stronger barrier in which case it can be omitted.
-  // 
-  // With the Serial or Parallel GC using +CondCardMark the card mark
-  // is performed conditionally on it currently being unmarked in
-  // which case the volatile put graph looks slightly different
+  // However, in the case of a volatile put if we can recognise this
+  // configuration and plant an stlr for the object write then we can
+  // omit the dmb and just plant an strb since visibility of the stlr
+  // is ordered before visibility of subsequent stores. StoreCM nodes
+  // also arise when using G1 or using CMS with conditional card
+  // marking. In these cases (as we shall see) we don't need to insert
+  // the dmb when translating StoreCM because there is already an
+  // intervening StoreLoad barrier between it and the StoreP/N.
+  //
+  // It is also possible to perform the card mark conditionally on it
+  // currently being unmarked in which case the volatile put graph
+  // will look slightly different
   //
   //   MemBarRelease____________________________________________
   //         ||    \\               Ctl \     Ctl \     \\  Mem \
   //         ||    StoreN/P[mo_release] CastP2X   If   LoadB     |
-  //         | \ Bot / oop                          \            |
+  //         | \     /                              \            |
   //         | MergeMem                            . . .      StoreB
   //         | /                                                /
   //         ||     /
   //   MemBarVolatile
   //
-  // It is worth noting at this stage that all the above
+  // It is worth noting at this stage that both the above
   // configurations can be uniquely identified by checking that the
   // memory flow includes the following subgraph:
   //
   //   MemBarRelease
   //  {MemBarCPUOrder}
-  //      |  \      . . .
-  //      |  StoreX[mo_release]  . . .
-  //  Bot |   / oop
-  //     MergeMem
-  //      |
+  //          |  \      . . .
+  //          |  StoreX[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
   //   MemBarVolatile
   //
-  // This is referred to as a *normal* volatile store subgraph. It can
-  // easily be detected starting from any candidate MemBarRelease,
-  // StoreX[mo_release] or MemBarVolatile node.
-  //
-  // A small variation on this normal case occurs for an unsafe CAS
-  // operation. The basic memory flow subgraph for a non-object CAS is
-  // as follows
+  // This is referred to as a *normal* subgraph. It can easily be
+  // detected starting from any candidate MemBarRelease,
+  // StoreX[mo_release] or MemBarVolatile.
+  //
+  // A simple variation on this normal case occurs for an unsafe CAS
+  // operation. The basic graph for a non-object CAS is
   //
   //   MemBarRelease
   //         ||
   //   MemBarCPUOrder
-  //          |     \\   . . .
-  //          |     CompareAndSwapX
-  //          |       |
-  //      Bot |     SCMemProj
-  //           \     / Bot
-  //           MergeMem
-  //           /
+  //         ||     \\   . . .
+  //         ||     CompareAndSwapX
+  //         ||       |
+  //         ||     SCMemProj
+  //         | \     /
+  //         | MergeMem
+  //         | /
   //   MemBarCPUOrder
   //         ||
   //   MemBarAcquire
   //
   // The same basic variations on this arrangement (mutatis mutandis)
-  // occur when a card mark is introduced. i.e. the CPUOrder MemBar
-  // feeds the extra CastP2X, LoadB etc nodes but the above memory
-  // flow subgraph is still present.
-  // 
-  // This is referred to as a *normal* CAS subgraph. It can easily be
-  // detected starting from any candidate MemBarRelease,
-  // StoreX[mo_release] or MemBarAcquire node.
-  //
-  // The code below uses two helper predicates, leading_to_trailing
-  // and trailing_to_leading to identify these normal graphs, one
-  // validating the layout starting from the top membar and searching
-  // down and the other validating the layout starting from the lower
-  // membar and searching up.
-  //
-  // There are two special case GC configurations when the simple
-  // normal graphs above may not be generated: when using G1 (which
-  // always employs a conditional card mark); and when using CMS with
-  // conditional card marking (+CondCardMark) configured. These GCs
-  // are both concurrent rather than stop-the world GCs. So they
-  // introduce extra Ctl+Mem flow into the graph between the leading
-  // and trailing membar nodes, in particular enforcing stronger
-  // memory serialisation beween the object put and the corresponding
-  // conditional card mark. CMS employs a post-write GC barrier while
-  // G1 employs both a pre- and post-write GC barrier.
-  //
-  // The post-write barrier subgraph for these configurations includes
-  // a MemBarVolatile node -- referred to as a card mark membar --
-  // which is needed to order the card write (StoreCM) operation in
-  // the barrier, the preceding StoreX (or CompareAndSwapX) and Store
-  // operations performed by GC threads i.e. a card mark membar
-  // constitutes a StoreLoad barrier hence must be translated to a dmb
-  // ish (whether or not it sits inside a volatile store sequence).
-  //
-  // Of course, the use of the dmb ish for the card mark membar also
-  // implies theat the StoreCM which follows can omit the dmb ishst
-  // instruction. The necessary visibility ordering will already be
-  // guaranteed by the dmb ish. In sum, the dmb ishst instruction only
-  // needs to be generated for as part of the StoreCM sequence with GC
-  // configuration +CMS -CondCardMark.
-  // 
-  // Of course all these extra barrier nodes may well be absent --
-  // they are only inserted for object puts. Their potential presence
-  // significantly complicates the task of identifying whether a
-  // MemBarRelease, StoreX[mo_release], MemBarVolatile or
-  // MemBarAcquire forms part of a volatile put or CAS when using
-  // these GC configurations (see below) and also complicates the
-  // decision as to how to translate a MemBarVolatile and StoreCM.
-  //
-  // So, thjis means that a card mark MemBarVolatile occurring in the
-  // post-barrier graph it needs to be distinguished from a normal
-  // trailing MemBarVolatile. Resolving this is straightforward: a
-  // card mark MemBarVolatile always projects a Mem feed to a StoreCM
-  // node and that is a unique marker
+  // occur when a card mark is introduced. i.e. we se the same basic
+  // shape but the StoreP/N is replaced with CompareAndSawpP/N and the
+  // tail of the graph is a pair comprising a MemBarCPUOrder +
+  // MemBarAcquire.
+  //
+  // So, in the case of a CAS the normal graph has the variant form
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder
+  //          |   \      . . .
+  //          |  CompareAndSwapX  . . .
+  //          |    |
+  //          |   SCMemProj
+  //          |   /  . . .
+  //         MergeMem
+  //          |
+  //   MemBarCPUOrder
+  //   MemBarAcquire
+  //
+  // This graph can also easily be detected starting from any
+  // candidate MemBarRelease, CompareAndSwapX or MemBarAcquire.
+  //
+  // the code below uses two helper predicates, leading_to_normal and
+  // normal_to_leading to identify these normal graphs, one validating
+  // the layout starting from the top membar and searching down and
+  // the other validating the layout starting from the lower membar
+  // and searching up.
+  //
+  // There are two special case GC configurations when a normal graph
+  // may not be generated: when using G1 (which always employs a
+  // conditional card mark); and when using CMS with conditional card
+  // marking configured. These GCs are both concurrent rather than
+  // stop-the world GCs. So they introduce extra Ctl+Mem flow into the
+  // graph between the leading and trailing membar nodes, in
+  // particular enforcing stronger memory serialisation beween the
+  // object put and the corresponding conditional card mark. CMS
+  // employs a post-write GC barrier while G1 employs both a pre- and
+  // post-write GC barrier. Of course the extra nodes may be absent --
+  // they are only inserted for object puts. This significantly
+  // complicates the task of identifying whether a MemBarRelease,
+  // StoreX[mo_release] or MemBarVolatile forms part of a volatile put
+  // when using these GC configurations (see below). It adds similar
+  // complexity to the task of identifying whether a MemBarRelease,
+  // CompareAndSwapX or MemBarAcquire forms part of a CAS.
+  //
+  // In both cases the post-write subtree includes an auxiliary
+  // MemBarVolatile (StoreLoad barrier) separating the object put and
+  // the read of the corresponding card. This poses two additional
+  // problems.
+  //
+  // Firstly, a card mark MemBarVolatile needs to be distinguished
+  // from a normal trailing MemBarVolatile. Resolving this first
+  // problem is straightforward: a card mark MemBarVolatile always
+  // projects a Mem feed to a StoreCM node and that is a unique marker
   //
   //      MemBarVolatile (card mark)
   //       C |    \     . . .
   //         |   StoreCM   . . .
   //       . . .
   //
-  // Returning to the task of translating the object put and the
-  // leading/trailing membar nodes: what do the node graphs look like
-  // for these 2 special cases? and how can we determine the status of
-  // a MemBarRelease, StoreX[mo_release] or MemBarVolatile in both
-  // normal and non-normal cases?
+  // The second problem is how the code generator is to translate the
+  // card mark barrier? It always needs to be translated to a "dmb
+  // ish" instruction whether or not it occurs as part of a volatile
+  // put. A StoreLoad barrier is needed after the object put to ensure
+  // i) visibility to GC threads of the object put and ii) visibility
+  // to the mutator thread of any card clearing write by a GC
+  // thread. Clearly a normal store (str) will not guarantee this
+  // ordering but neither will a releasing store (stlr). The latter
+  // guarantees that the object put is visible but does not guarantee
+  // that writes by other threads have also been observed.
+  //
+  // So, returning to the task of translating the object put and the
+  // leading/trailing membar nodes: what do the non-normal node graph
+  // look like for these 2 special cases? and how can we determine the
+  // status of a MemBarRelease, StoreX[mo_release] or MemBarVolatile
+  // in both normal and non-normal cases?
   //
   // A CMS GC post-barrier wraps its card write (StoreCM) inside an If
   // which selects conditonal execution based on the value loaded
@@ -1605,117 +1612,91 @@
   // which looks like this
   //
   //   MemBarRelease
-  //   MemBarCPUOrder_(leading)____________________
-  //     C |  | M \       \\               M |   C \
-  //       |  |    \    StoreN/P[mo_release] |  CastP2X
-  //       |  | Bot \    / oop      \        |
-  //       |  |    MergeMem          \      / 
-  //       |  |      /                |    /
-  //     MemBarVolatile (card mark)   |   /
-  //     C |  ||    M |               |  /
-  //       | LoadB    | Bot       oop | / Bot
-  //       |   |      |              / /
-  //       | Cmp      |\            / /
-  //       | /        | \          / /
-  //       If         |  \        / /
-  //       | \        |   \      / /
-  // IfFalse  IfTrue  |    \    / /
-  //       \     / \  |    |   / /
-  //        \   / StoreCM  |  / /
-  //         \ /      \   /  / /
-  //        Region     Phi  / /
-  //          | \   Raw |  / /
-  //          |  . . .  | / /
+  //   MemBarCPUOrder_(leading)__________________
+  //     C |    M \       \\                   C \
+  //       |       \    StoreN/P[mo_release]  CastP2X
+  //       |    Bot \    /
+  //       |       MergeMem
+  //       |         /
+  //      MemBarVolatile (card mark)
+  //     C |  ||    M |
+  //       | LoadB    |
+  //       |   |      |
+  //       | Cmp      |\
+  //       | /        | \
+  //       If         |  \
+  //       | \        |   \
+  // IfFalse  IfTrue  |    \
+  //       \     / \  |     \
+  //        \   / StoreCM    |
+  //         \ /      |      |
+  //        Region   . . .   |
+  //          | \           /
+  //          |  . . .  \  / Bot
   //          |       MergeMem
-  //          |           |
+  //          |          |
   //        MemBarVolatile (trailing)
   //
-  // Notice that there are two MergeMem nodes below the leading
-  // membar. The first MergeMem merges the AliasIdxBot Mem slice from
-  // the leading membar and the oopptr Mem slice from the Store into
-  // the card mark membar. The trailing MergeMem merges the
-  // AliasIdxBot Mem slice from the leading membar, the AliasIdxRaw
-  // slice from the StoreCM and an oop slice from the StoreN/P node
-  // into the trailing membar (n.b. the raw slice proceeds via a Phi
-  // associated with the If region).
-  //
-  // So, in the case of CMS + CondCardMark the volatile object store
-  // graph still includes a normal volatile store subgraph from the
-  // leading membar to the trailing membar. However, it also contains
-  // the same shape memory flow to the card mark membar. The two flows
-  // can be distinguished by testing whether or not the downstream
-  // membar is a card mark membar.
-  //
-  // The graph for a CAS also varies with CMS + CondCardMark, in
-  // particular employing a control feed from the CompareAndSwapX node
-  // through a CmpI and If to the card mark membar and StoreCM which
-  // updates the associated card. This avoids executing the card mark
-  // if the CAS fails. However, it can be seen from the diagram below
-  // that the presence of the barrier does not alter the normal CAS
-  // memory subgraph where the leading membar feeds a CompareAndSwapX,
-  // an SCMemProj, a MergeMem then a final trailing MemBarCPUOrder and
-  // MemBarAcquire pair.
+  // The first MergeMem merges the AliasIdxBot Mem slice from the
+  // leading membar and the oopptr Mem slice from the Store into the
+  // card mark membar. The trailing MergeMem merges the AliasIdxBot
+  // Mem slice from the card mark membar and the AliasIdxRaw slice
+  // from the StoreCM into the trailing membar (n.b. the latter
+  // proceeds via a Phi associated with the If region).
+  //
+  // The graph for a CAS varies slightly, the obvious difference being
+  // that the StoreN/P node is replaced by a CompareAndSwapP/N node
+  // and the trailing MemBarVolatile by a MemBarCPUOrder +
+  // MemBarAcquire pair. The other important difference is that the
+  // CompareAndSwap node's SCMemProj is not merged into the card mark
+  // membar - it still feeds the trailing MergeMem. This also means
+  // that the card mark membar receives its Mem feed directly from the
+  // leading membar rather than via a MergeMem.
   //
   //   MemBarRelease
-  //   MemBarCPUOrder__(leading)_______________________
-  //   C /  M |                        \\            C \
-  //  . . .   | Bot                CompareAndSwapN/P   CastP2X
-  //          |                  C /  M |
-  //          |                 CmpI    |
-  //          |                  /      |
-  //          |               . . .     |
-  //          |              IfTrue     |
-  //          |              /          |
-  //       MemBarVolatile (card mark)   |
-  //        C |  ||    M |              |
-  //          | LoadB    | Bot   ______/|
-  //          |   |      |      /       |
-  //          | Cmp      |     /      SCMemProj
-  //          | /        |    /         |
-  //          If         |   /         /
-  //          | \        |  /         / Bot
-  //     IfFalse  IfTrue | /         /
-  //          |   / \   / / prec    /
-  //   . . .  |  /  StoreCM        /
-  //        \ | /      | raw      /
-  //        Region    . . .      /
-  //           | \              /
-  //           |   . . .   \    / Bot
-  //           |        MergeMem
-  //           |          /
-  //         MemBarCPUOrder
-  //         MemBarAcquire (trailing)
+  //   MemBarCPUOrder__(leading)_________________________
+  //       ||                       \\                 C \
+  //   MemBarVolatile (card mark)  CompareAndSwapN/P  CastP2X
+  //     C |  ||    M |              |
+  //       | LoadB    |       ______/|
+  //       |   |      |      /       |
+  //       | Cmp      |     /      SCMemProj
+  //       | /        |    /         |
+  //       If         |   /         /
+  //       | \        |  /         /
+  // IfFalse  IfTrue  | /         /
+  //       \     / \  |/ prec    /
+  //        \   / StoreCM       /
+  //         \ /      |        /
+  //        Region   . . .    /
+  //          | \            /
+  //          |  . . .  \   / Bot
+  //          |       MergeMem
+  //          |          |
+  //        MemBarCPUOrder
+  //        MemBarAcquire (trailing)
   //
   // This has a slightly different memory subgraph to the one seen
-  // previously but the core of it has a similar memory flow to the
-  // CAS normal subgraph:
+  // previously but the core of it is the same as for the CAS normal
+  // sungraph
   //
   //   MemBarRelease
   //   MemBarCPUOrder____
-  //         |          \      . . .
-  //         |       CompareAndSwapX  . . .
-  //         |       C /  M |
-  //         |      CmpI    |
-  //         |       /      |
-  //         |      . .    /
-  //     Bot |   IfTrue   /
-  //         |   /       /
-  //    MemBarVolatile  /
-  //         | ...     /
-  //      StoreCM ... /
-  //         |       / 
-  //       . . .  SCMemProj
-  //      Raw \    / Bot
-  //        MergeMem
-  //           |
+  //      ||             \      . . .
+  //   MemBarVolatile  CompareAndSwapX  . . .
+  //      |  \            |
+  //        . . .   SCMemProj
+  //          |     /  . . .
+  //         MergeMem
+  //          |
   //   MemBarCPUOrder
   //   MemBarAcquire
   //
-  // The G1 graph for a volatile object put is a lot more complicated.
-  // Nodes inserted on behalf of G1 may comprise: a pre-write graph
-  // which adds the old value to the SATB queue; the releasing store
-  // itself; and, finally, a post-write graph which performs a card
-  // mark.
+  //
+  // G1 is quite a lot more complicated. The nodes inserted on behalf
+  // of G1 may comprise: a pre-write graph which adds the old value to
+  // the SATB queue; the releasing store itself; and, finally, a
+  // post-write graph which performs a card mark.
   //
   // The pre-write graph may be omitted, but only when the put is
   // writing to a newly allocated (young gen) object and then only if
@@ -1753,60 +1734,25 @@
   //       | CastP2X | StoreN/P[mo_release] |
   //       |         |         |            |
   //     C |       M |       M |          M |
-  //        \        | Raw     | oop       / Bot
+  //        \        |         |           /
   //                  . . .
   //          (post write subtree elided)
   //                    . . .
   //             C \         M /
   //         MemBarVolatile (trailing)
   //
-  // Note that the three memory feeds into the post-write tree are an
-  // AliasRawIdx slice associated with the writes in the pre-write
-  // tree, an oop type slice from the StoreX specific to the type of
-  // the volatile field and the AliasBotIdx slice emanating from the
-  // leading membar.
-  //
   // n.b. the LoadB in this subgraph is not the card read -- it's a
   // read of the SATB queue active flag.
   //
-  // The CAS graph is once again a variant of the above with a
-  // CompareAndSwapX node and SCMemProj in place of the StoreX.  The
-  // value from the CompareAndSwapX node is fed into the post-write
-  // graph aling with the AliasIdxRaw feed from the pre-barrier and
-  // the AliasIdxBot feeds from the leading membar and the ScMemProj.
-  //
-  //  MemBarRelease (leading)____________
-  //     C |  ||  M \   M \    M \  M \ . . .
-  //       | LoadB   \  LoadL  LoadN   \
-  //       | /        \                 \
-  //       If         |\                 \
-  //       | \        | \                 \
-  //  IfFalse  IfTrue |  \                 \
-  //       |     |    |   \                 \
-  //       |     If   |    \                 |
-  //       |     |          \                |
-  //       |                 \               |
-  //       |    . . .         \              |
-  //       | /       | /       \             |
-  //      Region  Phi[M]        \            |
-  //       | \       |           \           |
-  //       |  \_____ |            |          |
-  //     C | C \     |            |          |
-  //       | CastP2X |     CompareAndSwapX   |
-  //       |         |   res |     |         |
-  //     C |       M |       |  SCMemProj  M |
-  //        \        | Raw   |     | Bot    / Bot
-  //                  . . .
-  //          (post write subtree elided)
-  //                    . . .
-  //             C \         M /
-  //         MemBarVolatile (trailing)
+  // Once again the CAS graph is a minor variant on the above with the
+  // expected substitutions of CompareAndSawpX for StoreN/P and
+  // MemBarCPUOrder + MemBarAcquire for trailing MemBarVolatile.
   //
   // The G1 post-write subtree is also optional, this time when the
   // new value being written is either null or can be identified as a
   // newly allocated (young gen) object with no intervening control
   // flow. The latter cannot happen but the former may, in which case
-  // the card mark membar is omitted and the memory feeds from the
+  // the card mark membar is omitted and the memory feeds form the
   // leading membar and the SToreN/P are merged direct into the
   // trailing membar as per the normal subgraph. So, the only special
   // case which arises is when the post-write subgraph is generated.
@@ -1828,106 +1774,94 @@
   //
   //                (pre-write subtree elided)
   //        . . .                  . . .    . . .  . . .
-  //        C |               M |    M |    M |
-  //       Region            Phi[M] StoreN    |
-  //          |            Raw  |  oop |  Bot |
-  //         / \_______         |\     |\     |\
-  //      C / C \      . . .    | \    | \    | \
-  //       If   CastP2X . . .   |  \   |  \   |  \
-  //       / \                  |   \  |   \  |   \
-  //      /   \                 |    \ |    \ |    \
-  // IfFalse IfTrue             |      |      |     \
-  //   |       |                 \     |     /       |
-  //   |       If                 \    | \  /   \    |
-  //   |      / \                  \   |   /     \   |
-  //   |     /   \                  \  |  / \     |  |
-  //   | IfFalse IfTrue           MergeMem   \    |  |
-  //   |  . . .    / \                 |      \   |  |
-  //   |          /   \                |       |  |  |
-  //   |     IfFalse IfTrue            |       |  |  |
-  //   |      . . .    |               |       |  |  |
-  //   |               If             /        |  |  |
-  //   |               / \           /         |  |  |
-  //   |              /   \         /          |  |  |
-  //   |         IfFalse IfTrue    /           |  |  |
-  //   |           . . .   |      /            |  |  |
-  //   |                    \    /             |  |  |
-  //   |                     \  /              |  |  |
-  //   |         MemBarVolatile__(card mark  ) |  |  |
-  //   |              ||   C |     \           |  |  |
-  //   |             LoadB   If     |         /   |  |
-  //   |                    / \ Raw |        /   /  /
-  //   |                   . . .    |       /   /  /
-  //   |                        \   |      /   /  /
-  //   |                        StoreCM   /   /  /
-  //   |                           |     /   /  /
-  //   |                            . . .   /  /
-  //   |                                   /  /
-  //   |   . . .                          /  /
-  //   |    |             | /            /  /
-  //   |    |           Phi[M] /        /  /
-  //   |    |             |   /        /  /
-  //   |    |             |  /        /  /
-  //   |  Region  . . .  Phi[M]      /  /
-  //   |    |             |         /  /
-  //    \   |             |        /  /
-  //     \  | . . .       |       /  /
-  //      \ |             |      /  /
-  //      Region         Phi[M] /  /
-  //        |               \  /  /
-  //         \             MergeMem
-  //          \            /
-  //          MemBarVolatile
-  //
-  // As with CMS + CondCardMark the first MergeMem merges the
-  // AliasIdxBot Mem slice from the leading membar and the oopptr Mem
-  // slice from the Store into the card mark membar. However, in this
-  // case it may also merge an AliasRawIdx mem slice from the pre
-  // barrier write.
-  //
-  // The trailing MergeMem merges an AliasIdxBot Mem slice from the
-  // leading membar with an oop slice from the StoreN and an
-  // AliasRawIdx slice from the post barrier writes. In this case the
-  // AliasIdxRaw Mem slice is merged through a series of Phi nodes
-  // which combine feeds from the If regions in the post barrier
-  // subgraph.
-  //
-  // So, for G1 the same characteristic subgraph arises as for CMS +
-  // CondCardMark. There is a normal subgraph feeding the card mark
-  // membar and a normal subgraph feeding the trailing membar.
-  //
-  // The CAS graph when using G1GC also includes an optional
-  // post-write subgraph. It is very similar to the above graph except
-  // for a few details.
-  // 
-  // - The control flow is gated by an additonal If which tests the
-  // result from the CompareAndSwapX node
-  // 
-  //  - The MergeMem which feeds the card mark membar only merges the
-  // AliasIdxBot slice from the leading membar and the AliasIdxRaw
-  // slice from the pre-barrier. It does not merge the SCMemProj
-  // AliasIdxBot slice. So, this subgraph does not look like the
-  // normal CAS subgraph.
-  //
-  // - The MergeMem which feeds the trailing membar merges the
-  // AliasIdxBot slice from the leading membar, the AliasIdxRaw slice
-  // from the post-barrier and the SCMemProj AliasIdxBot slice i.e. it
-  // has two AliasIdxBot input slices. However, this subgraph does
-  // still look like the normal CAS subgraph.
-  //
-  // So, the upshot is:
-  //
-  // In all cases a volatile put graph will include a *normal*
-  // volatile store subgraph betwen the leading membar and the
-  // trailing membar. It may also include a normal volatile store
-  // subgraph betwen the leading membar and the card mark membar.
-  //
-  // In all cases a CAS graph will contain a unique normal CAS graph
-  // feeding the trailing membar.
-  //
-  // In all cases where there is a card mark membar (either as part of
-  // a volatile object put or CAS) it will be fed by a MergeMem whose
-  // AliasIdxBot slice feed will be a leading membar.
+  //        C |                    M |     M |    M |
+  //       Region                  Phi[M] StoreN    |
+  //          |                     / \      |      |
+  //         / \_______            /   \     |      |
+  //      C / C \      . . .            \    |      |
+  //       If   CastP2X . . .            |   |      |
+  //       / \                           |   |      |
+  //      /   \                          |   |      |
+  // IfFalse IfTrue                      |   |      |
+  //   |       |                         |   |     /|
+  //   |       If                        |   |    / |
+  //   |      / \                        |   |   /  |
+  //   |     /   \                        \  |  /   |
+  //   | IfFalse IfTrue                   MergeMem  |
+  //   |  . . .    / \                       /      |
+  //   |          /   \                     /       |
+  //   |     IfFalse IfTrue                /        |
+  //   |      . . .    |                  /         |
+  //   |               If                /          |
+  //   |               / \              /           |
+  //   |              /   \            /            |
+  //   |         IfFalse IfTrue       /             |
+  //   |           . . .   |         /              |
+  //   |                    \       /               |
+  //   |                     \     /                |
+  //   |             MemBarVolatile__(card mark)    |
+  //   |                ||   C |  M \  M \          |
+  //   |               LoadB   If    |    |         |
+  //   |                      / \    |    |         |
+  //   |                     . . .   |    |         |
+  //   |                          \  |    |        /
+  //   |                        StoreCM   |       /
+  //   |                          . . .   |      /
+  //   |                        _________/      /
+  //   |                       /  _____________/
+  //   |   . . .       . . .  |  /            /
+  //   |    |                 | /   _________/
+  //   |    |               Phi[M] /        /
+  //   |    |                 |   /        /
+  //   |    |                 |  /        /
+  //   |  Region  . . .     Phi[M]  _____/
+  //   |    /                 |    /
+  //   |                      |   /
+  //   | . . .   . . .        |  /
+  //   | /                    | /
+  // Region           |  |  Phi[M]
+  //   |              |  |  / Bot
+  //    \            MergeMem
+  //     \            /
+  //     MemBarVolatile
+  //
+  // As with CMS the initial MergeMem merges the AliasIdxBot Mem slice
+  // from the leading membar and the oopptr Mem slice from the Store
+  // into the card mark membar i.e. the memory flow to the card mark
+  // membar still looks like a normal graph.
+  //
+  // The trailing MergeMem merges an AliasIdxBot Mem slice with other
+  // Mem slices (from the StoreCM and other card mark queue stores).
+  // However in this case the AliasIdxBot Mem slice does not come
+  // direct from the card mark membar. It is merged through a series
+  // of Phi nodes. These are needed to merge the AliasIdxBot Mem flow
+  // from the leading membar with the Mem feed from the card mark
+  // membar. Each Phi corresponds to one of the Ifs which may skip
+  // around the card mark membar. So when the If implementing the NULL
+  // value check has been elided the total number of Phis is 2
+  // otherwise it is 3.
+  //
+  // The CAS graph when using G1GC also includes a pre-write subgraph
+  // and an optional post-write subgraph. Teh sam evarioations are
+  // introduced as for CMS with conditional card marking i.e. the
+  // StoreP/N is swapped for a CompareAndSwapP/N, the tariling
+  // MemBarVolatile for a MemBarCPUOrder + MemBarAcquire pair and the
+  // Mem feed from the CompareAndSwapP/N includes a precedence
+  // dependency feed to the StoreCM and a feed via an SCMemProj to the
+  // trailing membar. So, as before the configuration includes the
+  // normal CAS graph as a subgraph of the memory flow.
+  //
+  // So, the upshot is that in all cases the volatile put graph will
+  // include a *normal* memory subgraph betwen the leading membar and
+  // its child membar, either a volatile put graph (including a
+  // releasing StoreX) or a CAS graph (including a CompareAndSwapX).
+  // When that child is not a card mark membar then it marks the end
+  // of the volatile put or CAS subgraph. If the child is a card mark
+  // membar then the normal subgraph will form part of a volatile put
+  // subgraph if and only if the child feeds an AliasIdxBot Mem feed
+  // to a trailing barrier via a MergeMem. That feed is either direct
+  // (for CMS) or via 2 or 3 Phi nodes merging the leading barrier
+  // memory flow (for G1).
   //
   // The predicates controlling generation of instructions for store
   // and barrier nodes employ a few simple helper functions (described
@@ -1971,24 +1905,24 @@
   }
 
 
-  // leading_to_trailing
+  // leading_to_normal
   //
   //graph traversal helper which detects the normal case Mem feed from
   // a release membar (or, optionally, its cpuorder child) to a
   // dependent volatile membar i.e. it ensures that one or other of
   // the following Mem flow subgraph is present.
   //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
-  //     Bot |  \      . . .
-  //         |  StoreN/P[mo_release]  . . .
-  //         |   /
-  //        MergeMem
-  //         |
-  //   MemBarVolatile {not card mark}
-  //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //          |  \      . . .
+  //          |  StoreN/P[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
+  //   MemBarVolatile {trailing or card mark}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
   //      |       \      . . .
   //      |     CompareAndSwapX  . . .
   //               |
@@ -1999,23 +1933,6 @@
   //    MemBarCPUOrder
   //    MemBarAcquire {trailing}
   //
-  // the predicate needs to be capable of distinguishing the following
-  // volatile put graph which may arises when a GC post barrier
-  // inserts a card mark membar
-  //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder}__
-  //     Bot |   \       \
-  //         |   StoreN/P \
-  //         |    / \     |
-  //        MergeMem \    |
-  //         |        \   |
-  //   MemBarVolatile  \  |
-  //    {card mark}     \ |
-  //                  MergeMem
-  //                      |
-  // {not card mark} MemBarVolatile
-  //
   // if the correct configuration is present returns the trailing
   // membar otherwise NULL.
   //
@@ -2026,7 +1943,7 @@
   // the returned value may be a card mark or trailing membar
   //
 
-  MemBarNode *leading_to_trailing(MemBarNode *leading)
+  MemBarNode *leading_to_normal(MemBarNode *leading)
   {
     assert((leading->Opcode() == Op_MemBarRelease ||
 	    leading->Opcode() == Op_MemBarCPUOrder),
@@ -2043,21 +1960,15 @@
     StoreNode * st = NULL;
     LoadStoreNode *cas = NULL;
     MergeMemNode *mm = NULL;
-    MergeMemNode *mm2 = NULL;
 
     for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
       x = mem->fast_out(i);
       if (x->is_MergeMem()) {
 	if (mm != NULL) {
-	  if (mm2 != NULL) {
-	  // should not see more than 2 merge mems
-	    return NULL;
-	  } else {
-	    mm2 = x->as_MergeMem();
-	  }
-	} else {
-	  mm = x->as_MergeMem();
+	  return NULL;
 	}
+	// two merge mems is one too many
+	mm = x->as_MergeMem();
       } else if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) {
 	// two releasing stores/CAS nodes is one too many
 	if (st != NULL || cas != NULL) {
@@ -2077,13 +1988,13 @@
       return NULL;
     }
 
-    // must have at least one merge if we also have st
+    // must have a merge if we also have st
     if (st && !mm) {
       return NULL;
     }
 
+    Node *y = NULL;
     if (cas) {
-      Node *y = NULL;
       // look for an SCMemProj
       for (DUIterator_Fast imax, i = cas->fast_outs(imax); i < imax; i++) {
 	x = cas->fast_out(i);
@@ -2103,29 +2014,10 @@
 	  break;
 	}
       }
-      if (mm == NULL) {
+      if (mm == NULL)
 	return NULL;
-      }
-      MemBarNode *mbar = NULL;
-      // ensure the merge feeds a trailing membar cpuorder + acquire pair
-      for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
-	x = mm->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarCPUOrder) {
-	    MemBarNode *z =  x->as_MemBar();
-	    z = child_membar(z);
-	    if (z != NULL && z->Opcode() == Op_MemBarAcquire) {
-	      mbar = z;
-	    }
-	  }
-	  break;
-	}
-      }
-      return mbar;
     } else {
-      Node *y = NULL;
-      // ensure the store feeds the first mergemem;
+      // ensure the store feeds the existing mergemem;
       for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
 	if (st->fast_out(i) == mm) {
 	  y = st;
@@ -2135,89 +2027,55 @@
       if (y == NULL) {
 	return NULL;
       }
-      if (mm2 != NULL) {
-	// ensure the store feeds the second mergemem;
-	y = NULL;
-	for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
-	  if (st->fast_out(i) == mm2) {
-	    y = st;
+    }
+
+    MemBarNode *mbar = NULL;
+    // ensure the merge feeds to the expected type of membar
+    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
+      x = mm->fast_out(i);
+      if (x->is_MemBar()) {
+	int opcode = x->Opcode();
+	if (opcode == Op_MemBarVolatile && st) {
+	  mbar = x->as_MemBar();
+	} else if (cas && opcode == Op_MemBarCPUOrder) {
+	  MemBarNode *y =  x->as_MemBar();
+	  y = child_membar(y);
+	  if (y != NULL && y->Opcode() == Op_MemBarAcquire) {
+	    mbar = y;
 	  }
 	}
-	if (y == NULL) {
-	  return NULL;
-	}
+	break;
       }
-
-      MemBarNode *mbar = NULL;
-      // ensure the first mergemem feeds a volatile membar
-      for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
-	x = mm->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarVolatile) {
-	    mbar = x->as_MemBar();
-	  }
-	  break;
-	}
-      }
-      if (mm2 == NULL) {
-	// this is our only option for a trailing membar
-	return mbar;
-      }
-      // ensure the second mergemem feeds a volatile membar
-      MemBarNode *mbar2 = NULL;
-      for (DUIterator_Fast imax, i = mm2->fast_outs(imax); i < imax; i++) {
-	x = mm2->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarVolatile) {
-	    mbar2 = x->as_MemBar();
-	  }
-	  break;
-	}
-      }
-      // if we have two merge mems we must have two volatile membars
-      if (mbar == NULL || mbar2 == NULL) {
-	return NULL;
-      }
-      // return the trailing membar
-      if (is_card_mark_membar(mbar2)) {
-	return mbar;
-      } else {
-	if (is_card_mark_membar(mbar)) {
-	  return mbar2;
-	} else {
-	  return NULL;
-	}
-      }
-    }
-  }
-
-  // trailing_to_leading
+    }
+
+    return mbar;
+  }
+
+  // normal_to_leading
   //
   // graph traversal helper which detects the normal case Mem feed
-  // from a trailing membar to a preceding release membar (optionally
-  // its cpuorder child) i.e. it ensures that one or other of the
-  // following Mem flow subgraphs is present.
-  //
-  //   MemBarRelease {leading}
-  //   MemBarCPUOrder {optional}
-  //    | Bot |  \      . . .
-  //    |     |  StoreN/P[mo_release]  . . .
-  //    |     |   /
-  //    |    MergeMem
-  //    |     |
-  //   MemBarVolatile {not card mark}
-  //
-  //   MemBarRelease {leading}
-  //   MemBarCPUOrder {optional}
+  // from either a card mark or a trailing membar to a preceding
+  // release membar (optionally its cpuorder child) i.e. it ensures
+  // that one or other of the following Mem flow subgraphs is present.
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //          |  \      . . .
+  //          |  StoreN/P[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
+  //   MemBarVolatile {card mark or trailing}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
   //      |       \      . . .
   //      |     CompareAndSwapX  . . .
   //               |
   //     . . .    SCMemProj
   //           \   |
   //      |    MergeMem
-  //      |       |
+  //      |        /
   //    MemBarCPUOrder
   //    MemBarAcquire {trailing}
   //
@@ -2227,20 +2085,15 @@
   // if the configuration is present returns the cpuorder member for
   // preference or when absent the release membar otherwise NULL.
   //
-  // n.b. the input membar is expected to be a MemBarVolatile or
-  // MemBarAcquire. if it is a MemBarVolatile it must *not* be a card
-  // mark membar.
-
-  MemBarNode *trailing_to_leading(const MemBarNode *barrier)
+  // n.b. the input membar is expected to be a MemBarVolatile but
+  // need not be a card mark membar.
+
+  MemBarNode *normal_to_leading(const MemBarNode *barrier)
   {
     // input must be a volatile membar
     assert((barrier->Opcode() == Op_MemBarVolatile ||
 	    barrier->Opcode() == Op_MemBarAcquire),
 	   "expecting a volatile or an acquire membar");
-
-    assert((barrier->Opcode() != Op_MemBarVolatile) ||
-	   !is_card_mark_membar(barrier),
-	   "not expecting a card mark membar");
     Node *x;
     bool is_cas = barrier->Opcode() == Op_MemBarAcquire;
 
@@ -2353,35 +2206,169 @@
     return NULL;
   }
 
-  // card_mark_to_leading
-  //
-  // graph traversal helper which traverses from a card mark volatile
-  // membar to a leading membar i.e. it ensures that the following Mem
-  // flow subgraph is present.
-  //
-  //    MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
-  //         |   . . .
+  // card_mark_to_trailing
+  //
+  // graph traversal helper which detects extra, non-normal Mem feed
+  // from a card mark volatile membar to a trailing membar i.e. it
+  // ensures that one of the following three GC post-write Mem flow
+  // subgraphs is present.
+  //
+  // 1)
+  //     . . .
+  //       |
+  //   MemBarVolatile (card mark)
+  //      |          |
+  //      |        StoreCM
+  //      |          |
+  //      |        . . .
+  //  Bot |  /
+  //   MergeMem
+  //      |
+  //      |
+  //    MemBarVolatile {trailing}
+  //
+  // 2)
+  //   MemBarRelease/CPUOrder (leading)
+  //    |
+  //    |
+  //    |\       . . .
+  //    | \        |
+  //    |  \  MemBarVolatile (card mark)
+  //    |   \   |     |
+  //     \   \  |   StoreCM    . . .
+  //      \   \ |
+  //       \  Phi
+  //        \ /
+  //        Phi  . . .
   //     Bot |   /
-  //      MergeMem
+  //       MergeMem
   //         |
-  //     MemBarVolatile (card mark)
-  //        |     \
-  //      . . .   StoreCM
-  //
-  // if the configuration is present returns the cpuorder member for
-  // preference or when absent the release membar otherwise NULL.
-  //
-  // n.b. the input membar is expected to be a MemBarVolatile amd must
-  // be a card mark membar.
-
-  MemBarNode *card_mark_to_leading(const MemBarNode *barrier)
+  //    MemBarVolatile {trailing}
+  //
+  //
+  // 3)
+  //   MemBarRelease/CPUOrder (leading)
+  //    |
+  //    |\
+  //    | \
+  //    |  \      . . .
+  //    |   \       |
+  //    |\   \  MemBarVolatile (card mark)
+  //    | \   \   |     |
+  //    |  \   \  |   StoreCM    . . .
+  //    |   \   \ |
+  //     \   \  Phi
+  //      \   \ /
+  //       \  Phi
+  //        \ /
+  //        Phi  . . .
+  //     Bot |   /
+  //       MergeMem
+  //         |
+  //         |
+  //    MemBarVolatile {trailing}
+  //
+  // configuration 1 is only valid if UseConcMarkSweepGC &&
+  // UseCondCardMark
+  //
+  // configurations 2 and 3 are only valid if UseG1GC.
+  //
+  // if a valid configuration is present returns the trailing membar
+  // otherwise NULL.
+  //
+  // n.b. the supplied membar is expected to be a card mark
+  // MemBarVolatile i.e. the caller must ensure the input node has the
+  // correct operand and feeds Mem to a StoreCM node
+
+  MemBarNode *card_mark_to_trailing(const MemBarNode *barrier)
   {
     // input must be a card mark volatile membar
     assert(is_card_mark_membar(barrier), "expecting a card mark membar");
 
+    Node *feed = barrier->proj_out(TypeFunc::Memory);
+    Node *x;
+    MergeMemNode *mm = NULL;
+
+    const int MAX_PHIS = 3;	// max phis we will search through
+    int phicount = 0; 		// current search count
+
+    bool retry_feed = true;
+    while (retry_feed) {
+      // see if we have a direct MergeMem feed
+      for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) {
+	x = feed->fast_out(i);
+	// the correct Phi will be merging a Bot memory slice
+	if (x->is_MergeMem()) {
+	  mm = x->as_MergeMem();
+	  break;
+	}
+      }
+      if (mm) {
+	retry_feed = false;
+      } else if (UseG1GC & phicount++ < MAX_PHIS) {
+	// the barrier may feed indirectly via one or two Phi nodes
+	PhiNode *phi = NULL;
+	for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) {
+	  x = feed->fast_out(i);
+	  // the correct Phi will be merging a Bot memory slice
+	  if (x->is_Phi() && x->adr_type() == TypePtr::BOTTOM) {
+	    phi = x->as_Phi();
+	    break;
+	  }
+	}
+	if (!phi) {
+	  return NULL;
+	}
+	// look for another merge below this phi
+	feed = phi;
+      } else {
+	// couldn't find a merge
+	return NULL;
+      }
+    }
+
+    // sanity check this feed turns up as the expected slice
+    assert(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge");
+
+    MemBarNode *trailing = NULL;
+    // be sure we have a trailing membar the merge
+    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
+      x = mm->fast_out(i);
+      if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) {
+	trailing = x->as_MemBar();
+	break;
+      }
+    }
+
+    return trailing;
+  }
+
+  // trailing_to_card_mark
+  //
+  // graph traversal helper which detects extra, non-normal Mem feed
+  // from a trailing volatile membar to a preceding card mark volatile
+  // membar i.e. it identifies whether one of the three possible extra
+  // GC post-write Mem flow subgraphs is present
+  //
+  // this predicate checks for the same flow as the previous predicate
+  // but starting from the bottom rather than the top.
+  //
+  // if the configuration is present returns the card mark membar
+  // otherwise NULL
+  //
+  // n.b. the supplied membar is expected to be a trailing
+  // MemBarVolatile i.e. the caller must ensure the input node has the
+  // correct opcode
+
+  MemBarNode *trailing_to_card_mark(const MemBarNode *trailing)
+  {
+    assert(trailing->Opcode() == Op_MemBarVolatile,
+	   "expecting a volatile membar");
+    assert(!is_card_mark_membar(trailing),
+	   "not expecting a card mark membar");
+
     // the Mem feed to the membar should be a merge
-    Node *x = barrier->in(TypeFunc::Memory);
+    Node *x = trailing->in(TypeFunc::Memory);
     if (!x->is_MergeMem()) {
       return NULL;
     }
@@ -2389,19 +2376,117 @@
     MergeMemNode *mm = x->as_MergeMem();
 
     x = mm->in(Compile::AliasIdxBot);
-
+    // with G1 we may possibly see a Phi or two before we see a Memory
+    // Proj from the card mark membar
+
+    const int MAX_PHIS = 3;	// max phis we will search through
+    int phicount = 0; 		// current search count
+
+    bool retry_feed = !x->is_Proj();
+
+    while (retry_feed) {
+      if (UseG1GC && x->is_Phi() && phicount++ < MAX_PHIS) {
+	PhiNode *phi = x->as_Phi();
+	ProjNode *proj = NULL;
+	PhiNode *nextphi = NULL;
+	bool found_leading = false;
+	for (uint i = 1; i < phi->req(); i++) {
+	  x = phi->in(i);
+	  if (x->is_Phi()) {
+	    nextphi = x->as_Phi();
+	  } else if (x->is_Proj()) {
+	    int opcode = x->in(0)->Opcode();
+	    if (opcode == Op_MemBarVolatile) {
+	      proj = x->as_Proj();
+	    } else if (opcode == Op_MemBarRelease ||
+		       opcode == Op_MemBarCPUOrder) {
+	      // probably a leading membar
+	      found_leading = true;
+	    }
+	  }
+	}
+	// if we found a correct looking proj then retry from there
+	// otherwise we must see a leading and a phi or this the
+	// wrong config
+	if (proj != NULL) {
+	  x = proj;
+	  retry_feed = false;
+	} else if (found_leading && nextphi != NULL) {
+	  // retry from this phi to check phi2
+	  x = nextphi;
+	} else {
+	  // not what we were looking for
+	  return NULL;
+	}
+      } else {
+	return NULL;
+      }
+    }
+    // the proj has to come from the card mark membar
+    x = x->in(0);
     if (!x->is_MemBar()) {
       return NULL;
     }
 
-    MemBarNode *leading = x->as_MemBar();
-
-    if (leading_membar(leading)) {
+    MemBarNode *card_mark_membar = x->as_MemBar();
+
+    if (!is_card_mark_membar(card_mark_membar)) {
+      return NULL;
+    }
+
+    return card_mark_membar;
+  }
+
+  // trailing_to_leading
+  //
+  // graph traversal helper which checks the Mem flow up the graph
+  // from a (non-card mark) trailing membar attempting to locate and
+  // return an associated leading membar. it first looks for a
+  // subgraph in the normal configuration (relying on helper
+  // normal_to_leading). failing that it then looks for one of the
+  // possible post-write card mark subgraphs linking the trailing node
+  // to a the card mark membar (relying on helper
+  // trailing_to_card_mark), and then checks that the card mark membar
+  // is fed by a leading membar (once again relying on auxiliary
+  // predicate normal_to_leading).
+  //
+  // if the configuration is valid returns the cpuorder member for
+  // preference or when absent the release membar otherwise NULL.
+  //
+  // n.b. the input membar is expected to be either a volatile or
+  // acquire membar but in the former case must *not* be a card mark
+  // membar.
+
+  MemBarNode *trailing_to_leading(const MemBarNode *trailing)
+  {
+    assert((trailing->Opcode() == Op_MemBarAcquire ||
+	    trailing->Opcode() == Op_MemBarVolatile),
+	   "expecting an acquire or volatile membar");
+    assert((trailing->Opcode() != Op_MemBarVolatile ||
+	    !is_card_mark_membar(trailing)),
+	   "not expecting a card mark membar");
+
+    MemBarNode *leading = normal_to_leading(trailing);
+
+    if (leading) {
       return leading;
     }
 
-    return NULL;
-  }
+    // nothing more to do if this is an acquire
+    if (trailing->Opcode() == Op_MemBarAcquire) {
+      return NULL;
+    }
+
+    MemBarNode *card_mark_membar = trailing_to_card_mark(trailing);
+
+    if (!card_mark_membar) {
+      return NULL;
+    }
+
+    return normal_to_leading(card_mark_membar);
+  }
+
+  // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
 
 bool unnecessary_acquire(const Node *barrier)
 {
@@ -2617,8 +2702,19 @@
   }
 
   // must start with a normal feed
-  MemBarNode *trailing = leading_to_trailing(barrier);
-
+  MemBarNode *child_barrier = leading_to_normal(barrier);
+
+  if (!child_barrier) {
+    return false;
+  }
+
+  if (!is_card_mark_membar(child_barrier)) {
+    // this is the trailing membar and we are done
+    return true;
+  }
+
+  // must be sure this card mark feeds a trailing membar
+  MemBarNode *trailing = card_mark_to_trailing(child_barrier);
   return (trailing != NULL);
 }
 
@@ -2640,7 +2736,7 @@
   }
 
   // ok, if it's not a card mark then we still need to check if it is
-  // a trailing membar of a volatile put graph.
+  // a trailing membar of a volatile put hgraph.
 
   return (trailing_to_leading(mbvol) != NULL);
 }
@@ -2690,9 +2786,20 @@
   }
 
   // does this lead a normal subgraph?
-  MemBarNode *trailing = leading_to_trailing(barrier);
-
-  return (trailing != NULL);
+  MemBarNode *mbvol = leading_to_normal(barrier);
+
+  if (!mbvol) {
+    return false;
+  }
+
+  // all done unless this is a card mark
+  if (!is_card_mark_membar(mbvol)) {
+    return true;
+  }
+
+  // we found a card mark -- just make sure we have a trailing barrier
+
+  return (card_mark_to_trailing(mbvol) != NULL);
 }
 
 // predicate controlling translation of CAS
@@ -2734,7 +2841,7 @@
 	  "CAS not fed by cpuorder+release membar pair!");
 
   // does this lead a normal subgraph?
-  MemBarNode *mbar = leading_to_trailing(barrier);
+  MemBarNode *mbar = leading_to_normal(barrier);
 
   assert(mbar != NULL, "CAS not embedded in normal graph!");
 
@@ -2755,27 +2862,48 @@
 
   // we only ever need to generate a dmb ishst between an object put
   // and the associated card mark when we are using CMS without
-  // conditional card marking. Any other occurence will happen when
-  // performing a card mark using CMS with conditional card marking or
-  // G1. In those cases the preceding MamBarVolatile will be
-  // translated to a dmb ish which guarantes visibility of the
-  // preceding StoreN/P before this StoreCM
+  // conditional card marking
 
   if (!UseConcMarkSweepGC || UseCondCardMark) {
     return true;
   }
 
-  // if we are implementing volatile puts using barriers then we must
-  // insert the dmb ishst
+  // if we are implementing volatile puts using barriers then the
+  // object put as an str so we must insert the dmb ishst
 
   if (UseBarriersForVolatile) {
     return false;
   }
 
-  // we must be using CMS with conditional card marking so we ahve to
-  // generate the StoreStore
-
-  return false;
+  // we can omit the dmb ishst if this StoreCM is part of a volatile
+  // put because in thta case the put will be implemented by stlr
+  //
+  // we need to check for a normal subgraph feeding this StoreCM.
+  // that means the StoreCM must be fed Memory from a leading membar,
+  // either a MemBarRelease or its dependent MemBarCPUOrder, and the
+  // leading membar must be part of a normal subgraph
+
+  Node *x = storecm->in(StoreNode::Memory);
+
+  if (!x->is_Proj()) {
+    return false;
+  }
+
+  x = x->in(0);
+
+  if (!x->is_MemBar()) {
+    return false;
+  }
+
+  MemBarNode *leading = x->as_MemBar();
+
+  // reject invalid candidates
+  if (!leading_membar(leading)) {
+    return false;
+  }
+
+  // we can omit the StoreStore if it is the head of a normal subgraph
+  return (leading_to_normal(leading) != NULL);
 }
 
 
@@ -3008,6 +3136,10 @@
     __ notify(Assembler::method_reentry);
   }
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   if (do_polling() && C->is_method_compilation()) {
     __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
   }
@@ -9862,7 +9994,7 @@
 // END This section of the file is automatically generated. Do not edit --------------
 // ---------------------------------------------------------------------
 
-instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{
+instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
   match(Set prev (GetAndSetI mem newv));
   format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9871,7 +10003,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{
+instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
   match(Set prev (GetAndSetL mem newv));
   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9880,7 +10012,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{
+instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
   match(Set prev (GetAndSetN mem newv));
   format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9889,7 +10021,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{
+instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
   match(Set prev (GetAndSetP mem newv));
   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
   ins_encode %{
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -532,8 +532,14 @@
 
 void LIR_Assembler::return_op(LIR_Opr result) {
   assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,");
+
   // Pop the stack before the safepoint code
   __ remove_frame(initial_frame_size_in_bytes());
+
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   address polling_page(os::get_polling_page());
   __ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
   __ ret(lr);
--- a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1179,6 +1179,15 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ ldrw(tmp, in_progress);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ ldrb(tmp, in_progress);
+        }
+        __ cbzw(tmp, done);
+
         // Can we store original value in the thread's buffer?
         __ ldr(tmp, queue_index);
         __ cbz(tmp, runtime);
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -375,7 +375,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 }
 #endif
 
@@ -629,6 +630,7 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
     DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
+    DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
     DESCRIBE_FP_OFFSET(interpreter_frame_cache);
     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
     DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -46,6 +46,9 @@
 //    [pointer to locals     ]                   = locals()             locals_offset
 //    [constant pool cache   ]                   = cache()              cache_offset
 
+//    [klass of method       ]                   = mirror()             mirror_offset
+//    [padding               ]
+
 //    [methodData            ]                   = mdp()                mdx_offset
 //    [methodOop             ]                   = method()             method_offset
 
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -82,7 +82,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     _deopt_state = not_deoptimized;
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -53,4 +53,6 @@
 // evidence that it's worth doing.
 #define DEOPTIMIZE_WHEN_PATCHING
 
+#define SUPPORT_RESERVED_STACK_AREA
+
 #endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -50,7 +50,7 @@
 // stack if compiled for unix and LP64. To pass stack overflow tests we need
 // 20 shadow pages.
 #define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+5))
-#define DEFAULT_STACK_RESERVED_PAGES (0)
+#define DEFAULT_STACK_RESERVED_PAGES (1)
 
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES    DEFAULT_STACK_RED_PAGES
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -619,6 +619,22 @@
   // get sender esp
   ldr(esp,
       Address(rfp, frame::interpreter_frame_sender_sp_offset * wordSize));
+  if (StackReservedPages > 0) {
+    // testing if reserved zone needs to be re-enabled
+    Label no_reserved_zone_enabling;
+
+    ldr(rscratch1, Address(rthread, JavaThread::reserved_stack_activation_offset()));
+    cmp(esp, rscratch1);
+    br(Assembler::LS, no_reserved_zone_enabling);
+
+    call_VM_leaf(
+      CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address,
+                   InterpreterRuntime::throw_delayed_StackOverflowError));
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
   // remove frame anchor
   leave();
   // If we're returning to interpreted code we will shortly be
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -402,6 +402,30 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check() {
+    // testing if reserved zone needs to be enabled
+    Label no_reserved_zone_enabling;
+
+    ldr(rscratch1, Address(rthread, JavaThread::reserved_stack_activation_offset()));
+    cmp(sp, rscratch1);
+    br(Assembler::LO, no_reserved_zone_enabling);
+
+    enter();   // LR and FP are live.
+    lea(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone));
+    mov(c_rarg0, rthread);
+    blr(rscratch1);
+    leave();
+
+    // We have already removed our own frame.
+    // throw_delayed_StackOverflowError will think that it's been
+    // called by our caller.
+    lea(rscratch1, RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()));
+    br(rscratch1);
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+}
+
 int MacroAssembler::biased_locking_enter(Register lock_reg,
                                          Register obj_reg,
                                          Register swap_reg,
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -957,6 +957,9 @@
   // stack overflow + shadow pages.  Also, clobbers tmp
   void bang_stack_size(Register size, Register tmp);
 
+  // Check for reserved stack access in method being exited (for JIT)
+  void reserved_stack_check();
+
   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
                                                 Register tmp,
                                                 int offset);
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -4676,8 +4676,11 @@
     StubRoutines::_throw_StackOverflowError_entry =
       generate_throw_exception("StackOverflowError throw_exception",
                                CAST_FROM_FN_PTR(address,
-                                                SharedRuntime::
-                                                throw_StackOverflowError));
+                                                SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_delayed_StackOverflowError_entry =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address,
+                                                SharedRuntime::throw_delayed_StackOverflowError));
     if (UseCRC32Intrinsics) {
       // set table address before stub generation which use it
       StubRoutines::_crc_table_adr = (address)StubRoutines::aarch64::_crc_table;
--- a/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -551,6 +551,8 @@
         const Register r_index_1    = R1;
         const Register r_buffer_2   = R2;
 
+        Address queue_active(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+                                               SATBMarkQueue::byte_offset_of_active()));
         Address queue_index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                               SATBMarkQueue::byte_offset_of_index()));
         Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
@@ -559,6 +561,11 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+        __ ldrb(R1, queue_active);
+        __ cbz(R1, done);
+
         __ ldr(r_index_1, queue_index);
         __ ldr(r_pre_val_0, Address(SP, nb_saved_regs*wordSize));
         __ ldr(r_buffer_2, buffer);
--- a/hotspot/src/cpu/arm/vm/frame_arm.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/arm/vm/frame_arm.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -364,7 +364,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
   assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
 }
 #endif
--- a/hotspot/src/cpu/arm/vm/frame_arm.inline.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/arm/vm/frame_arm.inline.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -75,7 +75,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(_cb->as_compiled_method()->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     _deopt_state = not_deoptimized;
--- a/hotspot/src/cpu/ppc/vm/c1_Runtime1_ppc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/ppc/vm/c1_Runtime1_ppc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -741,7 +741,10 @@
         Register tmp  = R14;
         Register tmp2 = R15;
 
-        Label refill, restart;
+        Label refill, restart, marking_not_active;
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -753,6 +756,16 @@
         __ std(tmp, -16, R1_SP);
         __ std(tmp2, -24, R1_SP);
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ lwz(tmp, satb_q_active_byte_offset, R16_thread);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ lbz(tmp, satb_q_active_byte_offset, R16_thread);
+        }
+        __ cmpdi(CCR0, tmp, 0);
+        __ beq(CCR0, marking_not_active);
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate.
@@ -769,6 +782,7 @@
         __ std(tmp, satb_q_index_byte_offset, R16_thread);
         __ stdx(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card>
 
+        __ bind(marking_not_active);
         // Restore temp registers and return-from-leaf.
         __ ld(tmp2, -24, R1_SP);
         __ ld(tmp, -16, R1_SP);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -2569,7 +2569,7 @@
 }
 
 // Spin and retry if lock is busy.
-// inputs: box_Reg (monitor address)
+// inputs: owner_addr_Reg (monitor address)
 //       : retry_count_Reg
 // output: retry_count_Reg decremented by 1
 // CTR is killed
@@ -2577,15 +2577,22 @@
   Label SpinLoop, doneRetry;
   addic_(retry_count_Reg, retry_count_Reg, -1);
   blt(CCR0, doneRetry);
-  li(R0, RTMSpinLoopCount);
-  mtctr(R0);
+
+  if (RTMSpinLoopCount > 1) {
+    li(R0, RTMSpinLoopCount);
+    mtctr(R0);
+  }
 
   bind(SpinLoop);
   smt_yield(); // Can't use waitrsv(). No permission (SIGILL).
-  bdz(retryLabel);
-  ld(R0, 0, owner_addr_Reg);
-  cmpdi(CCR0, R0, 0);
-  bne(CCR0, SpinLoop);
+
+  if (RTMSpinLoopCount > 1) {
+    bdz(retryLabel);
+    ld(R0, 0, owner_addr_Reg);
+    cmpdi(CCR0, R0, 0);
+    bne(CCR0, SpinLoop);
+  }
+
   b(retryLabel);
 
   bind(doneRetry);
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -327,7 +327,10 @@
       warning("RTMAbortRatio must be in the range 0 to 100, resetting it to 50");
       FLAG_SET_DEFAULT(RTMAbortRatio, 50);
     }
-    guarantee(RTMSpinLoopCount > 0, "unsupported");
+    if (RTMSpinLoopCount < 0) {
+      warning("RTMSpinLoopCount must not be a negative value, resetting it to 0");
+      FLAG_SET_DEFAULT(RTMSpinLoopCount, 0);
+    }
 #else
     // Only C2 does RTM locking optimization.
     // Can't continue because UseRTMLocking affects UseBiasedLocking flag
--- a/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1105,16 +1105,16 @@
       }
     case T_FLOAT :
       if (short_disp) {
-                    __ z_ste(from->as_float_reg(),  disp_value, disp_reg, dest);
+        __ z_ste(from->as_float_reg(),  disp_value, disp_reg, dest);
       } else {
-                    __ z_stey(from->as_float_reg(), disp_value, disp_reg, dest);
+        __ z_stey(from->as_float_reg(), disp_value, disp_reg, dest);
       }
       break;
     case T_DOUBLE:
       if (short_disp) {
-                    __ z_std(from->as_double_reg(),  disp_value, disp_reg, dest);
+        __ z_std(from->as_double_reg(),  disp_value, disp_reg, dest);
       } else {
-                    __ z_stdy(from->as_double_reg(), disp_value, disp_reg, dest);
+        __ z_stdy(from->as_double_reg(), disp_value, disp_reg, dest);
       }
       break;
     default: ShouldNotReachHere();
@@ -1148,6 +1148,10 @@
     __ restore_return_pc();
   }
 
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check(Z_R14);
+  }
+
   // We need to mark the code position where the load from the safepoint
   // polling page was emitted as relocInfo::poll_return_type here.
   __ relocate(relocInfo::poll_return_type);
--- a/hotspot/src/cpu/s390/vm/c1_Runtime1_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/c1_Runtime1_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -784,7 +784,10 @@
         Register tmp  = Z_R6; // Must be non-volatile because it is used to save pre_val.
         Register tmp2 = Z_R7;
 
-        Label refill, restart;
+        Label refill, restart, marking_not_active;
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -796,6 +799,15 @@
         __ z_stg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
         __ z_stg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ load_and_test_int(tmp, Address(Z_thread, satb_q_active_byte_offset));
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ load_and_test_byte(tmp, Address(Z_thread, satb_q_active_byte_offset));
+        }
+        __ z_bre(marking_not_active); // Activity indicator is zero, so there is no marking going on currently.
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate.
@@ -810,6 +822,7 @@
         __ z_stg(pre_val, 0, tmp, tmp2); // [_buf + index] := <address_of_card>
         __ z_stg(tmp, satb_q_index_byte_offset, Z_thread);
 
+        __ bind(marking_not_active);
         // Restore tmp registers (see assertion in G1PreBarrierStub::emit_code()).
         __ z_lg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
         __ z_lg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
--- a/hotspot/src/cpu/s390/vm/globalDefinitions_s390.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/globalDefinitions_s390.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -52,4 +52,6 @@
 // The expected size in bytes of a cache line, used to pad data structures.
 #define DEFAULT_CACHE_LINE_SIZE 256
 
+#define SUPPORT_RESERVED_STACK_AREA
+
 #endif // CPU_S390_VM_GLOBALDEFINITIONS_S390_HPP
--- a/hotspot/src/cpu/s390/vm/globals_s390.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/globals_s390.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -56,7 +56,7 @@
 // Java_java_net_SocketOutputStream_socketWrite0() uses a 64k buffer on the
 // stack. To pass stack overflow tests we need 20 shadow pages.
 #define DEFAULT_STACK_SHADOW_PAGES   (20 DEBUG_ONLY(+2))
-#define DEFAULT_STACK_RESERVED_PAGES (0)
+#define DEFAULT_STACK_RESERVED_PAGES (1)
 
 #define MIN_STACK_YELLOW_PAGES     DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES        DEFAULT_STACK_RED_PAGES
--- a/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -860,16 +860,39 @@
                                                   bool throw_monitor_exception,
                                                   bool install_monitor_exception,
                                                   bool notify_jvmti) {
-
+  BLOCK_COMMENT("remove_activation {");
   unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
 
   // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
   notify_method_exit(false, state, notify_jvmti ? NotifyJVMTI : SkipNotifyJVMTI);
 
+  if (StackReservedPages > 0) {
+    BLOCK_COMMENT("reserved_stack_check:");
+    // Test if reserved zone needs to be enabled.
+    Label no_reserved_zone_enabling;
+
+    // Compare frame pointers. There is no good stack pointer, as with stack
+    // frame compression we can get different SPs when we do calls. A subsequent
+    // call could have a smaller SP, so that this compare succeeds for an
+    // inner call of the method annotated with ReservedStack.
+    z_lg(Z_R0, Address(Z_SP, (intptr_t)_z_abi(callers_sp)));
+    z_clg(Z_R0, Address(Z_thread, JavaThread::reserved_stack_activation_offset())); // Compare with frame pointer in memory.
+    z_brl(no_reserved_zone_enabling);
+
+    // Enable reserved zone again, throw stack overflow exception.
+    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), Z_thread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError));
+
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
+
   verify_oop(Z_tos, state);
   verify_thread();
 
   pop_interpreter_frame(return_pc, Z_ARG2, Z_ARG3);
+  BLOCK_COMMENT("} remove_activation");
 }
 
 // lock object
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -2666,6 +2666,32 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check(Register return_pc) {
+  // Test if reserved zone needs to be enabled.
+  Label no_reserved_zone_enabling;
+  assert(return_pc == Z_R14, "Return pc must be in R14 before z_br() to StackOverflow stub.");
+  BLOCK_COMMENT("reserved_stack_check {");
+
+  z_clg(Z_SP, Address(Z_thread, JavaThread::reserved_stack_activation_offset()));
+  z_brl(no_reserved_zone_enabling);
+
+  // Enable reserved zone again, throw stack overflow exception.
+  save_return_pc();
+  push_frame_abi160(0);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), Z_thread);
+  pop_frame();
+  restore_return_pc();
+
+  load_const_optimized(Z_R1, StubRoutines::throw_delayed_StackOverflowError_entry());
+  // Don't use call() or z_basr(), they will invalidate Z_R14 which contains the return pc.
+  z_br(Z_R1);
+
+  should_not_reach_here();
+
+  bind(no_reserved_zone_enabling);
+  BLOCK_COMMENT("} reserved_stack_check");
+}
+
 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
 void MacroAssembler::tlab_allocate(Register obj,
                                    Register var_size_in_bytes,
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -627,6 +627,11 @@
   // Stack overflow checking
   void bang_stack_with_offset(int offset);
 
+  // Check for reserved stack access in method being exited. If the reserved
+  // stack area was accessed, protect it again and throw StackOverflowError.
+  // Uses Z_R1.
+  void reserved_stack_check(Register return_pc);
+
   // Atomics
   // -- none?
 
--- a/hotspot/src/cpu/s390/vm/s390.ad	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/s390.ad	Wed Jul 05 22:48:30 2017 +0200
@@ -909,15 +909,8 @@
   // If this does safepoint polling, then do it here.
   bool need_polling = do_polling() && C->is_method_compilation();
 
-  // Touch the polling page.
-  // Part 1: get the page's address.
-  if (need_polling) {
-    AddressLiteral pp(os::get_polling_page());
-    __ load_const_optimized(Z_R1_scratch, pp);
-  }
-
   // Pop frame, restore return_pc, and all stuff needed by interpreter.
-  // Pop frame by add insted of load (a penny saved is a penny got :-).
+  // Pop frame by add instead of load (a penny saved is a penny got :-).
   int frame_size_in_bytes = Assembler::align((C->frame_slots() << LogBytesPerInt), frame::alignment_in_bytes);
   int retPC_offset        = frame_size_in_bytes + _z_abi16(return_pc);
   if (Displacement::is_validDisp(retPC_offset)) {
@@ -928,9 +921,14 @@
     __ restore_return_pc();
   }
 
-  // Touch the polling page,
-  // part 2: touch the page now.
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check(Z_R14);
+  }
+
+  // Touch the polling page.
   if (need_polling) {
+    AddressLiteral pp(os::get_polling_page());
+    __ load_const_optimized(Z_R1_scratch, pp);
     // We need to mark the code position where the load from the safepoint
     // polling page was emitted as relocInfo::poll_return_type here.
     __ relocate(relocInfo::poll_return_type);
@@ -939,7 +937,7 @@
 }
 
 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
-  // variable size. determine dynamically.
+  // Variable size. determine dynamically.
   return MachNode::size(ra_);
 }
 
--- a/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -2433,13 +2433,12 @@
     StubRoutines::_throw_StackOverflowError_entry          =
       generate_throw_exception("StackOverflowError throw_exception",
                                CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
+    StubRoutines::_throw_delayed_StackOverflowError_entry  =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError), false);
 
     //----------------------------------------------------------------------
     // Entry points that are platform specific.
-    // Build this early so it's available for the interpreter.
-    StubRoutines::_throw_StackOverflowError_entry          =
-      generate_throw_exception("StackOverflowError throw_exception",
-                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
 
     if (UseCRC32Intrinsics) {
       // We have no CRC32 table on z/Architecture.
--- a/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1112,16 +1112,21 @@
   // top_frame_size = TOP_IJAVA_FRAME_ABI + max_stack + size of interpreter state
   __ add2reg(top_frame_size,
              frame::z_top_ijava_frame_abi_size +
-               frame::z_ijava_state_size +
-               frame::interpreter_frame_monitor_size() * wordSize,
+             frame::z_ijava_state_size +
+             frame::interpreter_frame_monitor_size() * wordSize,
              max_stack);
 
-  // Check if there's room for the new frame...
-  Register frame_size = max_stack; // Reuse the regiser for max_stack.
-  __ z_lgr(frame_size, Z_SP);
-  __ z_sgr(frame_size, sp_after_resize);
-  __ z_agr(frame_size, top_frame_size);
-  generate_stack_overflow_check(frame_size, fp/*tmp1*/);
+  if (!native_call) {
+    // Stack overflow check.
+    // Native calls don't need the stack size check since they have no
+    // expression stack and the arguments are already on the stack and
+    // we only add a handful of words to the stack.
+    Register frame_size = max_stack; // Reuse the regiser for max_stack.
+    __ z_lgr(frame_size, Z_SP);
+    __ z_sgr(frame_size, sp_after_resize);
+    __ z_agr(frame_size, top_frame_size);
+    generate_stack_overflow_check(frame_size, fp/*tmp1*/);
+  }
 
   DEBUG_ONLY(__ z_cg(Z_R14, _z_abi16(return_pc), Z_SP));
   __ asm_assert_eq("killed Z_R14", 0);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -694,6 +694,7 @@
 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
   int store_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
+    assert(base != O7, "destroying register");
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
@@ -712,9 +713,12 @@
       case T_LONG  :
 #ifdef _LP64
         if (unaligned || PatchALot) {
-          __ srax(from_reg->as_register_lo(), 32, O7);
+          // Don't use O7 here because it may be equal to 'base' (see LIR_Assembler::reg2mem)
+          assert(G3_scratch != base, "can't handle this");
+          assert(G3_scratch != from_reg->as_register_lo(), "can't handle this");
+          __ srax(from_reg->as_register_lo(), 32, G3_scratch);
           __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes);
-          __ stw(O7,                         base, offset + hi_word_offset_in_bytes);
+          __ stw(G3_scratch,                 base, offset + hi_word_offset_in_bytes);
         } else {
           __ stx(from_reg->as_register_lo(), base, offset);
         }
@@ -821,7 +825,7 @@
       case T_SHORT : __ ldsh(base, offset, to_reg->as_register()); break;
       case T_INT   : __ ld(base, offset, to_reg->as_register()); break;
       case T_LONG  :
-        if (!unaligned) {
+        if (!unaligned && !PatchALot) {
 #ifdef _LP64
           __ ldx(base, offset, to_reg->as_register_lo());
 #else
@@ -1297,7 +1301,7 @@
       disp_reg = O7;
     }
   } else if (unaligned || PatchALot) {
-    __ add(src, addr->index()->as_register(), O7);
+    __ add(src, addr->index()->as_pointer_register(), O7);
     src = O7;
   } else {
     disp_reg = addr->index()->as_pointer_register();
@@ -1424,7 +1428,7 @@
       disp_reg = O7;
     }
   } else if (unaligned || PatchALot) {
-    __ add(src, addr->index()->as_register(), O7);
+    __ add(src, addr->index()->as_pointer_register(), O7);
     src = O7;
   } else {
     disp_reg = addr->index()->as_pointer_register();
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -856,7 +856,9 @@
         Register tmp2 = G3_scratch;
 
         Label refill, restart;
-        bool with_frame = false; // I don't know if we can do with-frame.
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -864,6 +866,17 @@
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_buf());
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ ld(G2_thread, satb_q_active_byte_offset, tmp);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ ldsb(G2_thread, satb_q_active_byte_offset, tmp);
+        }
+        __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, restart);
+        __ retl();
+        __ delayed()->nop();
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -1623,6 +1623,8 @@
 
         NOT_LP64(__ get_thread(thread);)
 
+        Address queue_active(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
+                                              SATBMarkQueue::byte_offset_of_active()));
         Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                              SATBMarkQueue::byte_offset_of_index()));
         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
@@ -1631,6 +1633,15 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ cmpl(queue_active, 0);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ cmpb(queue_active, 0);
+        }
+        __ jcc(Assembler::equal, done);
+
         // Can we store original value in the thread's buffer?
 
         __ movptr(tmp, queue_index);
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -376,7 +376,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in CompiledMethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 }
 #endif
 
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -75,7 +75,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     if (_cb->is_deoptimization_stub()) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -3499,12 +3499,12 @@
   }
 }
 
-void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src, Register scratchReg) {
   if (reachable(src)) {
     movdqu(dst, as_Address(src));
   } else {
-    lea(rscratch1, src);
-    movdqu(dst, Address(rscratch1, 0));
+    lea(scratchReg, src);
+    movdqu(dst, Address(scratchReg, 0));
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1085,7 +1085,7 @@
   void movdqu(Address     dst, XMMRegister src);
   void movdqu(XMMRegister dst, Address src);
   void movdqu(XMMRegister dst, XMMRegister src);
-  void movdqu(XMMRegister dst, AddressLiteral src);
+  void movdqu(XMMRegister dst, AddressLiteral src, Register scratchReg = rscratch1);
   // AVX Unaligned forms
   void vmovdqu(Address     dst, XMMRegister src);
   void vmovdqu(XMMRegister dst, Address src);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -817,7 +817,7 @@
   movl(d, Address(CTX, 4*3));
   movl(e, Address(CTX, 4*4));
   movl(f, Address(CTX, 4*5));
-  movl(g, Address(CTX, 4*6));
+  // load g - r10 after it is used as scratch
   movl(h, Address(CTX, 4*7));
 
   pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask;
@@ -825,6 +825,8 @@
   vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));     //[_SHUF_00BA wrt rip]
   vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64));     //[_SHUF_DC00 wrt rip]
 
+  movl(g, Address(CTX, 4*6));
+
   movq(Address(rsp, _CTX), CTX);           // store
 
 bind(loop0);
@@ -977,7 +979,7 @@
   movl(d, Address(CTX, 4*3));   // 0xa54ff53a
   movl(e, Address(CTX, 4*4));   // 0x510e527f
   movl(f, Address(CTX, 4*5));   // 0x9b05688c
-  movl(g, Address(CTX, 4*6));   // 0x1f83d9ab
+  // load g - r10 after use as scratch
   movl(h, Address(CTX, 4*7));   // 0x5be0cd19
 
 
@@ -986,6 +988,8 @@
   vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));     //[_SHUF_00BA wrt rip]
   vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64));     //[_SHUF_DC00 wrt rip]
 
+  movl(g, Address(CTX, 4*6));   // 0x1f83d9ab
+
   movq(Address(rsp, _CTX), CTX);
   jmpb(do_last_block);
 
@@ -1154,9 +1158,8 @@
       // Move to appropriate lanes for calculating w[16] and w[17]
       vperm2f128(xmm4, xmm0, xmm0, 0); //xmm4 = W[-16] + W[-7] + s0{ BABA }
 
-      address MASK_YMM_LO = StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512();
       //Move to appropriate lanes for calculating w[18] and w[19]
-      vpand(xmm0, xmm0, ExternalAddress(MASK_YMM_LO + 32), AVX_256bit); //xmm0 = W[-16] + W[-7] + s0{ DC00 }
+      vpand(xmm0, xmm0, xmm10, AVX_256bit); //xmm0 = W[-16] + W[-7] + s0{ DC00 }
       //Calculate w[16] and w[17] in both 128 bit lanes
       //Calculate sigma1 for w[16] and w[17] on both 128 bit lanes
       vperm2f128(xmm2, xmm7, xmm7, 17); //xmm2 = W[-2] {BABA}
@@ -1250,6 +1253,7 @@
 
     const XMMRegister& XFER = xmm0; // YTMP0
     const XMMRegister& BYTE_FLIP_MASK = xmm9; // ymm9
+    const XMMRegister& YMM_MASK_LO = xmm10; // ymm10
 #ifdef _WIN64
     const Register& INP = rcx; //1st arg
     const Register& CTX = rdx; //2nd arg
@@ -1368,11 +1372,14 @@
     movq(d, Address(CTX, 8 * 3));
     movq(e, Address(CTX, 8 * 4));
     movq(f, Address(CTX, 8 * 5));
-    movq(g, Address(CTX, 8 * 6));
+    // load g - r10 after it is used as scratch
     movq(h, Address(CTX, 8 * 7));
 
     pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask_sha512;
     vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); //PSHUFFLE_BYTE_FLIP_MASK wrt rip
+    vmovdqu(YMM_MASK_LO, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));
+
+    movq(g, Address(CTX, 8 * 6));
 
     bind(loop0);
     lea(TBL, ExternalAddress(K512_W));
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -3207,7 +3207,7 @@
     const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
 #else
     const Address  len_mem(rbp, 6 * wordSize);  // length is on stack on Win64
-    const Register len_reg     = r10;      // pick the first volatile windows register
+    const Register len_reg     = r11;      // pick the volatile windows register
 #endif
     const Register pos         = rax;
 
@@ -3404,7 +3404,7 @@
     const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
 #else
     const Address  len_mem(rbp, 6 * wordSize);  // length is on stack on Win64
-    const Register len_reg     = r10;      // pick the first volatile windows register
+    const Register len_reg     = r11;      // pick the volatile windows register
 #endif
     const Register pos         = rax;
 
@@ -3930,7 +3930,7 @@
 
     __ push(rbx); // Save RBX
     __ movdqu(xmm_curr_counter, Address(counter, 0x00)); // initialize counter with initial counter
-    __ movdqu(xmm_counter_shuf_mask, ExternalAddress(StubRoutines::x86::counter_shuffle_mask_addr()));
+    __ movdqu(xmm_counter_shuf_mask, ExternalAddress(StubRoutines::x86::counter_shuffle_mask_addr()), pos); // pos as scratch
     __ pshufb(xmm_curr_counter, xmm_counter_shuf_mask); //counter is shuffled
     __ movptr(pos, 0);
 
@@ -3953,7 +3953,7 @@
     __ movl(Address(used_addr, 0), used);
 
     // key length could be only {11, 13, 15} * 4 = {44, 52, 60}
-    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()), rbx); // rbx as scratch
     __ movl(rbx, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
     __ cmpl(rbx, 52);
     __ jcc(Assembler::equal, L_multiBlock_loopTop[1]);
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Wed Jul 05 22:48:30 2017 +0200
@@ -37,6 +37,7 @@
 import jdk.tools.jaotc.binformat.Symbol.Kind;
 import jdk.tools.jaotc.binformat.elf.JELFRelocObject;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 
 /**
  * A format-agnostic container class that holds various components of a binary.
@@ -257,9 +258,9 @@
      * prefix {@code prefix}. It also initializes internal code container, symbol table and
      * relocation tables.
      */
-    public BinaryContainer(GraalHotSpotVMConfig config, String jvmVersion) {
-        this.codeSegmentSize = config.codeSegmentSize;
-        this.codeEntryAlignment = config.codeEntryAlignment;
+    public BinaryContainer(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig, String jvmVersion) {
+        this.codeSegmentSize = graalHotSpotVMConfig.codeSegmentSize;
+        this.codeEntryAlignment = graalHotSpotVMConfig.codeEntryAlignment;
 
         // read only, code
         codeContainer = new CodeContainer(".text", this);
@@ -289,30 +290,31 @@
 
         addGlobalSymbols();
 
-        recordConfiguration(config);
+        recordConfiguration(graalHotSpotVMConfig, graphBuilderConfig);
     }
 
-    private void recordConfiguration(GraalHotSpotVMConfig config) {
+    private void recordConfiguration(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig) {
         // @formatter:off
-        boolean[] booleanFlags = { config.cAssertions, // Debug VM
-                                   config.useCompressedOops,
-                                   config.useCompressedClassPointers,
-                                   config.compactFields,
-                                   config.useG1GC,
-                                   config.useCMSGC,
-                                   config.useTLAB,
-                                   config.useBiasedLocking,
+        boolean[] booleanFlags = { graalHotSpotVMConfig.cAssertions, // Debug VM
+                                   graalHotSpotVMConfig.useCompressedOops,
+                                   graalHotSpotVMConfig.useCompressedClassPointers,
+                                   graalHotSpotVMConfig.compactFields,
+                                   graalHotSpotVMConfig.useG1GC,
+                                   graalHotSpotVMConfig.useCMSGC,
+                                   graalHotSpotVMConfig.useTLAB,
+                                   graalHotSpotVMConfig.useBiasedLocking,
                                    TieredAOT.getValue(),
-                                   config.enableContended,
-                                   config.restrictContended,
+                                   graalHotSpotVMConfig.enableContended,
+                                   graalHotSpotVMConfig.restrictContended,
+                                   graphBuilderConfig.omitAssertions()
         };
 
-        int[] intFlags         = { config.narrowOopShift,
-                                   config.narrowKlassShift,
-                                   config.contendedPaddingWidth,
-                                   config.fieldsAllocationStyle,
-                                   config.objectAlignment,
-                                   config.codeSegmentSize,
+        int[] intFlags         = { graalHotSpotVMConfig.getOopEncoding().shift,
+                                   graalHotSpotVMConfig.getKlassEncoding().shift,
+                                   graalHotSpotVMConfig.contendedPaddingWidth,
+                                   graalHotSpotVMConfig.fieldsAllocationStyle,
+                                   1 << graalHotSpotVMConfig.getOopEncoding().alignment,
+                                   graalHotSpotVMConfig.codeSegmentSize,
         };
         // @formatter:on
 
@@ -395,6 +397,10 @@
         return "_aot_narrow_klass_base_address";
     }
 
+    public String getNarrowOopBaseAddressSymbolName() {
+        return "_aot_narrow_oop_base_address";
+    }
+
     public String getLogOfHeapRegionGrainBytesSymbolName() {
         return "_aot_log_of_heap_region_grain_bytes";
     }
@@ -445,6 +451,7 @@
         createGotSymbol(getHeapTopAddressSymbolName());
         createGotSymbol(getHeapEndAddressSymbolName());
         createGotSymbol(getNarrowKlassBaseAddressSymbolName());
+        createGotSymbol(getNarrowOopBaseAddressSymbolName());
         createGotSymbol(getPollingPageSymbolName());
         createGotSymbol(getLogOfHeapRegionGrainBytesSymbolName());
         createGotSymbol(getInlineContiguousAllocationSupportedSymbolName());
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java	Wed Jul 05 22:48:30 2017 +0200
@@ -77,10 +77,14 @@
         this.filters = filters;
         providers = backend.getProviders();
         codeCache = providers.getCodeCache();
-        graphBuilderSuite = initGraphBuilderSuite(backend);
+        graphBuilderSuite = initGraphBuilderSuite(backend, main.options.compileWithAssertions);
         highTierContext = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.ALL);
     }
 
+    public PhaseSuite<HighTierContext> getGraphBuilderSuite() {
+        return graphBuilderSuite;
+    }
+
     private Suites getSuites() {
         // create suites every time, as we modify options for the compiler
         return backend.getSuites().getDefaultSuites();
@@ -146,14 +150,14 @@
         return backend.getRuntime().getVMConfig().cAssertions;
     }
 
-    private static PhaseSuite<HighTierContext> initGraphBuilderSuite(HotSpotBackend backend) {
+    private static PhaseSuite<HighTierContext> initGraphBuilderSuite(HotSpotBackend backend, boolean compileWithAssertions) {
         PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
         GraphBuilderConfiguration baseConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
 
         // Use all default plugins.
         Plugins plugins = baseConfig.getPlugins();
-        GraphBuilderConfiguration aotConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true);
+        GraphBuilderConfiguration aotConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withOmitAssertions(!compileWithAssertions);
 
         iterator.next();
         iterator.remove();
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java	Wed Jul 05 22:48:30 2017 +0200
@@ -293,12 +293,18 @@
             // Record methods holder
             methodInfo.addDependentKlassData(binaryContainer, resolvedJavaType);
             // Record inlinee classes
-            for (ResolvedJavaMethod m : methodInfo.getCompilationResult().getMethods()) {
-                methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) m.getDeclaringClass());
+            ResolvedJavaMethod[] inlinees = methodInfo.getCompilationResult().getMethods();
+            if (inlinees != null) {
+                for (ResolvedJavaMethod m : inlinees) {
+                    methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) m.getDeclaringClass());
+                }
             }
             // Record classes of fields that were accessed
-            for (ResolvedJavaField f : methodInfo.getCompilationResult().getFields()) {
-                methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) f.getDeclaringClass());
+            ResolvedJavaField[] fields = methodInfo.getCompilationResult().getFields();
+            if (fields != null) {
+                for (ResolvedJavaField f : fields) {
+                    methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) f.getDeclaringClass());
+                }
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,64 @@
+package jdk.tools.jaotc;/*
+ * Copyright (c) 2015, 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.
+ */
+
+public class LoadedClass {
+    private final String name;
+    private final Class<?> clz;
+
+    public LoadedClass(String name, Class<?> clz) {
+        this.name = name;
+        this.clz = clz;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Class<?> getLoadedClass() {
+        return clz;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof LoadedClass)) return false;
+
+        LoadedClass that = (LoadedClass) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        return clz != null ? clz.equals(that.clz) : that.clz == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (clz != null ? clz.hashCode() : 0);
+        return result;
+    }
+}
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -43,19 +43,31 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Set;
 import java.util.stream.Stream;
 
 import jdk.tools.jaotc.binformat.BinaryContainer;
 import jdk.tools.jaotc.binformat.ByteContainer;
-import jdk.tools.jaotc.collect.ClassCollector;
+import jdk.tools.jaotc.collect.*;
+import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider;
+import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
+import jdk.tools.jaotc.collect.jar.JarSourceProvider;
+import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
 import jdk.tools.jaotc.utils.Timer;
 
 import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
+import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.runtime.RuntimeProvider;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -120,17 +132,7 @@
         abstract void process(Main task, String opt, String arg) throws BadArgs;
     }
 
-    static Option[] recognizedOptions = {new Option("  --module <name>            Module to compile", true, "--module") {
-        @Override
-        void process(Main task, String opt, String arg) {
-            task.options.module = arg;
-        }
-    }, new Option("  --module-path <path>       Specify where to find module to compile", true, "--module-path") {
-        @Override
-        void process(Main task, String opt, String arg) {
-            task.options.modulepath = arg;
-        }
-    }, new Option("  --output <file>            Output file name", true, "--output") {
+    static Option[] recognizedOptions = { new Option("  --output <file>            Output file name", true, "--output") {
         @Override
         void process(Main task, String opt, String arg) {
             String name = arg;
@@ -139,22 +141,48 @@
             }
             task.options.outputName = name;
         }
+    }, new Option("  --class-name <class names> List of classes to compile", true, "--class-name", "--classname") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(ClassNameSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --jar <jarfiles>           List of jar files to compile", true, "--jar") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(JarSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --module <modules>         List of modules to compile", true, "--module") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(ModuleSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --directory <dirs>         List of directories where to search for files to compile", true, "--directory") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(DirectorySourceProvider.TYPE, arg));
+        }
+    }, new Option("  --search-path <dirs>       List of directories where to search for specified files", true, "--search-path") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            String[] elements = arg.split(":");
+            task.options.searchPath.add(elements);
+        }
     }, new Option("  --compile-commands <file>  Name of file with compile commands", true, "--compile-commands") {
         @Override
         void process(Main task, String opt, String arg) {
             task.options.methodList = arg;
         }
-    }, new Option("  --compile-for-tiered       Generated profiling code for tiered compilation", false, "--compile-for-tiered") {
+    }, new Option("  --compile-for-tiered       Generate profiling code for tiered compilation", false, "--compile-for-tiered") {
         @Override
         void process(Main task, String opt, String arg) {
             TieredAOT.setValue(true);
         }
-    }, new Option("  --classpath <path>         Specify where to find user class files", true, "--classpath", "--class-path") {
+    }, new Option("  --compile-with-assertions  Compile with java assertions", false, "--compile-with-assertions") {
         @Override
         void process(Main task, String opt, String arg) {
-            task.options.classpath = arg;
+            task.options.compileWithAssertions = true;
         }
-    }, new Option("  --threads <number>         Number of compilation threads to be used", true, "--threads") {
+    }, new Option("  --compile-threads <number> Number of compilation threads to be used", true, "--compile-threads", "--threads") {
         @Override
         void process(Main task, String opt, String arg) {
             int threads = Integer.parseInt(arg);
@@ -213,27 +241,27 @@
     }};
 
     public static class Options {
-        public List<String> files = new LinkedList<>();
-        public String module = null;
-        public String modulepath = "modules";
+        public List<SearchFor> files = new LinkedList<>();
         public String outputName = "unnamed";
         public String methodList;
-        public String classpath = ".";
+        public List<ClassSource> sources = new ArrayList<>();
+        public SearchPath searchPath = new SearchPath();
 
         /**
          * We don't see scaling beyond 16 threads.
          */
         private static final int COMPILER_THREADS = 16;
 
-        int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
+        public int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
 
         public boolean ignoreClassLoadingErrors;
         public boolean exitOnError;
-        boolean info;
-        boolean verbose;
-        boolean debug;
-        boolean help;
-        boolean version;
+        public boolean info;
+        public boolean verbose;
+        public boolean debug;
+        public boolean help;
+        public boolean version;
+        public boolean compileWithAssertions;
     }
 
     /* package */final Options options = new Options();
@@ -275,7 +303,9 @@
 
             printlnInfo("Compiling " + options.outputName + "...");
             final long start = System.currentTimeMillis();
-            run();
+            if (!run()) {
+              return EXIT_ABNORMAL;
+            }
             final long end = System.currentTimeMillis();
             printlnInfo("Total time: " + (end - start) + " ms");
 
@@ -318,17 +348,34 @@
     }
 
     @SuppressWarnings("try")
-    private void run() throws Exception {
+    private boolean run() throws Exception {
         openLog();
 
         try {
             CompilationSpec compilationRestrictions = collectSpecifiedMethods();
 
-            Set<Class<?>> classesToCompile;
+            Set<Class<?>> classesToCompile = new HashSet<>();
 
             try (Timer t = new Timer(this, "")) {
-                ClassCollector collector = new ClassCollector(this.options, this);
-                classesToCompile = collector.collectClassesToCompile();
+                FileSupport fileSupport = new FileSupport();
+                ClassSearch lookup = new ClassSearch();
+                lookup.addProvider(new ModuleSourceProvider());
+                lookup.addProvider(new ClassNameSourceProvider(fileSupport));
+                lookup.addProvider(new JarSourceProvider());
+                lookup.addProvider(new DirectorySourceProvider(fileSupport));
+
+                List<LoadedClass> found = null;
+                try {
+                    found = lookup.search(options.files, options.searchPath);
+                } catch (InternalError e) {
+                    reportError(e);
+                    return false;
+                }
+
+                for (LoadedClass loadedClass : found) {
+                    classesToCompile.add(loadedClass.getLoadedClass());
+                }
+
                 printInfo(classesToCompile.size() + " classes found");
             }
 
@@ -356,6 +403,11 @@
             AOTCompiler compiler = new AOTCompiler(this, aotBackend, options.threads);
             classes = compiler.compileClasses(classes);
 
+            GraalHotSpotVMConfig graalHotSpotVMConfig = runtime.getVMConfig();
+            PhaseSuite<HighTierContext> graphBuilderSuite = aotBackend.getGraphBuilderSuite();
+            ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
+            GraphBuilderConfiguration graphBuilderConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
+
             // Free memory!
             try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
                 printMemoryUsage();
@@ -364,7 +416,7 @@
                 System.gc();
             }
 
-            BinaryContainer binaryContainer = new BinaryContainer(runtime.getVMConfig(), JVM_VERSION);
+            BinaryContainer binaryContainer = new BinaryContainer(graalHotSpotVMConfig, graphBuilderConfig, JVM_VERSION);
             DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
             dataBuilder.prepareData();
 
@@ -446,6 +498,7 @@
         } finally {
             closeLog();
         }
+        return true;
     }
 
     private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions, GraalFilters filters) {
@@ -509,7 +562,7 @@
                     break;
                 }
             } else {
-                options.files.add(arg);
+                options.files.add(new SearchFor(arg));
             }
         }
     }
@@ -570,6 +623,12 @@
         log.flush();
     }
 
+    private void reportError(Throwable e) {
+        log.println("Error: " + e.getMessage());
+        e.printStackTrace(log);
+        log.flush();
+    }
+
     private void reportError(String key, Object... args) {
         printError(MessageFormat.format(key, args));
     }
@@ -580,17 +639,17 @@
     }
 
     private void showUsage() {
-        log.println("Usage: " + PROGNAME + " <options> list...");
+        log.println("Usage: " + PROGNAME + " <options> list");
         log.println("use --help for a list of possible options");
     }
 
     private void showHelp() {
-        log.println("Usage: " + PROGNAME + " <options> <--module name> | <list...>");
+        log.println("Usage: " + PROGNAME + " <options> list");
         log.println();
-        log.println("  list       A list of class files, jar files or directories which");
-        log.println("             contains class files.");
+        log.println("  list       A : separated list of class names, modules, jar files");
+        log.println("             or directories which contain class files.");
         log.println();
-        log.println("where possible options include:");
+        log.println("where options include:");
         for (Option o : recognizedOptions) {
             String name = o.aliases[0].substring(1); // there must always be at least one name
             name = name.charAt(0) == '-' ? name.substring(1) : name;
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Wed Jul 05 22:48:30 2017 +0200
@@ -48,6 +48,7 @@
     HEAP_TOP_ADDRESS("CodeInstaller::HEAP_TOP_ADDRESS"),
     HEAP_END_ADDRESS("CodeInstaller::HEAP_END_ADDRESS"),
     NARROW_KLASS_BASE_ADDRESS("CodeInstaller::NARROW_KLASS_BASE_ADDRESS"),
+    NARROW_OOP_BASE_ADDRESS("CodeInstaller::NARROW_OOP_BASE_ADDRESS"),
     CRC_TABLE_ADDRESS("CodeInstaller::CRC_TABLE_ADDRESS"),
     LOG_OF_HEAP_REGION_GRAIN_BYTES("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES"),
     INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED");
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Wed Jul 05 22:48:30 2017 +0200
@@ -57,6 +57,7 @@
             case HEAP_TOP_ADDRESS:
             case HEAP_END_ADDRESS:
             case NARROW_KLASS_BASE_ADDRESS:
+            case NARROW_OOP_BASE_ADDRESS:
             case CRC_TABLE_ADDRESS:
             case LOG_OF_HEAP_REGION_GRAIN_BYTES:
             case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
@@ -78,6 +79,9 @@
                     case NARROW_KLASS_BASE_ADDRESS:
                         vmSymbolName = binaryContainer.getNarrowKlassBaseAddressSymbolName();
                         break;
+                    case NARROW_OOP_BASE_ADDRESS:
+                        vmSymbolName = binaryContainer.getNarrowOopBaseAddressSymbolName();
+                        break;
                     case CRC_TABLE_ADDRESS:
                         vmSymbolName = binaryContainer.getCrcTableAddressSymbolName();
                         break;
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java	Mon Feb 06 17:19:06 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,332 +0,0 @@
-/*
- * 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.collect;
-
-import jdk.tools.jaotc.LogPrinter;
-import jdk.tools.jaotc.Main;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.*;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.*;
-
-import static java.nio.file.FileVisitResult.CONTINUE;
-
-public class ClassCollector {
-    private final Main.Options options;
-    private final LogPrinter log;
-
-    public ClassCollector(Main.Options options, LogPrinter log) {
-        this.options = options;
-        this.log = log;
-    }
-
-    /**
-     * Collect all class names passed by the user.
-     *
-     * @return array list of classes
-     */
-    public Set<Class<?>> collectClassesToCompile() {
-        Set<Class<?>> classes = new HashSet<>();
-        List<String> filesToScan = new LinkedList<>(options.files);
-
-        if (options.module != null) {
-            classes.addAll(scanModule(filesToScan));
-        }
-
-        classes.addAll(scanFiles(filesToScan));
-        return classes;
-    }
-
-    private Set<Class<?>> scanModule(List<String> filesToScan) {
-        String module = options.module;
-        // Search module in standard JDK installation.
-        Path dir = getModuleDirectory(options.modulepath, module);
-
-        if (Files.isDirectory(dir)) {
-            return loadFromModuleDirectory(dir);
-        } else {
-            findFilesToScan(filesToScan, module);
-            return new HashSet<>();
-        }
-    }
-
-    private Set<Class<?>> loadFromModuleDirectory(Path dir) {
-        log.printInfo("Scanning module: " + dir + " ...");
-        log.printlnVerbose(" "); // Break line
-
-        FileSystemFinder finder = new FileSystemFinder(dir, pathname -> entryIsClassFile(pathname.toString()));
-        Set<Class<?>> cls = loadWithClassLoader(() -> ClassLoader.getSystemClassLoader(), dir, finder);
-        log.printlnInfo(" " + cls.size() + " classes loaded.");
-        return cls;
-    }
-
-    private void findFilesToScan(List<String> filesToScan, String module) {
-        // Try to search regular directory, .jar or .class files
-        Path path = Paths.get(options.modulepath, module);
-
-        if (Files.isDirectory(path)) {
-            filesToScan.add(".");
-            options.classpath = path.toString();
-        } else if (path.endsWith(".jar") || path.endsWith(".class")) {
-            filesToScan.add(path.toString());
-        } else {
-            path = Paths.get(options.modulepath, module + ".jar");
-            if (Files.exists(path)) {
-                filesToScan.add(path.toString());
-            } else {
-                path = Paths.get(options.modulepath, module + ".class");
-                if (Files.exists(path)) {
-                    filesToScan.add(path.toString());
-                } else {
-                    throw new InternalError("Expecting a .class, .jar or directory: " + path);
-                }
-            }
-        }
-    }
-
-    private boolean entryIsClassFile(String entry) {
-        return entry.endsWith(".class") && !entry.endsWith("module-info.class");
-    }
-
-    private Set<Class<?>> scanFiles(List<String> filesToScan) {
-        Set<Class<?>> classes = new HashSet<>();
-        for (String fileName : filesToScan) {
-            Set<Class<?>> loaded = scanFile(fileName);
-            log.printlnInfo(" " + loaded.size() + " classes loaded.");
-            classes.addAll(loaded);
-        }
-        return classes;
-    }
-
-    interface ClassLoaderFactory {
-        ClassLoader create() throws IOException;
-    }
-
-    private Set<Class<?>> loadWithClassLoader(ClassLoaderFactory factory, Path root, FileSystemFinder finder) {
-        ClassLoader loader = null;
-        try {
-            loader = factory.create();
-            return loadClassFiles(root, finder, loader);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        } finally {
-            if (loader instanceof AutoCloseable) {
-                try {
-                    ((AutoCloseable) loader).close();
-                } catch (Exception e) {
-                    throw new InternalError(e);
-                }
-            }
-        }
-    }
-
-    private Set<Class<?>> scanFile(String fileName) {
-        log.printInfo("Scanning: " + fileName + " ...");
-        log.printlnVerbose(" "); // Break line
-
-        if (fileName.endsWith(".jar")) {
-            return loadFromJarFile(fileName);
-        } else if (fileName.endsWith(".class")) {
-            Set<Class<?>> classes = new HashSet<>();
-            loadFromClassFile(fileName, classes);
-            return classes;
-        } else {
-            return scanClassPath(fileName);
-        }
-    }
-
-    private Set<Class<?>> loadFromJarFile(String fileName) {
-        FileSystem fs = makeFileSystem(fileName);
-        FileSystemFinder finder = new FileSystemFinder(fs.getPath("/"), pathname -> entryIsClassFile(pathname.toString()));
-        return loadWithClassLoader(() -> URLClassLoader.newInstance(buildUrls(fileName)), fs.getPath("/"), finder);
-    }
-
-    private void loadFromClassFile(String fileName, Set<Class<?>> classes) {
-        Class<?> result;
-        File file = new File(options.classpath);
-        try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) {
-            result = loadClassFile(loader, fileName);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-        Class<?> c = result;
-        addClass(classes, fileName, c);
-    }
-
-    private Set<Class<?>> scanClassPath(String fileName) {
-        Path classPath = Paths.get(options.classpath);
-        if (!Files.exists(classPath)) {
-            throw new InternalError("Path does not exist: " + classPath);
-        }
-        if (!Files.isDirectory(classPath)) {
-            throw new InternalError("Path must be a directory: " + classPath);
-        }
-
-        // Combine class path and file name and see what it is.
-        Path combinedPath = Paths.get(options.classpath + File.separator + fileName);
-        if (combinedPath.endsWith(".class")) {
-            throw new InternalError("unimplemented");
-        } else if (Files.isDirectory(combinedPath)) {
-            return scanDirectory(classPath, combinedPath);
-        } else {
-            throw new InternalError("Expecting a .class, .jar or directory: " + fileName);
-        }
-    }
-
-    private FileSystem makeFileSystem(String fileName) {
-        try {
-            return FileSystems.newFileSystem(makeJarFileURI(fileName), new HashMap<>());
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private URI makeJarFileURI(String fileName) {
-        try {
-            return new URI("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/");
-        } catch (URISyntaxException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private PathMatcher combine(PathMatcher m1, PathMatcher m2) {
-        return path -> m1.matches(path) && m2.matches(path);
-    }
-
-    private Set<Class<?>> scanDirectory(Path classPath, Path combinedPath) {
-        String dir = options.classpath;
-
-        FileSystem fileSystem = FileSystems.getDefault();
-        PathMatcher matcher = fileSystem.getPathMatcher("glob:" + "*.class");
-        FileSystemFinder finder = new FileSystemFinder(combinedPath,
-            combine(matcher, pathname -> entryIsClassFile(pathname.toString())));
-
-        File file = new File(dir);
-        try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) {
-            return loadClassFiles(classPath, finder, loader);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private Set<Class<?>> loadClassFiles(Path root, FileSystemFinder finder, ClassLoader loader) {
-        Set<Class<?>> classes = new HashSet<>();
-        for (Path name : finder.done()) {
-            // Now relativize to the class path so we get the actual class names.
-            String entry = root.relativize(name).normalize().toString();
-            Class<?> c = loadClassFile(loader, entry);
-            addClass(classes, entry, c);
-        }
-        return classes;
-    }
-
-    private void addClass(Set<Class<?>> classes, String name, Class<?> c) {
-        if (c != null) {
-            classes.add(c);
-            log.printlnVerbose(" loaded " + name);
-        }
-    }
-
-    private URL[] buildUrls(String fileName) throws MalformedURLException {
-        return new URL[]{ new URL("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/") };
-    }
-
-    private URL[] buildUrls(File file) throws MalformedURLException {
-        return new URL[] {file.toURI().toURL() };
-    }
-
-    private Path getModuleDirectory(String modulepath, String module) {
-        FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
-        return fs.getPath(modulepath, module);
-    }
-
-    /**
-     * Loads a class with the given file name from the specified {@link URLClassLoader}.
-     */
-    private Class<?> loadClassFile(final ClassLoader loader, final String fileName) {
-        int start = 0;
-        if (fileName.startsWith("/")) {
-            start = 1;
-        }
-        String className = fileName.substring(start, fileName.length() - ".class".length());
-        className = className.replace('/', '.');
-        try {
-            return loader.loadClass(className);
-        } catch (Throwable e) {
-            // If we are running in JCK mode we ignore all exceptions.
-            if (options.ignoreClassLoadingErrors) {
-                log.printError(className + ": " + e);
-                return null;
-            }
-            throw new InternalError(e);
-        }
-    }
-
-    /**
-     * {@link FileVisitor} implementation to find class files recursively.
-     */
-    private static class FileSystemFinder extends SimpleFileVisitor<Path> {
-        private final ArrayList<Path> fileNames = new ArrayList<>();
-        private final PathMatcher filter;
-
-        FileSystemFinder(Path combinedPath, PathMatcher filter) {
-            this.filter = filter;
-            try {
-                Files.walkFileTree(combinedPath, this);
-            } catch (IOException e) {
-                throw new InternalError(e);
-            }
-        }
-
-        /**
-         * Compares the glob pattern against the file name.
-         */
-        void find(Path file) {
-            Path name = file.getFileName();
-            if (name != null && filter.matches(name)) {
-                fileNames.add(file);
-            }
-        }
-
-        List<Path> done() {
-            return fileNames;
-        }
-
-        @Override
-        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-            find(file);
-            return CONTINUE;
-        }
-
-        @Override
-        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-            find(dir);
-            return CONTINUE;
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+import jdk.tools.jaotc.LoadedClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassSearch {
+    private List<SourceProvider> providers = new ArrayList<>();
+
+    public void addProvider(SourceProvider provider) {
+        providers.add(provider);
+    }
+
+    public List<LoadedClass> search(List<SearchFor> search, SearchPath searchPath) {
+        List<LoadedClass> loaded = new ArrayList<>();
+
+        List<ClassSource> sources = new ArrayList<>();
+
+        for (SearchFor entry : search) {
+            sources.add(findSource(entry, searchPath));
+        }
+
+        for (ClassSource source : sources) {
+            source.eachClass((name, loader) -> loaded.add(loadClass(name, loader)));
+        }
+
+        return loaded;
+    }
+
+    private LoadedClass loadClass(String name, ClassLoader loader) {
+        try {
+            Class<?> clzz = loader.loadClass(name);
+            return new LoadedClass(name, clzz);
+        } catch (ClassNotFoundException e) {
+            throw new InternalError("Failed to load with: " + loader, e);
+        }
+    }
+
+    private ClassSource findSource(SearchFor searchFor, SearchPath searchPath) {
+        ClassSource found = null;
+
+        for (SourceProvider provider : providers) {
+            if (!searchFor.isUnknown() && !provider.supports(searchFor.getType())) {
+                continue;
+            }
+
+            ClassSource source = provider.findSource(searchFor.getName(), searchPath);
+            if (source != null) {
+                if (found != null) {
+                    throw new InternalError("Multiple possible sources: " + source + " and: " + found);
+                }
+                found = source;
+            }
+        }
+
+        if (found == null) {
+            throw new InternalError("Failed to find: " + searchFor.toString());
+        }
+        return found;
+    }
+
+    public static List<SearchFor> makeList(String type, String argument) {
+        List<SearchFor> list = new ArrayList<>();
+        String[] elements = argument.split(":");
+        for (String element : elements) {
+            list.add(new SearchFor(element, type));
+        }
+        return list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public interface ClassSource {
+    static boolean pathIsClassFile(Path entry) {
+        String fileName = entry.getFileName().toString();
+        return fileName.endsWith(".class") && !fileName.endsWith("module-info.class");
+    }
+
+    static String makeClassName(Path path) {
+        String fileName = path.toString();
+
+        if (!fileName.endsWith(".class")) {
+            throw new IllegalArgumentException("File doesn't end with .class: '" + fileName + "'");
+        }
+
+        int start = 0;
+        if (fileName.startsWith("/")) {
+            start = 1;
+        }
+
+        String className = fileName.substring(start, fileName.length() - ".class".length());
+        className = className.replace('/', '.');
+        return className;
+    }
+
+    void eachClass(BiConsumer<String, ClassLoader> consumer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+import java.io.IOException;
+import java.net.*;
+import java.nio.file.*;
+import java.util.HashMap;
+
+public class FileSupport {
+    public boolean exists(Path path)  {
+        return Files.exists(path);
+    }
+
+    public boolean isDirectory(Path path) {
+        return Files.isDirectory(path);
+    }
+
+    private FileSystem makeJarFileSystem(Path path) {
+        try {
+            return FileSystems.newFileSystem(makeJarFileURI(path), new HashMap<>());
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private URI makeJarFileURI(Path path) {
+        try {
+            return new URI("jar:file:" + path.toAbsolutePath() + "!/");
+        } catch (URISyntaxException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public ClassLoader createClassLoader(Path path, ClassLoader parent) {
+        try {
+            return URLClassLoader.newInstance(buildUrls(path), parent);
+        } catch (MalformedURLException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public ClassLoader createClassLoader(Path path) throws MalformedURLException {
+        return URLClassLoader.newInstance(buildUrls(path));
+    }
+
+    private URL[] buildUrls(Path path) throws MalformedURLException {
+        return new URL[] { path.toUri().toURL() };
+    }
+
+    public Path getJarFileSystemRoot(Path jarFile) {
+        FileSystem fileSystem = makeJarFileSystem(jarFile);
+        return fileSystem.getPath("/");
+    }
+
+    public boolean isAbsolute(Path entry) {
+        return entry.isAbsolute();
+    }
+
+    public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException {
+        DirectoryStream<Path> paths = fileSystem.provider().newDirectoryStream(root,null);
+        for (Path entry : paths) {
+            Path relative = root.relativize(entry);
+            if (relative.equals(path)) {
+                return entry;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+import java.io.IOException;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+/**
+ * {@link FileVisitor} implementation to find class files recursively.
+ */
+public class FileSystemFinder extends SimpleFileVisitor<Path> implements Iterable<Path> {
+    private final ArrayList<Path> fileNames = new ArrayList<>();
+    private final PathMatcher filter;
+
+    public FileSystemFinder(Path combinedPath, PathMatcher filter) {
+        this.filter = filter;
+        try {
+            Files.walkFileTree(combinedPath, this);
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    /**
+     * Compares the glob pattern against the file name.
+     */
+    private void find(Path file) {
+        Path name = file.getFileName();
+        if (name != null && filter.matches(name)) {
+            fileNames.add(file);
+        }
+    }
+
+    @Override
+    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+        find(file);
+        return CONTINUE;
+    }
+
+    @Override
+    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+        find(dir);
+        return CONTINUE;
+    }
+
+
+    @Override
+    public Iterator<Path> iterator() {
+        return fileNames.iterator();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+public class SearchFor {
+    private final String name;
+    private final String type;
+
+    public SearchFor(String name) {
+        this(name, "unknown");
+    }
+
+    public SearchFor(String name, String type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    public boolean isUnknown() {
+        return "unknown".equals(type);
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return type + ":" + name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchPath {
+    private final List<Path> searchPaths = new ArrayList<>();
+    private final FileSupport fileSupport;
+
+    public SearchPath() {
+        this(new FileSupport());
+    }
+
+    public SearchPath(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+    }
+
+    public Path find(FileSystem fileSystem, Path entry, String... defaults) {
+        if (isAbsolute(entry)) {
+            if (exists(entry)) {
+                return entry;
+            }
+            return null;
+        }
+
+        if (exists(entry)) {
+            return entry;
+        }
+
+        for (String searchPath : defaults) {
+            Path newPath = fileSystem.getPath(searchPath, entry.toString());
+            if (exists(newPath)) {
+                return newPath;
+            }
+        }
+
+        for (Path searchPath : searchPaths) {
+            Path newPath = fileSystem.getPath(searchPath.toString(), entry.toString());
+            if (exists(newPath)) {
+                return newPath;
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isAbsolute(Path entry) {
+        return fileSupport.isAbsolute(entry);
+    }
+
+    private boolean exists(Path entry) {
+        return fileSupport.exists(entry);
+    }
+
+    public void add(String... paths) {
+        for (String name : paths) {
+            Path path = Paths.get(name);
+            searchPaths.add(path);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect;
+
+public interface SourceProvider {
+    ClassSource findSource(String name, SearchPath searchPath);
+
+    boolean supports(String type);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.classname;
+
+import jdk.tools.jaotc.collect.ClassSource;
+
+import java.util.function.BiConsumer;
+
+public class ClassNameSource implements ClassSource {
+    private final String name;
+    private final ClassLoader classLoader;
+
+    public ClassNameSource(String name, ClassLoader classLoader) {
+        this.name = name;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        consumer.accept(name, classLoader);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.classname;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class ClassNameSourceProvider implements SourceProvider {
+    public final static String TYPE = "classname";
+    private final ClassLoader classLoader;
+
+    public ClassNameSourceProvider(FileSupport fileSupport) {
+        String classPath = System.getProperty("java.class.path");
+        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+        if (classPath != null && !classPath.isEmpty()) {
+            classLoader = systemClassLoader;
+        } else {
+            Path path = Paths.get(".").toAbsolutePath();
+            classLoader = fileSupport.createClassLoader(path, systemClassLoader);
+        }
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        try {
+            classLoader.loadClass(name);
+            return new ClassNameSource(name, classLoader);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.directory;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class DirectorySource implements ClassSource {
+    private final Path directoryPath;
+    private final ClassLoader classLoader;
+
+    public DirectorySource(Path directoryPath, ClassLoader classLoader) {
+        this.directoryPath = directoryPath;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(directoryPath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(directoryPath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "directory:" + directoryPath.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.directory;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.net.MalformedURLException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+public class DirectorySourceProvider implements SourceProvider {
+    private final FileSupport fileSupport;
+    private final FileSystem fileSystem;
+    public final static String TYPE = "directory";
+
+    public DirectorySourceProvider(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+        fileSystem = FileSystems.getDefault();
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path directoryPath = fileSystem.getPath(name);
+
+        if (!fileSupport.exists(directoryPath)) {
+            return null;
+        }
+        if (!fileSupport.isDirectory(directoryPath)) {
+            return null;
+        }
+
+        try {
+            ClassLoader classLoader = fileSupport.createClassLoader(directoryPath);
+            return new DirectorySource(directoryPath, classLoader);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.jar;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class JarFileSource implements ClassSource {
+    private final Path jarFile;
+    private final Path jarRootPath;
+    private final ClassLoader classLoader;
+
+
+    public JarFileSource(Path jarFile, Path jarRootPath, ClassLoader classLoader) {
+        this.jarFile = jarFile;
+        this.jarRootPath = jarRootPath;
+        this.classLoader = classLoader;
+    }
+
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(jarRootPath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(jarRootPath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "jar:" + jarFile.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.jar;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.net.MalformedURLException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.ProviderNotFoundException;
+
+public class JarSourceProvider implements SourceProvider {
+    private final FileSystem fileSystem;
+    private final FileSupport fileSupport;
+    public final static String TYPE = "jar";
+
+    public JarSourceProvider() {
+        this(new FileSupport());
+    }
+
+    public JarSourceProvider(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+        fileSystem = FileSystems.getDefault();
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path fileName = fileSystem.getPath(name);
+        Path jarFile = searchPath.find(fileSystem, fileName);
+
+        if (!validPath(jarFile)) {
+            return null;
+        }
+
+        return createSource(jarFile);
+    }
+
+    private ClassSource createSource(Path jarFile) {
+        try {
+            Path jarRootPath = fileSupport.getJarFileSystemRoot(jarFile);
+            if (jarRootPath == null) {
+                return null;
+            }
+            ClassLoader classLoader = fileSupport.createClassLoader(jarFile);
+            return new JarFileSource(jarFile, jarRootPath, classLoader);
+        } catch (ProviderNotFoundException | MalformedURLException e) {
+        }
+        return null;
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+
+    private boolean validPath(Path jarFile) {
+        return jarFile != null && !fileSupport.isDirectory(jarFile);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.module;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class ModuleSource implements ClassSource {
+    private final Path modulePath;
+    private final ClassLoader classLoader;
+
+    public ModuleSource(Path modulePath, ClassLoader classLoader) {
+        this.modulePath = modulePath;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(modulePath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(modulePath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    public Path getModulePath() {
+        return modulePath;
+    }
+
+    @Override
+    public String toString() {
+        return "module:" + modulePath.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 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.
+ */
+package jdk.tools.jaotc.collect.module;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+public class ModuleSourceProvider implements SourceProvider {
+    private final FileSystem fileSystem;
+    private final ClassLoader classLoader;
+    private final FileSupport fileSupport;
+    public final static String TYPE = "module";
+
+    public ModuleSourceProvider() {
+        this(FileSystems.getFileSystem(URI.create("jrt:/")), ClassLoader.getSystemClassLoader(), new FileSupport());
+    }
+
+    public ModuleSourceProvider(FileSystem fileSystem, ClassLoader classLoader, FileSupport fileSupport) {
+        this.fileSystem = fileSystem;
+        this.classLoader = classLoader;
+        this.fileSupport = fileSupport;
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path path = fileSystem.getPath(name);
+        Path dir = fileSystem.getPath("modules");
+
+        if (dir == null || !fileSupport.isDirectory(dir)) {
+            return null;
+        }
+
+        Path found = findModuleDirectory(dir, path);
+
+        if (found == null) {
+            return null;
+        }
+
+        return new ModuleSource(found, classLoader);
+    }
+
+    private Path findModuleDirectory(Path root, Path path) {
+        try {
+            return fileSupport.getSubDirectory(fileSystem, root, path);
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Wed Jul 05 22:48:30 2017 +0200
@@ -100,15 +100,19 @@
     native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Determines if {@code method} can be inlined. A method may not be inlinable for a number of
-     * reasons such as:
-     * <ul>
-     * <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
-     * <li>the method may have a bytecode breakpoint set</li>
-     * <li>the method may have other bytecode features that require special handling by the VM</li>
-     * </ul>
+     * Determines whether {@code method} is currently compilable by the JVMCI compiler being used by
+     * the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a
+     * breakpoint is currently set in {@code method} or {@code method} contains other bytecode
+     * features that require special handling by the VM.
      */
-    native boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
+    native boolean isCompilable(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Determines if {@code method} is targeted by a VM directive (e.g.,
+     * {@code -XX:CompileCommand=dontinline,<pattern>}) or annotation (e.g.,
+     * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
+     */
+    native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Determines if {@code method} should be inlined at any cost. This could be because:
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Wed Jul 05 22:48:30 2017 +0200
@@ -50,13 +50,6 @@
     boolean isForceInline();
 
     /**
-     * Returns true if this method has a {@code DontInline} annotation.
-     *
-     * @return true if DontInline annotation present, false otherwise
-     */
-    boolean isDontInline();
-
-    /**
      * Returns true if this method has a {@code ReservedStackAccess} annotation.
      *
      * @return true if ReservedStackAccess annotation present, false otherwise
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Wed Jul 05 22:48:30 2017 +0200
@@ -299,15 +299,6 @@
     }
 
     /**
-     * Returns true if this method has a {@code DontInline} annotation.
-     *
-     * @return true if DontInline annotation present, false otherwise
-     */
-    public boolean isDontInline() {
-        return (getFlags() & config().methodFlagsDontInline) != 0;
-    }
-
-    /**
      * Returns true if this method has a {@code ReservedStackAccess} annotation.
      *
      * @return true if ReservedStackAccess annotation present, false otherwise
@@ -582,10 +573,15 @@
 
     @Override
     public boolean canBeInlined() {
-        if (isDontInline()) {
+        if (hasNeverInlineDirective()) {
             return false;
         }
-        return compilerToVM().canInlineMethod(this);
+        return compilerToVM().isCompilable(this);
+    }
+
+    @Override
+    public boolean hasNeverInlineDirective() {
+        return compilerToVM().hasNeverInlineDirective(this);
     }
 
     @Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Wed Jul 05 22:48:30 2017 +0200
@@ -347,6 +347,13 @@
     boolean canBeInlined();
 
     /**
+     * Determines if this method is targeted by a VM directive (e.g.,
+     * {@code -XX:CompileCommand=dontinline,<pattern>}) or VM recognized annotation (e.g.,
+     * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
+     */
+    boolean hasNeverInlineDirective();
+
+    /**
      * Returns {@code true} if the inlining of this method should be forced.
      */
     boolean shouldBeInlined();
--- a/hotspot/src/jdk.vm.compiler/.mx.graal/suite.py	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/.mx.graal/suite.py	Wed Jul 05 22:48:30 2017 +0200
@@ -638,6 +638,7 @@
       "annotationProcessors" : [
         "GRAAL_NODEINFO_PROCESSOR",
         "GRAAL_REPLACEMENTS_VERIFIER",
+        "GRAAL_OPTIONS_PROCESSOR",
       ],
       "workingSets" : "Graal,Graph",
     },
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java	Wed Jul 05 22:48:30 2017 +0200
@@ -116,6 +116,7 @@
     public static final int INFO_LOG_LEVEL = 2;
     public static final int VERBOSE_LOG_LEVEL = 3;
     public static final int DETAILED_LOG_LEVEL = 4;
+    public static final int VERY_DETAILED_LOG_LEVEL = 5;
 
     public static boolean isDumpEnabled(int dumpLevel) {
         return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel);
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Wed Jul 05 22:48:30 2017 +0200
@@ -267,10 +267,15 @@
 
             if (config.useCompressedClassPointers) {
                 Register register = r10;
-                AMD64HotSpotMove.decodeKlassPointer(asm, register, providers.getRegisters().getHeapBaseRegister(), src, config.getKlassEncoding());
-                if (config.narrowKlassBase != 0) {
-                    // The heap base register was destroyed above, so restore it
-                    asm.movq(providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase);
+                AMD64HotSpotMove.decodeKlassPointer(crb, asm, register, providers.getRegisters().getHeapBaseRegister(), src, config);
+                if (GeneratePIC.getValue()) {
+                    asm.movq(providers.getRegisters().getHeapBaseRegister(), asm.getPlaceholder(-1));
+                    crb.recordMark(config.MARKID_NARROW_OOP_BASE_ADDRESS);
+                } else {
+                    if (config.narrowKlassBase != 0) {
+                        // The heap base register was destroyed above, so restore it
+                        asm.movq(providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase);
+                    }
                 }
                 asm.cmpq(inlineCacheKlass, register);
             } else {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Wed Jul 05 22:48:30 2017 +0200
@@ -265,14 +265,21 @@
         }
     }
 
-    public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, CompressEncoding encoding) {
+    public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
+        CompressEncoding encoding = config.getKlassEncoding();
         masm.movl(register, address);
         if (encoding.shift != 0) {
             assert encoding.alignment == encoding.shift : "Decode algorithm is wrong";
             masm.shlq(register, encoding.alignment);
         }
-        if (encoding.base != 0) {
-            masm.movq(scratch, encoding.base);
+        if (GeneratePIC.getValue() || encoding.base != 0) {
+            if (GeneratePIC.getValue()) {
+                masm.movq(scratch, masm.getPlaceholder(-1));
+                crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+            } else {
+                assert encoding.base != 0;
+                masm.movq(scratch, encoding.base);
+            }
             masm.addq(register, scratch);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java	Wed Jul 05 22:48:30 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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.
+ */
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+
+public class AOTGraalHotSpotVMConfig extends GraalHotSpotVMConfig {
+    private final CompressEncoding aotOopEncoding;
+    private final CompressEncoding aotKlassEncoding;
+
+    public AOTGraalHotSpotVMConfig(HotSpotVMConfigStore store) {
+        super(store);
+        // In AOT, force the shift to be always equal to alignment therefore avoiding zero-shift.
+        CompressEncoding vmOopEncoding = super.getOopEncoding();
+        aotOopEncoding = new CompressEncoding(vmOopEncoding.base, vmOopEncoding.alignment, vmOopEncoding.alignment);
+        CompressEncoding vmKlassEncoding = super.getKlassEncoding();
+        aotKlassEncoding = new CompressEncoding(vmKlassEncoding.base, vmKlassEncoding.alignment, vmKlassEncoding.alignment);
+        assert check();
+    }
+
+    @Override
+    public CompressEncoding getOopEncoding() {
+        return aotOopEncoding;
+    }
+
+    @Override
+    public CompressEncoding getKlassEncoding() {
+        return aotKlassEncoding;
+    }
+}
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Wed Jul 05 22:48:30 2017 +0200
@@ -479,7 +479,6 @@
     public final int methodCompiledEntryOffset = getFieldOffset("Method::_from_compiled_entry", Integer.class, "address");
     public final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, isJDK8 ? "nmethod*" : "CompiledMethod*");
 
-    public final int methodFlagsJfrTowrite = getConstant("Method::_jfr_towrite", Integer.class);
     public final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
     public final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
     public final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class);
@@ -773,13 +772,14 @@
     public final int MARKID_HEAP_TOP_ADDRESS = getConstant("CodeInstaller::HEAP_TOP_ADDRESS", Integer.class, 17);
     public final int MARKID_HEAP_END_ADDRESS = getConstant("CodeInstaller::HEAP_END_ADDRESS", Integer.class, 18);
     public final int MARKID_NARROW_KLASS_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_KLASS_BASE_ADDRESS", Integer.class, 19);
-    public final int MARKID_CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 20);
-    public final int MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 21);
-    public final int MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = getConstant("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED", Integer.class, 22);
+    public final int MARKID_NARROW_OOP_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_OOP_BASE_ADDRESS", Integer.class, 20);
+    public final int MARKID_CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 21);
+    public final int MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 22);
+    public final int MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = getConstant("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED", Integer.class, 23);
 
     // Checkstyle: resume
 
-    private boolean check() {
+    protected boolean check() {
         for (Field f : getClass().getDeclaredFields()) {
             int modifiers = f.getModifiers();
             if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Wed Jul 05 22:48:30 2017 +0200
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.debug.GraalDebugConfig.areScopedGlobalMetricsEnabled;
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.DebugValueSummary;
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.Dump;
@@ -99,7 +100,7 @@
     HotSpotGraalRuntime(HotSpotJVMCIRuntime jvmciRuntime, CompilerConfigurationFactory compilerConfigurationFactory) {
 
         HotSpotVMConfigStore store = jvmciRuntime.getConfigStore();
-        config = new GraalHotSpotVMConfig(store);
+        config = GeneratePIC.getValue() ? new AOTGraalHotSpotVMConfig(store) : new GraalHotSpotVMConfig(store);
         CompileTheWorldOptions.overrideWithNativeOptions(config);
 
         // Only set HotSpotPrintInlining if it still has its default value (false).
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Wed Jul 05 22:48:30 2017 +0200
@@ -22,7 +22,6 @@
  */
 package org.graalvm.compiler.hotspot.meta;
 
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
 import static org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider.FieldReadEnabledInImmutableCode;
 
@@ -112,11 +111,6 @@
                 return true;
             }
         }
-        if (GeneratePIC.getValue()) {
-            if (field.isSynthetic() && field.getName().startsWith("$assertionsDisabled")) {
-                return tryReadField(b, field, null);
-            }
-        }
         if (b.parsingIntrinsic() && wordOperationPlugin.handleLoadStaticField(b, field)) {
             return true;
         }
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Wed Jul 05 22:48:30 2017 +0200
@@ -1738,9 +1738,8 @@
             } else {
                 // Intrinsic was not applied: remove intrinsic guard
                 // and restore the original receiver node in the arguments array
-                for (Node node : graph.getNewNodes(intrinsicGuard.mark)) {
-                    GraphUtil.killCFG(node);
-                }
+                intrinsicGuard.lastInstr.setNext(null);
+                GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
                 lastInstr = intrinsicGuard.lastInstr;
                 args[0] = intrinsicGuard.receiver;
             }
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java	Wed Jul 05 22:48:30 2017 +0200
@@ -153,9 +153,7 @@
         }
 
         for (Node node : methodScope.graph.getNewNodes(methodScope.methodStartMark)) {
-            if (!(node instanceof FixedNode) && node.hasNoUsages()) {
-                GraphUtil.killCFG(node);
-            }
+            GraphUtil.tryKillUnused(node);
         }
     }
 
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Wed Jul 05 22:48:30 2017 +0200
@@ -506,7 +506,7 @@
         for (Node successor : snapshot) {
             if (successor != null && successor.isAlive()) {
                 if (successor != survivingSuccessor) {
-                    GraphUtil.killCFG(successor, tool);
+                    GraphUtil.killCFG((FixedNode) successor, tool);
                 }
             }
         }
@@ -566,6 +566,9 @@
             reduceTrivialMerge(begin);
         } else { // convert to merge
             AbstractMergeNode merge = this.add(new MergeNode());
+            for (EndNode end : begin.forwardEnds()) {
+                merge.addForwardEnd(end);
+            }
             this.replaceFixedWithFixed(begin, merge);
         }
     }
@@ -576,7 +579,14 @@
         for (PhiNode phi : merge.phis().snapshot()) {
             assert phi.valueCount() == 1;
             ValueNode singleValue = phi.valueAt(0);
-            phi.replaceAtUsagesAndDelete(singleValue);
+            if (phi.hasUsages()) {
+                phi.replaceAtUsagesAndDelete(singleValue);
+            } else {
+                phi.safeDelete();
+                if (singleValue != null) {
+                    GraphUtil.tryKillUnused(singleValue);
+                }
+            }
         }
         // remove loop exits
         if (merge instanceof LoopBeginNode) {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Wed Jul 05 22:48:30 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,18 +22,30 @@
  */
 package org.graalvm.compiler.nodes.util;
 
+import static org.graalvm.compiler.graph.Graph.Options.VerifyGraalGraphEdges;
+import static org.graalvm.compiler.nodes.util.GraphUtil.Options.VerifyKillCFGUnusedNodes;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.Set;
 
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.code.SourceStackTraceBailoutException;
+import org.graalvm.compiler.core.common.CollectionsFactory;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.debug.Debug;
+import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeWorkList;
+import org.graalvm.compiler.graph.Position;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.graph.spi.SimplifierTool;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractEndNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -48,11 +60,15 @@
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
 import org.graalvm.compiler.nodes.spi.LimitedValueProxy;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.ValueProxy;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionType;
+import org.graalvm.compiler.options.OptionValue;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.BytecodePosition;
@@ -64,22 +80,78 @@
 
 public class GraphUtil {
 
-    public static void killCFG(Node node, SimplifierTool tool) {
-        NodeWorkList worklist = killCFG(node, tool, null);
-        if (worklist != null) {
-            for (Node successor : worklist) {
-                killCFG(successor, tool, worklist);
+    public static class Options {
+        @Option(help = "Verify that there are no new unused nodes when performing killCFG", type = OptionType.Debug)//
+        public static final OptionValue<Boolean> VerifyKillCFGUnusedNodes = new OptionValue<>(false);
+    }
+
+    @SuppressWarnings("try")
+    public static void killCFG(FixedNode node, SimplifierTool tool) {
+        try (Debug.Scope scope = Debug.scope("KillCFG", node)) {
+            Set<Node> unusedNodes = null;
+            Set<Node> unsafeNodes = null;
+            Graph.NodeEventScope nodeEventScope = null;
+            if (VerifyGraalGraphEdges.getValue()) {
+                unsafeNodes = collectUnsafeNodes(node.graph());
+            }
+            if (VerifyKillCFGUnusedNodes.getValue()) {
+                Set<Node> collectedUnusedNodes = unusedNodes = CollectionsFactory.newSet();
+                nodeEventScope = node.graph().trackNodeEvents(new Graph.NodeEventListener() {
+                    @Override
+                    public void event(Graph.NodeEvent e, Node n) {
+                        if (e == Graph.NodeEvent.ZERO_USAGES && isFloatingNode(n)) {
+                            collectedUnusedNodes.add(n);
+                        }
+                    }
+                });
+            }
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, node.graph(), "Before killCFG %s", node);
+            NodeWorkList worklist = killCFG(node, tool, null);
+            if (worklist != null) {
+                for (Node n : worklist) {
+                    killCFG(n, tool, worklist);
+                }
+            }
+            if (VerifyGraalGraphEdges.getValue()) {
+                Set<Node> newUnsafeNodes = collectUnsafeNodes(node.graph());
+                newUnsafeNodes.removeAll(unsafeNodes);
+                assert newUnsafeNodes.isEmpty() : "New unsafe nodes: " + newUnsafeNodes;
+            }
+            if (VerifyKillCFGUnusedNodes.getValue()) {
+                nodeEventScope.close();
+                unusedNodes.removeIf(n -> n.isDeleted());
+                assert unusedNodes.isEmpty() : "New unused nodes: " + unusedNodes;
+            }
+        } catch (Throwable t) {
+            throw Debug.handle(t);
+        }
+    }
+
+    /**
+     * Collects all node in the graph which have non-optional inputs that are null.
+     */
+    private static Set<Node> collectUnsafeNodes(Graph graph) {
+        Set<Node> unsafeNodes = CollectionsFactory.newSet();
+        for (Node n : graph.getNodes()) {
+            for (Position pos : n.inputPositions()) {
+                Node input = pos.get(n);
+                if (input == null) {
+                    if (!pos.isInputOptional()) {
+                        unsafeNodes.add(n);
+                    }
+                }
             }
         }
+        return unsafeNodes;
     }
 
     private static NodeWorkList killCFG(Node node, SimplifierTool tool, NodeWorkList worklist) {
         NodeWorkList newWorklist = worklist;
-        // DebugScope.forceDump(node.graph(), "kill CFG %s", node);
         if (node instanceof FixedNode) {
             newWorklist = killCFGLinear((FixedNode) node, newWorklist, tool);
         } else {
-            propagateKill(node);
+            newWorklist = propagateKill(node, newWorklist);
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, node.graph(), "killCFG (Floating) %s", node);
         }
         return newWorklist;
     }
@@ -93,19 +165,20 @@
             if (current instanceof AbstractEndNode) {
                 // We reached a control flow end.
                 AbstractEndNode end = (AbstractEndNode) current;
-                killEnd(end, tool);
+                newWorklist = killEnd(end, newWorklist, tool);
             } else if (current instanceof FixedWithNextNode) {
-                next = ((FixedWithNextNode) current).next();
+                // Node guaranteed to have a single successor
+                FixedWithNextNode fixedWithNext = (FixedWithNextNode) current;
+                assert fixedWithNext.successors().count() == 1 || fixedWithNext.successors().count() == 0;
+                assert fixedWithNext.successors().first() == fixedWithNext.next();
+                next = fixedWithNext.next();
             } else {
-                // Normal control flow node.
                 /*
                  * We do not take a successor snapshot because this iterator supports concurrent
                  * modifications as long as they do not change the size of the successor list. Not
                  * taking a snapshot allows us to see modifications to other branches that may
                  * happen while processing one branch.
                  */
-                // assert node.successors().count() > 1 || node.successors().count() == 0 :
-                // node.getClass();
                 Iterator<Node> successors = current.successors().iterator();
                 if (successors.hasNext()) {
                     Node first = successors.next();
@@ -126,100 +199,158 @@
                 }
             }
             current.replaceAtPredecessor(null);
-            propagateKill(current);
+            newWorklist = propagateKill(current, newWorklist);
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, current.graph(), "killCFGLinear %s", current);
             current = next;
         }
+        Debug.dump(Debug.DETAILED_LOG_LEVEL, in.graph(), "killCFGLinear %s", in);
         return newWorklist;
     }
 
-    public static void killCFG(Node node) {
+    public static void killCFG(FixedNode node) {
         killCFG(node, null);
     }
 
-    private static void killEnd(AbstractEndNode end, SimplifierTool tool) {
+    /**
+     * Node type used temporarily while deleting loops.
+     *
+     * It is used as replacement for the loop {@link PhiNode PhiNodes} in order to break data-flow
+     * cycles before deleting the loop. The control-flow of the whole loop is killed before killing
+     * the poison node if they are still alive.
+     */
+    @NodeInfo(allowedUsageTypes = InputType.Unchecked)
+    private static final class PoisonNode extends FloatingNode {
+        public static final NodeClass<PoisonNode> TYPE = NodeClass.create(PoisonNode.class);
+
+        protected PoisonNode() {
+            super(TYPE, StampFactory.forVoid());
+        }
+    }
+
+    private static NodeWorkList killEnd(AbstractEndNode end, NodeWorkList worklist, SimplifierTool tool) {
+        NodeWorkList newWorklist = worklist;
         AbstractMergeNode merge = end.merge();
         if (merge != null) {
             merge.removeEnd(end);
             StructuredGraph graph = end.graph();
             if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) {
                 // dead loop
-                for (PhiNode phi : merge.phis().snapshot()) {
-                    propagateKill(phi);
-                }
                 LoopBeginNode begin = (LoopBeginNode) merge;
                 // disconnect and delete loop ends & loop exits
                 for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
                     loopend.predecessor().replaceFirstSuccessor(loopend, null);
                     loopend.safeDelete();
                 }
+                // clean unused proxies to avoid creating new unused nodes
+                for (LoopExitNode exit : begin.loopExits()) {
+                    for (ProxyNode vpn : exit.proxies().snapshot()) {
+                        tryKillUnused(vpn);
+                    }
+                }
                 begin.removeExits();
+                PoisonNode poison = null;
+                if (merge.phis().isNotEmpty()) {
+                    poison = graph.unique(new PoisonNode());
+                    for (PhiNode phi : merge.phis()) {
+                        phi.replaceAtUsages(poison);
+                    }
+                    for (PhiNode phi : merge.phis().snapshot()) {
+                        killWithUnusedFloatingInputs(phi);
+                    }
+                }
                 FixedNode loopBody = begin.next();
-                if (loopBody != null) { // for small infinite loops, the body may be killed while
-                                        // killing the loop ends
-                    killCFG(loopBody);
+                Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, end.graph(), "killEnd (Loop) %s after initial loop cleanup", end);
+                if (loopBody != null) {
+                    // for small infinite loops, the body may already be killed while killing the
+                    // LoopEnds
+                    newWorklist = killCFG(loopBody, tool, worklist);
                 }
+                FrameState frameState = begin.stateAfter();
                 begin.safeDelete();
+                if (frameState != null) {
+                    tryKillUnused(frameState);
+                }
+                if (poison != null && poison.isAlive()) {
+                    if (newWorklist == null) {
+                        newWorklist = graph.createNodeWorkList();
+                    }
+                    // drain the worklist to finish the loop before adding the poison
+                    for (Node n : newWorklist) {
+                        killCFG(n, tool, newWorklist);
+                    }
+                    if (poison.isAlive()) {
+                        newWorklist.add(poison);
+                    }
+                }
             } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) {
                 // not a loop anymore
                 if (tool != null) {
-                    merge.phis().forEach(phi -> tool.addToWorkList(phi.usages()));
+                    for (PhiNode phi : merge.phis()) {
+                        tool.addToWorkList(phi.usages());
+                    }
                 }
                 graph.reduceDegenerateLoopBegin((LoopBeginNode) merge);
             } else if (merge.phiPredecessorCount() == 1) {
                 // not a merge anymore
                 if (tool != null) {
-                    merge.phis().forEach(phi -> tool.addToWorkList(phi.usages()));
+                    for (PhiNode phi : merge.phis()) {
+                        tool.addToWorkList(phi.usages());
+                    }
                 }
                 graph.reduceTrivialMerge(merge);
             }
         }
+        return newWorklist;
     }
 
     public static boolean isFloatingNode(Node n) {
         return !(n instanceof FixedNode);
     }
 
-    private static void propagateKill(Node node) {
+    private static NodeWorkList propagateKill(Node node, NodeWorkList workList) {
+        NodeWorkList newWorkList = workList;
         if (node != null && node.isAlive()) {
-            node.markDeleted();
-
-            for (Node in : node.inputs()) {
-                if (in.isAlive()) {
-                    in.removeUsage(node);
-                    if (in.hasNoUsages() && !(in instanceof FixedNode)) {
-                        killWithUnusedFloatingInputs(in);
+            for (Node usage : node.usages().snapshot()) {
+                assert usage.isAlive();
+                if (isFloatingNode(usage)) {
+                    boolean addUsage = false;
+                    if (usage instanceof PhiNode) {
+                        PhiNode phi = (PhiNode) usage;
+                        assert phi.merge() != null;
+                        if (phi.merge() == node) {
+                            // we reach the phi directly through he merge, queue it.
+                            addUsage = true;
+                        } else {
+                            // we reach it though a value
+                            assert phi.values().contains(node);
+                            // let that be handled when we reach the corresponding End node
+                        }
+                    } else {
+                        addUsage = true;
+                    }
+                    if (addUsage) {
+                        if (newWorkList == null) {
+                            newWorkList = node.graph().createNodeWorkList();
+                        }
+                        newWorkList.add(usage);
                     }
                 }
+                usage.replaceFirstInput(node, null);
             }
+            killWithUnusedFloatingInputs(node);
+        }
+        return newWorkList;
+    }
 
-            ArrayList<Node> usageToKill = null;
-            for (Node usage : node.usages()) {
-                if (usage.isAlive() && !(usage instanceof FixedNode)) {
-                    if (usageToKill == null) {
-                        usageToKill = new ArrayList<>();
-                    }
-                    usageToKill.add(usage);
-                }
-            }
-            if (usageToKill != null) {
-                for (Node usage : usageToKill) {
-                    if (usage.isAlive()) {
-                        if (usage instanceof PhiNode) {
-                            PhiNode phiNode = (PhiNode) usage;
-                            usage.replaceFirstInput(node, null);
-                            if (phiNode.merge() == null || !phiNode.hasValidInput()) {
-                                propagateKill(usage);
-                            }
-                        } else {
-                            propagateKill(usage);
-                        }
-                    }
-                }
-            }
-        }
+    private static boolean checkKill(Node node) {
+        node.assertTrue(node.isAlive(), "must be alive");
+        node.assertTrue(node.hasNoUsages(), "cannot kill node %s because of usages: %s", node, node.usages());
+        node.assertTrue(node.predecessor() == null, "cannot kill node %s because of predecessor: %s", node, node.predecessor());
+        return true;
     }
 
     public static void killWithUnusedFloatingInputs(Node node) {
+        assert checkKill(node);
         node.markDeleted();
         outer: for (Node in : node.inputs()) {
             if (in.isAlive()) {
@@ -227,7 +358,7 @@
                 if (in.hasNoUsages()) {
                     node.maybeNotifyZeroUsages(in);
                 }
-                if (!(in instanceof FixedNode)) {
+                if (isFloatingNode(in)) {
                     if (in.hasNoUsages()) {
                         killWithUnusedFloatingInputs(in);
                     } else if (in instanceof PhiNode) {
@@ -244,6 +375,35 @@
         }
     }
 
+    /**
+     * Removes all nodes created after the {@code mark}, assuming no "old" nodes point to "new"
+     * nodes.
+     */
+    public static void removeNewNodes(Graph graph, Graph.Mark mark) {
+        assert checkNoOldToNewEdges(graph, mark);
+        for (Node n : graph.getNewNodes(mark)) {
+            n.markDeleted();
+            for (Node in : n.inputs()) {
+                in.removeUsage(n);
+            }
+        }
+    }
+
+    private static boolean checkNoOldToNewEdges(Graph graph, Graph.Mark mark) {
+        for (Node old : graph.getNodes()) {
+            if (graph.isNew(mark, old)) {
+                break;
+            }
+            for (Node n : old.successors()) {
+                assert !graph.isNew(mark, n) : old + " -> " + n;
+            }
+            for (Node n : old.inputs()) {
+                assert !graph.isNew(mark, n) : old + " -> " + n;
+            }
+        }
+        return true;
+    }
+
     public static void removeFixedWithUnusedInputs(FixedWithNextNode fixed) {
         if (fixed instanceof StateSplit) {
             FrameState stateAfter = ((StateSplit) fixed).stateAfter();
@@ -688,8 +848,9 @@
 
         @Override
         public void deleteBranch(Node branch) {
-            branch.predecessor().replaceFirstSuccessor(branch, null);
-            GraphUtil.killCFG(branch, this);
+            FixedNode fixedBranch = (FixedNode) branch;
+            fixedBranch.predecessor().replaceFirstSuccessor(fixedBranch, null);
+            GraphUtil.killCFG(fixedBranch, this);
         }
 
         @Override
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Wed Jul 05 22:48:30 2017 +0200
@@ -444,8 +444,9 @@
 
             @Override
             public void deleteBranch(Node branch) {
-                branch.predecessor().replaceFirstSuccessor(branch, null);
-                GraphUtil.killCFG(branch, this);
+                FixedNode fixedBranch = (FixedNode) branch;
+                fixedBranch.predecessor().replaceFirstSuccessor(fixedBranch, null);
+                GraphUtil.killCFG(fixedBranch, this);
             }
 
             @Override
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 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
@@ -632,7 +632,6 @@
   sigaddset(&unblocked_sigs, SIGBUS);
   sigaddset(&unblocked_sigs, SIGFPE);
   sigaddset(&unblocked_sigs, SIGTRAP);
-  sigaddset(&unblocked_sigs, SIGDANGER);
   sigaddset(&unblocked_sigs, SR_signum);
 
   if (!ReduceSignalUsage) {
@@ -1553,6 +1552,8 @@
   print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
   print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
   print_signal_handler(st, SIGTRAP, buf, buflen);
+  // We also want to know if someone else adds a SIGDANGER handler because
+  // that will interfere with OOM killling.
   print_signal_handler(st, SIGDANGER, buf, buflen);
 }
 
@@ -3156,7 +3157,6 @@
     set_signal_handler(SIGFPE, true);
     set_signal_handler(SIGTRAP, true);
     set_signal_handler(SIGXFSZ, true);
-    set_signal_handler(SIGDANGER, true);
 
     if (libjsig_is_loaded) {
       // Tell libjsig jvm finishes setting signal handlers.
@@ -3273,7 +3273,6 @@
   if (UseSIGTRAP) {
     DO_SIGNAL_CHECK(SIGTRAP);
   }
-  DO_SIGNAL_CHECK(SIGDANGER);
 
   // ReduceSignalUsage allows the user to override these handlers
   // see comments at the very top and jvm_solaris.h
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -778,6 +778,11 @@
   // is already attached to a debugger; debugger must observe
   // the exception below to show the correct name.
 
+  // If there is no debugger attached skip raising the exception
+  if (!IsDebuggerPresent()) {
+    return;
+  }
+
   const DWORD MS_VC_EXCEPTION = 0x406D1388;
   struct {
     DWORD dwType;     // must be 0x1000
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 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
@@ -258,13 +258,6 @@
     }
   }
 
-  // Handle SIGDANGER right away. AIX would raise SIGDANGER whenever available swap
-  // space falls below 30%. This is only a chance for the process to gracefully abort.
-  // We can't hope to proceed after SIGDANGER since SIGKILL tailgates.
-  if (sig == SIGDANGER) {
-    goto report_and_die;
-  }
-
   if (info == NULL || uc == NULL || thread == NULL && vmthread == NULL) {
     goto run_chained_handler;
   }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -87,6 +87,7 @@
 #define SPELL_REG_FP "rbp"
 #else
 #define REG_FP 29
+#define REG_LR 30
 
 #define SPELL_REG_SP "sp"
 #define SPELL_REG_FP "x29"
@@ -182,6 +183,46 @@
   return frame(sp, fp, epc.pc());
 }
 
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      // In compiled code, the stack banging is performed before LR
+      // has been saved in the frame.  LR is live, and SP and FP
+      // belong to the caller.
+      intptr_t* fp = os::Linux::ucontext_get_fp(uc);
+      intptr_t* sp = os::Linux::ucontext_get_sp(uc);
+      address pc = (address)(uc->uc_mcontext.regs[REG_LR]
+                         - NativeInstruction::instruction_size);
+      *fr = frame(sp, fp, pc);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 // By default, gcc always saves frame pointer rfp on this stack. This
 // may get turned off by -fomit-frame-pointer.
 frame os::get_sender_for_C_frame(frame* fr) {
@@ -313,6 +354,24 @@
         if (thread->in_stack_yellow_reserved_zone(addr)) {
           thread->disable_stack_yellow_reserved_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Java frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)(
+                      activation.fp() + frame::interpreter_frame_initial_sp_offset));
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.  Guard pages will be reenabled
             // while unwinding the stack.
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
--- a/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp	Mon Feb 06 17:19:06 2017 -0800
+++ b/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp	Wed Jul 05 22:48:30 2017 +0200
@@ -144,6 +144,42 @@
   return frame(sp, epc.pc());
 }
 
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // Interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // More complex code with compiled code.
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->