http-client-branch: merge http-client-branch
authorchegar
Thu, 16 Nov 2017 12:15:55 +0000
branchhttp-client-branch
changeset 55820 76d033c9908f
parent 55819 18e431209168 (current diff)
parent 47825 13e39ca700d0 (diff)
child 55821 fa0fc03c0853
http-client-branch: merge
src/hotspot/.mx.jvmci/.project
src/hotspot/.mx.jvmci/.pydevproject
src/hotspot/cpu/aarch64/jni_aarch64.h
src/hotspot/cpu/arm/jni_arm.h
src/hotspot/cpu/ppc/jni_ppc.h
src/hotspot/cpu/s390/jni_s390.h
src/hotspot/cpu/sparc/jni_sparc.h
src/hotspot/cpu/x86/jni_x86.h
src/hotspot/cpu/zero/jni_zero.h
src/hotspot/os/aix/jvm_aix.h
src/hotspot/os/bsd/jvm_bsd.h
src/hotspot/os/linux/jvm_linux.h
src/hotspot/os/solaris/jvm_solaris.h
src/hotspot/os/windows/jvm_windows.h
src/hotspot/share/gc/g1/concurrentG1Refine.cpp
src/hotspot/share/gc/g1/concurrentG1Refine.hpp
src/hotspot/share/gc/g1/concurrentG1RefineThread.cpp
src/hotspot/share/gc/g1/concurrentG1RefineThread.hpp
src/hotspot/share/prims/jni_md.h
src/hotspot/share/prims/jvm.h
src/java.base/macosx/native/include/jni_md.h
src/java.base/macosx/native/include/jvm_md.h
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JNIid.java
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/overview.html
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/overview.html
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySlowPathNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyUnrollNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BasicIdealGraphPrinter.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java
test/hotspot/jtreg/applications/ctw/Modules.java
--- a/make/CompileToolsHotspot.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/CompileToolsHotspot.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -67,6 +67,7 @@
           $(SRC_DIR)/org.graalvm.compiler.phases.common/src \
           $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
           $(SRC_DIR)/org.graalvm.compiler.virtual/src \
+          $(SRC_DIR)/org.graalvm.graphio/src \
           $(SRC_DIR)/org.graalvm.util/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
@@ -125,6 +126,7 @@
           $(SRC_DIR)/org.graalvm.compiler.nodeinfo/src \
           $(SRC_DIR)/org.graalvm.compiler.options/src \
           $(SRC_DIR)/org.graalvm.compiler.serviceprovider/src \
+          $(SRC_DIR)/org.graalvm.graphio/src \
           $(SRC_DIR)/org.graalvm.util/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.code/src \
           $(VM_CI_SRC_DIR)/jdk.vm.ci.common/src \
--- a/make/Help.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/Help.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -36,15 +36,18 @@
 	$(info =====================)
 	$(info )
 	$(info Common make targets)
-	$(info $(_) make [default]         # Compile all modules in langtools, hotspot, jdk, jaxws,)
-	$(info $(_)                        # jaxp and corba, and create a runnable "exploded" image)
-	$(info $(_) make all               # Compile everything, all repos, docs and images)
-	$(info $(_) make images            # Create complete jdk and jre images (alias for product-images))
-	$(info $(_) make <name>-image      # Build just the image (jdk, jre, test, docs etc))
+	$(info $(_) make [default]         # Compile all modules and create a runnable "exploded")
+	$(info $(_)                        # image (alias for jdk or exploded-image))
+	$(info $(_) make all               # Create all images: product, test, docs)
+	$(info $(_)                        # (alias for all-images))
+	$(info $(_) make images            # Create complete jdk and jre images)
+	$(info $(_)                        # (alias for product-images))
+	$(info $(_) make <name>-image      # Build just the image for any of: )
+	$(info $(_)                        # jdk, jre, test, docs, symbols, profiles)
 	$(info $(_) make <phase>           # Build the specified phase and everything it depends on)
 	$(info $(_)                        # (gensrc, java, copy, libs, launchers, gendata, rmic))
-	$(info $(_) make *-only            # Applies to most targets and disables compling the)
-	$(info $(_)                        # dependencies for the target. This is faster but may)
+	$(info $(_) make *-only            # Applies to most targets and disables building the)
+	$(info $(_)                        # dependencies for that target. This is faster but may)
 	$(info $(_)                        # result in incorrect build results!)
 	$(info $(_) make docs              # Create all docs)
 	$(info $(_) make docs-jdk-api      # Create just JDK javadocs)
@@ -74,7 +77,7 @@
 	$(info $(_) make hotspot           # Build all of hotspot)
 	$(info $(_) make hotspot-<variant> # Build just the specified jvm variant)
 	$(info $(_) make hotspot-gensrc    # Only build the gensrc part of hotspot)
-	$(info $(_) make hotspot-<variant>-<phase> # Build the specified phase for the specified module)
+	$(info $(_) make hotspot-<variant>-<phase> # Build the specified phase for the variant)
 	$(info )
 	$(info Targets for specific modules)
 	$(info $(_) make <module>          # Build <module> and everything it depends on)
--- a/make/common/MakeBase.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/common/MakeBase.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -473,15 +473,32 @@
     $(subst $(SPACE),?,$(strip $1))
 
 ################################################################################
-# Make directory without forking mkdir if not needed
+# Make directory without forking mkdir if not needed.
+#
+# If a directory with an encoded space is provided, the wildcard function
+# sometimes returns false answers (typically if the dir existed when the
+# makefile was parsed, but was deleted by a previous rule). In that case, always
+# call mkdir regardless of what wildcard says.
+#
 # 1: List of directories to create
 MakeDir = \
     $(strip \
-        $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, $(if $(wildcard $d), , \
-            "$(call DecodeSpace, $d)")))) \
+        $(eval MakeDir_dirs_to_make := $(strip $(foreach d, $1, \
+          $(if $(findstring ?, $d), '$(call DecodeSpace, $d)', \
+            $(if $(wildcard $d), , $d) \
+          ) \
+        ))) \
         $(if $(MakeDir_dirs_to_make), $(shell $(MKDIR) -p $(MakeDir_dirs_to_make))) \
     )
 
+# Make directory for target file. Should handle spaces in filenames. Just
+# calling $(call MakeDir $(@D)) will not work if the directory contains a space
+# and the target file already exists. In that case, the target file will have
+# its wildcard ? resolved and the $(@D) will evaluate each space separated dir
+# part on its own.
+MakeTargetDir = \
+    $(call MakeDir, $(dir $(call EncodeSpace, $@)))
+
 ################################################################################
 # Assign a variable only if it is empty
 # Param 1 - Variable to assign
@@ -499,7 +516,7 @@
   # If the source and target parent directories are the same, recursive copy doesn't work
   # so we fall back on regular copy, which isn't preserving symlinks.
   define install-file
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(RM) '$(call DecodeSpace, $@)'
 	if [ '$(call DecodeSpace, $(dir $@))' != \
 	    '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \
@@ -526,21 +543,21 @@
   # If copying a soft link to a directory, need to delete the target first to avoid
   # weird errors.
   define install-file
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(RM) '$(call DecodeSpace, $@)'
 	$(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 	if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then $(XATTR) -cs '$(call DecodeSpace, $@)'; fi
   endef
 else
   define install-file
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(CP) -fP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
   endef
 endif
 
 # Variant of install file that does not preserve symlinks
 define install-file-nolink
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 endef
 
@@ -590,13 +607,13 @@
 # careful when using this on Windows since the symlink created is only valid in
 # the unix emulation environment.
 define link-file-relative
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(RM) '$(call DecodeSpace, $@)'
 	$(LN) -s '$(call DecodeSpace, $(call RelativePath, $<, $(@D)))' '$(call DecodeSpace, $@)'
 endef
 
 define link-file-absolute
-	$(call MakeDir, $(@D))
+	$(call MakeTargetDir)
 	$(RM) '$(call DecodeSpace, $@)'
 	$(LN) -s '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
 endef
--- a/make/copy/Copy-java.base.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/copy/Copy-java.base.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -42,7 +42,7 @@
 	$(call install-file)
 
 $(INCLUDE_DST_OS_DIR)/%.h: \
-    $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_EXPORT_DIR)/native/include/%.h
+    $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include/%.h
 	$(call install-file)
 
 ################################################################################
--- a/make/hotspot/lib/CompileJvm.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/hotspot/lib/CompileJvm.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -57,8 +57,8 @@
     $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \
     -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \
     -I$(TOPDIR)/src/hotspot/share/precompiled \
-    -I$(TOPDIR)/src/hotspot/share/prims \
     -I$(TOPDIR)/src/java.base/share/native/include \
+    -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \
     #
 
 # INCLUDE_SUFFIX_* is only meant for including the proper
--- a/make/hotspot/lib/CompileLibjsig.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/hotspot/lib/CompileLibjsig.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -57,7 +57,7 @@
       endif
 
     else ifeq ($(OPENJDK_TARGET_OS), solaris)
-      LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/hotspot/os/solaris
+      LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/java.base/unix/native/include
       LIBJSIG_LDFLAGS := -m64 -mt -xnolib
       LIBJSIG_LIBS := $(LIBDL)
 
--- a/make/mapfiles/libinstrument/mapfile-vers	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/mapfiles/libinstrument/mapfile-vers	Thu Nov 16 12:15:55 2017 +0000
@@ -31,6 +31,7 @@
 	    Agent_OnAttach;
             Java_sun_instrument_InstrumentationImpl_isModifiableClass0;
             Java_sun_instrument_InstrumentationImpl_isRetransformClassesSupported0;
+            Java_sun_instrument_InstrumentationImpl_setHasTransformers;
             Java_sun_instrument_InstrumentationImpl_setHasRetransformableTransformers;
             Java_sun_instrument_InstrumentationImpl_retransformClasses0;
             Java_sun_instrument_InstrumentationImpl_getAllLoadedClasses0;
--- a/make/nashorn/build.xml	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/nashorn/build.xml	Thu Nov 16 12:15:55 2017 +0000
@@ -830,8 +830,8 @@
 
     <!-- underscorejs -->
     <mkdir dir="${test.external.dir}/underscore"/>
-    <get src="http://underscorejs.org/underscore.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
-    <get src="http://underscorejs.org/underscore-min.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true"/>
+    <get src="http://underscorejs.org/underscore.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true" tryGzipEncoding="true"/>
+    <get src="http://underscorejs.org/underscore-min.js" dest="${test.external.dir}/underscore" skipexisting="true" ignoreerrors="true" tryGzipEncoding="true"/>
 
     <!-- yui -->
     <mkdir dir="${test.external.dir}/yui"/>
--- a/make/test/JtregNativeHotspot.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/make/test/JtregNativeHotspot.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -63,6 +63,8 @@
     $(TOPDIR)/test/hotspot/jtreg/runtime/RedefineTests \
     $(TOPDIR)/test/hotspot/jtreg/compiler/floatingpoint/ \
     $(TOPDIR)/test/hotspot/jtreg/compiler/calls \
+    $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup \
+    $(TOPDIR)/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/GetNamedModule \
     $(TOPDIR)/test/hotspot/jtreg/serviceability/jvmti/IsModifiableModule \
--- a/src/hotspot/.mx.jvmci/.project	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>mx.jvmci</name>
-	<comment></comment>
-	<projects>
-		<project>mx</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.python.pydev.PyDevBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.python.pydev.pythonNature</nature>
-	</natures>
-</projectDescription>
--- a/src/hotspot/.mx.jvmci/.pydevproject	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?eclipse-pydev version="1.0"?><pydev_project>
-<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
-<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
-<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
-<path>/mx.jvmci</path>
-</pydev_pathproperty>
-<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
-<path>/mx</path>
-</pydev_pathproperty>
-
-</pydev_project>
--- a/src/hotspot/.mx.jvmci/mx_jvmci.py	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/.mx.jvmci/mx_jvmci.py	Thu Nov 16 12:15:55 2017 +0000
@@ -42,11 +42,6 @@
 
 JVMCI_VERSION = 9
 
-"""
-Top level directory of the JDK source workspace.
-"""
-_jdkSourceRoot = dirname(_suite.dir)
-
 _JVMCI_JDK_TAG = 'jvmci'
 
 _minVersion = mx.VersionSpec('1.9')
@@ -145,7 +140,7 @@
     return True
 
 def _makehelp():
-    return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
+    return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_get_jdk_dir())
 
 def _runmake(args):
     """run the JDK make process
@@ -155,12 +150,12 @@
 
     jdkBuildDir = _get_jdk_build_dir()
     if not exists(jdkBuildDir):
-        # JDK9 must be bootstrapped with a JDK8
-        compliance = mx.JavaCompliance('8')
-        jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
+        # JDK10 must be bootstrapped with a JDK9
+        compliance = mx.JavaCompliance('9')
+        jdk9 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
         cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=external', '--disable-precompiled-headers', '--with-jvm-features=graal',
-               '--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home, '--with-jvm-features=graal']
-        mx.run(cmd, cwd=_jdkSourceRoot)
+               '--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk9.home, '--with-jvm-features=graal']
+        mx.run(cmd, cwd=_get_jdk_dir())
     cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
     if mx.get_opts().verbose:
         cmd.append('LOG=debug')
@@ -170,11 +165,11 @@
 
     if not mx.get_opts().verbose:
         mx.log('--------------- make execution ----------------------')
-        mx.log('Working directory: ' + _jdkSourceRoot)
+        mx.log('Working directory: ' + _get_jdk_dir())
         mx.log('Command line: ' + ' '.join(cmd))
         mx.log('-----------------------------------------------------')
 
-    mx.run(cmd, cwd=_jdkSourceRoot)
+    mx.run(cmd, cwd=_get_jdk_dir())
 
 def _runmultimake(args):
     """run the JDK make process for one or more configurations"""
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1489,6 +1489,17 @@
 
 #undef INSN
 
+  // Aliases for short forms of orn
+void mvn(Register Rd, Register Rm,
+            enum shift_kind kind = LSL, unsigned shift = 0) {
+  orn(Rd, zr, Rm, kind, shift);
+}
+
+void mvnw(Register Rd, Register Rm,
+            enum shift_kind kind = LSL, unsigned shift = 0) {
+  ornw(Rd, zr, Rm, kind, shift);
+}
+
   // Add/subtract (shifted register)
 #define INSN(NAME, size, op)                            \
   void NAME(Register Rd, Register Rn, Register Rm,      \
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2657,9 +2657,9 @@
   __ adrp(res, ExternalAddress(StubRoutines::crc_table_addr()), offset);
   if (offset) __ add(res, res, offset);
 
-  __ ornw(crc, zr, crc); // ~crc
+  __ mvnw(crc, crc); // ~crc
   __ update_byte_crc32(crc, val, res);
-  __ ornw(res, zr, crc); // ~crc
+  __ mvnw(res, crc); // ~crc
 }
 
 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
--- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1030,7 +1030,81 @@
 }
 
 void LIRGenerator::do_update_CRC32C(Intrinsic* x) {
-  Unimplemented();
+  assert(UseCRC32CIntrinsics, "why are we here?");
+  // Make all state_for calls early since they can emit code
+  LIR_Opr result = rlock_result(x);
+  int flags = 0;
+  switch (x->id()) {
+    case vmIntrinsics::_updateBytesCRC32C:
+    case vmIntrinsics::_updateDirectByteBufferCRC32C: {
+      bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);
+      int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;
+
+      LIRItem crc(x->argument_at(0), this);
+      LIRItem buf(x->argument_at(1), this);
+      LIRItem off(x->argument_at(2), this);
+      LIRItem end(x->argument_at(3), this);
+
+      buf.load_item();
+      off.load_nonconstant();
+      end.load_nonconstant();
+
+      // len = end - off
+      LIR_Opr len  = end.result();
+      LIR_Opr tmpA = new_register(T_INT);
+      LIR_Opr tmpB = new_register(T_INT);
+      __ move(end.result(), tmpA);
+      __ move(off.result(), tmpB);
+      __ sub(tmpA, tmpB, tmpA);
+      len = tmpA;
+
+      LIR_Opr index = off.result();
+      if(off.result()->is_constant()) {
+        index = LIR_OprFact::illegalOpr;
+        offset += off.result()->as_jint();
+      }
+      LIR_Opr base_op = buf.result();
+
+      if (index->is_valid()) {
+        LIR_Opr tmp = new_register(T_LONG);
+        __ convert(Bytecodes::_i2l, index, tmp);
+        index = tmp;
+      }
+
+      if (offset) {
+        LIR_Opr tmp = new_pointer_register();
+        __ add(base_op, LIR_OprFact::intConst(offset), tmp);
+        base_op = tmp;
+        offset = 0;
+      }
+
+      LIR_Address* a = new LIR_Address(base_op,
+                                       index,
+                                       offset,
+                                       T_BYTE);
+      BasicTypeList signature(3);
+      signature.append(T_INT);
+      signature.append(T_ADDRESS);
+      signature.append(T_INT);
+      CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+      const LIR_Opr result_reg = result_register_for(x->type());
+
+      LIR_Opr addr = new_pointer_register();
+      __ leal(LIR_OprFact::address(a), addr);
+
+      crc.load_item_force(cc->at(0));
+      __ move(addr, cc->at(1));
+      __ move(len, cc->at(2));
+
+      __ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args());
+      __ move(result_reg, result);
+
+      break;
+    }
+    default: {
+      ShouldNotReachHere();
+    }
+  }
 }
 
 void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -431,11 +431,11 @@
   // This is the sp before any possible extension (adapter/locals).
   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (map->update_map()) {
     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   return frame(sender_sp, unextended_sp, link(), sender_pc());
 }
--- a/src/hotspot/cpu/aarch64/jni_aarch64.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef _JAVASOFT_JNI_MD_H_
-#define _JAVASOFT_JNI_MD_H_
-
-#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
-
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-
-  #define JNICALL
-  typedef int jint;
-  typedef long jlong;
-
-#else
-  #define JNIEXPORT __declspec(dllexport)
-  #define JNIIMPORT __declspec(dllimport)
-  #define JNICALL __stdcall
-
-  typedef int jint;
-  typedef __int64 jlong;
-#endif
-
-typedef signed char jbyte;
-
-#endif /* !_JAVASOFT_JNI_MD_H_ */
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/assembler.hpp"
 #include "asm/assembler.inline.hpp"
 #include "interpreter/interpreter.hpp"
@@ -38,7 +39,6 @@
 #include "opto/compile.hpp"
 #include "opto/intrinsicnode.hpp"
 #include "opto/node.hpp"
-#include "prims/jvm.h"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/interfaceSupport.hpp"
@@ -2929,6 +2929,105 @@
   eor(crc, crc, tmp);
 }
 
+void MacroAssembler::kernel_crc32_using_crc32(Register crc, Register buf,
+        Register len, Register tmp0, Register tmp1, Register tmp2,
+        Register tmp3) {
+    Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop, CRC_less64, CRC_by64_pre, CRC_by32_loop, CRC_less32, L_exit;
+    assert_different_registers(crc, buf, len, tmp0, tmp1, tmp2, tmp3);
+
+    mvnw(crc, crc);
+
+    subs(len, len, 128);
+    br(Assembler::GE, CRC_by64_pre);
+  BIND(CRC_less64);
+    adds(len, len, 128-32);
+    br(Assembler::GE, CRC_by32_loop);
+  BIND(CRC_less32);
+    adds(len, len, 32-4);
+    br(Assembler::GE, CRC_by4_loop);
+    adds(len, len, 4);
+    br(Assembler::GT, CRC_by1_loop);
+    b(L_exit);
+
+  BIND(CRC_by32_loop);
+    ldp(tmp0, tmp1, Address(post(buf, 16)));
+    subs(len, len, 32);
+    crc32x(crc, crc, tmp0);
+    ldr(tmp2, Address(post(buf, 8)));
+    crc32x(crc, crc, tmp1);
+    ldr(tmp3, Address(post(buf, 8)));
+    crc32x(crc, crc, tmp2);
+    crc32x(crc, crc, tmp3);
+    br(Assembler::GE, CRC_by32_loop);
+    cmn(len, 32);
+    br(Assembler::NE, CRC_less32);
+    b(L_exit);
+
+  BIND(CRC_by4_loop);
+    ldrw(tmp0, Address(post(buf, 4)));
+    subs(len, len, 4);
+    crc32w(crc, crc, tmp0);
+    br(Assembler::GE, CRC_by4_loop);
+    adds(len, len, 4);
+    br(Assembler::LE, L_exit);
+  BIND(CRC_by1_loop);
+    ldrb(tmp0, Address(post(buf, 1)));
+    subs(len, len, 1);
+    crc32b(crc, crc, tmp0);
+    br(Assembler::GT, CRC_by1_loop);
+    b(L_exit);
+
+  BIND(CRC_by64_pre);
+    sub(buf, buf, 8);
+    ldp(tmp0, tmp1, Address(buf, 8));
+    crc32x(crc, crc, tmp0);
+    ldr(tmp2, Address(buf, 24));
+    crc32x(crc, crc, tmp1);
+    ldr(tmp3, Address(buf, 32));
+    crc32x(crc, crc, tmp2);
+    ldr(tmp0, Address(buf, 40));
+    crc32x(crc, crc, tmp3);
+    ldr(tmp1, Address(buf, 48));
+    crc32x(crc, crc, tmp0);
+    ldr(tmp2, Address(buf, 56));
+    crc32x(crc, crc, tmp1);
+    ldr(tmp3, Address(pre(buf, 64)));
+
+    b(CRC_by64_loop);
+
+    align(CodeEntryAlignment);
+  BIND(CRC_by64_loop);
+    subs(len, len, 64);
+    crc32x(crc, crc, tmp2);
+    ldr(tmp0, Address(buf, 8));
+    crc32x(crc, crc, tmp3);
+    ldr(tmp1, Address(buf, 16));
+    crc32x(crc, crc, tmp0);
+    ldr(tmp2, Address(buf, 24));
+    crc32x(crc, crc, tmp1);
+    ldr(tmp3, Address(buf, 32));
+    crc32x(crc, crc, tmp2);
+    ldr(tmp0, Address(buf, 40));
+    crc32x(crc, crc, tmp3);
+    ldr(tmp1, Address(buf, 48));
+    crc32x(crc, crc, tmp0);
+    ldr(tmp2, Address(buf, 56));
+    crc32x(crc, crc, tmp1);
+    ldr(tmp3, Address(pre(buf, 64)));
+    br(Assembler::GE, CRC_by64_loop);
+
+    // post-loop
+    crc32x(crc, crc, tmp2);
+    crc32x(crc, crc, tmp3);
+
+    sub(len, len, 64);
+    add(buf, buf, 8);
+    cmn(len, 128);
+    br(Assembler::NE, CRC_less64);
+  BIND(L_exit);
+    mvnw(crc, crc);
+}
+
 /**
  * @param crc   register containing existing CRC (32-bit)
  * @param buf   register pointing to input byte buffer (byte*)
@@ -2942,58 +3041,13 @@
   Label L_by16, L_by16_loop, L_by4, L_by4_loop, L_by1, L_by1_loop, L_exit;
   unsigned long offset;
 
-    ornw(crc, zr, crc);
-
   if (UseCRC32) {
-    Label CRC_by64_loop, CRC_by4_loop, CRC_by1_loop;
-
-      subs(len, len, 64);
-      br(Assembler::GE, CRC_by64_loop);
-      adds(len, len, 64-4);
-      br(Assembler::GE, CRC_by4_loop);
-      adds(len, len, 4);
-      br(Assembler::GT, CRC_by1_loop);
-      b(L_exit);
-
-    BIND(CRC_by4_loop);
-      ldrw(tmp, Address(post(buf, 4)));
-      subs(len, len, 4);
-      crc32w(crc, crc, tmp);
-      br(Assembler::GE, CRC_by4_loop);
-      adds(len, len, 4);
-      br(Assembler::LE, L_exit);
-    BIND(CRC_by1_loop);
-      ldrb(tmp, Address(post(buf, 1)));
-      subs(len, len, 1);
-      crc32b(crc, crc, tmp);
-      br(Assembler::GT, CRC_by1_loop);
-      b(L_exit);
-
-      align(CodeEntryAlignment);
-    BIND(CRC_by64_loop);
-      subs(len, len, 64);
-      ldp(tmp, tmp3, Address(post(buf, 16)));
-      crc32x(crc, crc, tmp);
-      crc32x(crc, crc, tmp3);
-      ldp(tmp, tmp3, Address(post(buf, 16)));
-      crc32x(crc, crc, tmp);
-      crc32x(crc, crc, tmp3);
-      ldp(tmp, tmp3, Address(post(buf, 16)));
-      crc32x(crc, crc, tmp);
-      crc32x(crc, crc, tmp3);
-      ldp(tmp, tmp3, Address(post(buf, 16)));
-      crc32x(crc, crc, tmp);
-      crc32x(crc, crc, tmp3);
-      br(Assembler::GE, CRC_by64_loop);
-      adds(len, len, 64-4);
-      br(Assembler::GE, CRC_by4_loop);
-      adds(len, len, 4);
-      br(Assembler::GT, CRC_by1_loop);
-    BIND(L_exit);
-      ornw(crc, zr, crc);
+      kernel_crc32_using_crc32(crc, buf, len, table0, table1, table2, table3);
       return;
   }
 
+    mvnw(crc, crc);
+
     adrp(table0, ExternalAddress(StubRoutines::crc_table_addr()), offset);
     if (offset) add(table0, table0, offset);
     add(table1, table0, 1*256*sizeof(juint));
@@ -3171,7 +3225,7 @@
     adds(len, len, 4);
     br(Assembler::GT, L_by1_loop);
   BIND(L_exit);
-    ornw(crc, zr, crc);
+    mvnw(crc, crc);
 }
 
 /**
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1261,6 +1261,9 @@
                                Register yz_idx1, Register yz_idx2,
                                Register tmp, Register tmp3, Register tmp4,
                                Register tmp7, Register product_hi);
+  void kernel_crc32_using_crc32(Register crc, Register buf,
+        Register len, Register tmp0, Register tmp1, Register tmp2,
+        Register tmp3);
 public:
   void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
                        Register zlen, Register tmp1, Register tmp2, Register tmp3,
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -41,7 +41,7 @@
 #ifdef COMPILER1
 #include "c1/c1_Runtime1.hpp"
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #include "adfiles/ad_aarch64.hpp"
 #include "opto/runtime.hpp"
 #endif
@@ -114,7 +114,7 @@
 };
 
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     // Save upper half of vector registers
     int vect_words = 32 * 8 / wordSize;
@@ -2688,7 +2688,7 @@
   return 0;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 //------------------------------generate_uncommon_trap_blob--------------------
 void SharedRuntime::generate_uncommon_trap_blob() {
   // Allocate space for the code
@@ -2894,7 +2894,7 @@
   }
 #endif
 }
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
 
 
 //------------------------------generate_handler_blob------
@@ -3070,8 +3070,7 @@
   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
 }
 
-
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
 //
 //------------------------------generate_exception_blob---------------------------
@@ -3200,4 +3199,4 @@
   // Set exception blob
   _exception_blob =  ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
 }
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -4937,6 +4937,10 @@
       StubRoutines::_crc_table_adr = (address)StubRoutines::aarch64::_crc_table;
       StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
     }
+
+    if (UseCRC32CIntrinsics) {
+      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
+    }
   }
 
   void generate_all() {
@@ -5014,10 +5018,6 @@
       StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(true,  "sha256_implCompressMB");
     }
 
-    if (UseCRC32CIntrinsics) {
-      StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C();
-    }
-
     // generate Adler32 intrinsics code
     if (UseAdler32Intrinsics) {
       StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -472,7 +472,7 @@
 #if INCLUDE_JVMCI
   // Check if we need to take lock at entry of synchronized method.  This can
   // only occur on method entry so emit it only for vtos with step 0.
-  if (UseJVMCICompiler && state == vtos && step == 0) {
+  if (EnableJVMCI && state == vtos && step == 0) {
     Label L;
     __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
     __ cbz(rscratch1, L);
@@ -483,7 +483,7 @@
     __ bind(L);
   } else {
 #ifdef ASSERT
-    if (UseJVMCICompiler) {
+    if (EnableJVMCI) {
       Label L;
       __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
       __ cbz(rscratch1, L);
@@ -984,9 +984,9 @@
     __ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset);
     __ add(tbl, tbl, offset);
 
-    __ ornw(crc, zr, crc); // ~crc
+    __ mvnw(crc, crc); // ~crc
     __ update_byte_crc32(crc, val, tbl);
-    __ ornw(crc, zr, crc); // ~crc
+    __ mvnw(crc, crc); // ~crc
 
     // result in c_rarg0
 
@@ -1061,8 +1061,44 @@
   return NULL;
 }
 
-// Not supported
+/**
+ * Method entry for intrinsic-candidate (non-native) methods:
+ *   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
+ *   int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long buf, int off, int end)
+ * Unlike CRC32, CRC32C does not have any methods marked as native
+ * CRC32C also uses an "end" variable instead of the length variable CRC32 uses
+ */
 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
+  if (UseCRC32Intrinsics) {
+    address entry = __ pc();
+
+    // Prepare jump to stub using parameters from the stack
+    const Register crc = c_rarg0; // initial crc
+    const Register buf = c_rarg1; // source java byte array address
+    const Register len = c_rarg2; // len argument to the kernel
+
+    const Register end = len; // index of last element to process
+    const Register off = crc; // offset
+
+    __ ldrw(end, Address(esp)); // int end
+    __ ldrw(off, Address(esp, wordSize)); // int offset
+    __ sub(len, end, off);
+    __ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
+    __ add(buf, buf, off); // + offset
+    if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
+      __ ldrw(crc, Address(esp, 4*wordSize)); // long crc
+    } else {
+      __ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
+      __ ldrw(crc, Address(esp, 3*wordSize)); // long crc
+    }
+
+    __ andr(sp, r13, -16); // Restore the caller's SP
+
+    // Jump to the stub.
+    __ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
+
+    return entry;
+  }
   return NULL;
 }
 
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -33,7 +33,7 @@
 #include "runtime/safepoint.hpp"
 
 // ----------------------------------------------------------------------------
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #define __ _masm.
 // emit call stub, compiled java to interpreter
 address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
@@ -89,7 +89,7 @@
 int CompiledStaticCall::reloc_to_interp_stub() {
   return 10;  // 4 in emit_to_interp_stub + 1 in Java_Static_Call
 }
-#endif // COMPILER2 || JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 // size of C2 call stub, compiled java to interpretor
 int CompiledStaticCall::to_interp_stub_size() {
--- a/src/hotspot/cpu/arm/interp_masm_arm.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "gc/shared/barrierSet.inline.hpp"
 #include "gc/shared/cardTableModRefBS.inline.hpp"
 #include "gc/shared/collectedHeap.hpp"
--- a/src/hotspot/cpu/arm/jni_arm.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef _JAVASOFT_JNI_MD_H_
-#define _JAVASOFT_JNI_MD_H_
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((externally_visible,visibility("default")))
-  #define JNIIMPORT     __attribute__((externally_visible,visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-
-#define JNICALL
-
-typedef int jint;
-#if defined(_LP64)
-  typedef long jlong;
-#else
-  typedef long long jlong;
-#endif
-typedef signed char jbyte;
-
-#endif /* !_JAVASOFT_JNI_MD_H_ */
--- a/src/hotspot/cpu/arm/methodHandles_arm.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -27,12 +27,12 @@
 // Last synchronization: changeset f8c9417e3571
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/stubCodeGenerator.hpp"
--- a/src/hotspot/cpu/arm/vm_version_arm_64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/arm/vm_version_arm_64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/stubCodeGenerator.hpp"
--- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -941,7 +941,7 @@
 inline void Assembler::vpmsumw(  VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b)); }
 
 // Vector Permute and Xor (introduced with Power 8)
-inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPMSUMW_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
+inline void Assembler::vpermxor( VectorRegister d, VectorRegister a, VectorRegister b, VectorRegister c) { emit_int32( VPERMXOR_OPCODE | vrt(d) | vra(a) | vrb(b) | vrc(c)); }
 
 // Transactional Memory instructions (introduced with Power 8)
 inline void Assembler::tbegin_()                                { emit_int32( TBEGIN_OPCODE | rc(1)); }
--- a/src/hotspot/cpu/ppc/globals_ppc.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/ppc/globals_ppc.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -69,7 +69,7 @@
 define_pd_global(bool, RewriteBytecodes,      true);
 define_pd_global(bool, RewriteFrequentPairs,  true);
 
-define_pd_global(bool, UseMembar,             false);
+define_pd_global(bool, UseMembar,             true);
 
 define_pd_global(bool, PreserveFramePointer,  false);
 
--- a/src/hotspot/cpu/ppc/jni_ppc.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2013 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef CPU_PPC_VM_JNI_PPC_H
-#define CPU_PPC_VM_JNI_PPC_H
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-
-#define JNICALL
-
-typedef int jint;
-
-#if defined(_LP64)
-  typedef long jlong;
-#else
-  typedef long long jlong;
-#endif
-
-typedef signed char jbyte;
-
-#endif // CPU_PPC_VM_JNI_PPC_H
--- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,12 +24,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1469,8 +1469,31 @@
   }
   // Save or restore single word registers.
   for (int i = 0; i < total_in_args; i++) {
-    // PPC64: pass ints as longs: must only deal with floats here.
-    if (in_regs[i].first()->is_FloatRegister()) {
+    if (in_regs[i].first()->is_Register()) {
+      int offset = slot * VMRegImpl::stack_slot_size;
+      // Value lives in an input register. Save it on stack.
+      switch (in_sig_bt[i]) {
+        case T_BOOLEAN:
+        case T_CHAR:
+        case T_BYTE:
+        case T_SHORT:
+        case T_INT:
+          if (map != NULL) {
+            __ stw(in_regs[i].first()->as_Register(), offset, R1_SP);
+          } else {
+            __ lwa(in_regs[i].first()->as_Register(), offset, R1_SP);
+          }
+          slot++;
+          assert(slot <= stack_slots, "overflow (after INT or smaller stack slot)");
+          break;
+        case T_ARRAY:
+        case T_LONG:
+          // handled above
+          break;
+        case T_OBJECT:
+        default: ShouldNotReachHere();
+      }
+    } else if (in_regs[i].first()->is_FloatRegister()) {
       if (in_sig_bt[i] == T_FLOAT) {
         int offset = slot * VMRegImpl::stack_slot_size;
         slot++;
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,11 +24,11 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/assembler.inline.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "compiler/disassembler.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
@@ -109,7 +109,8 @@
 
   if (PowerArchitecturePPC64 >= 8) {
     if (FLAG_IS_DEFAULT(SuperwordUseVSX)) {
-      FLAG_SET_ERGO(bool, SuperwordUseVSX, true);
+      // TODO: Switch on when it works stable. Currently, MachSpillCopyNode::implementation code is missing.
+      //FLAG_SET_ERGO(bool, SuperwordUseVSX, true);
     }
   } else {
     if (SuperwordUseVSX) {
--- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -277,7 +277,7 @@
     length.set_instruction(x->length());
     length.load_item();
   }
-  if (needs_store_check) {
+  if (needs_store_check || x->check_boolean()) {
     value.load_item();
   } else {
     value.load_for_store(x->elt_type());
@@ -327,11 +327,14 @@
     // Needs GC write barriers.
     pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
-    __ move(value.result(), array_addr, null_check_info);
-    // Seems to be a precise.
+  }
+
+  LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+  __ move(result, array_addr, null_check_info);
+
+  if (obj_store) {
+    // Precise card mark
     post_barrier(LIR_OprFact::address(array_addr), value.result());
-  } else {
-    __ move(value.result(), array_addr, null_check_info);
   }
 }
 
--- a/src/hotspot/cpu/s390/globals_s390.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/globals_s390.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -71,7 +71,7 @@
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
-define_pd_global(bool, UseMembar,            false);
+define_pd_global(bool, UseMembar,            true);
 
 define_pd_global(bool, PreserveFramePointer, false);
 
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -843,6 +843,38 @@
   verify_oop(Z_tos, state);
 }
 
+void InterpreterMacroAssembler::narrow(Register result, Register ret_type) {
+  get_method(ret_type);
+  z_lg(ret_type, Address(ret_type, in_bytes(Method::const_offset())));
+  z_lb(ret_type, Address(ret_type, in_bytes(ConstMethod::result_type_offset())));
+
+  Label notBool, notByte, notChar, done;
+
+  // common case first
+  compareU32_and_branch(ret_type, T_INT, bcondEqual, done);
+
+  compareU32_and_branch(ret_type, T_BOOLEAN, bcondNotEqual, notBool);
+  z_nilf(result, 0x1);
+  z_bru(done);
+
+  bind(notBool);
+  compareU32_and_branch(ret_type, T_BYTE, bcondNotEqual, notByte);
+  z_lbr(result, result);
+  z_bru(done);
+
+  bind(notByte);
+  compareU32_and_branch(ret_type, T_CHAR, bcondNotEqual, notChar);
+  z_nilf(result, 0xffff);
+  z_bru(done);
+
+  bind(notChar);
+  // compareU32_and_branch(ret_type, T_SHORT, bcondNotEqual, notShort);
+  z_lhr(result, result);
+
+  // Nothing to do for T_INT
+  bind(done);
+}
+
 // remove activation
 //
 // Unlock the receiver if this is a synchronized method.
--- a/src/hotspot/cpu/s390/interp_masm_s390.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/interp_masm_s390.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -86,6 +86,8 @@
   void dispatch_next_noverify_oop(TosState state, int step = 0);
   void dispatch_via(TosState state, address* table);
 
+  void narrow(Register result, Register ret_type);
+
   // Jump to an invoked target.
   void prepare_to_jump_from_interpreted(Register method);
   void jump_from_interpreted(Register method, Register temp);
--- a/src/hotspot/cpu/s390/jni_s390.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef _JAVASOFT_JNI_MD_H_
-#define _JAVASOFT_JNI_MD_H_
-
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-
-#define JNICALL
-
-typedef int jint;
-
-typedef long int jlong;
-
-typedef signed char jbyte;
-
-#endif // _JAVASOFT_JNI_MD_H_
--- a/src/hotspot/cpu/s390/methodHandles_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,12 +24,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 
 #ifdef PRODUCT
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1309,15 +1309,42 @@
         }
       } else {
         __ z_lg(reg, offset, Z_SP);
-        slot += VMRegImpl::slots_per_word;
-        assert(slot <= stack_slots, "overflow (after LONG/ARRAY stack slot)");
       }
+      slot += VMRegImpl::slots_per_word;
+      assert(slot <= stack_slots, "overflow (after LONG/ARRAY stack slot)");
     }
   }
 
   // Save or restore single word registers.
   for (int i = 0; i < total_in_args; i++) {
-    if (in_regs[i].first()->is_FloatRegister()) {
+    if (in_regs[i].first()->is_Register()) {
+      int offset = slot * VMRegImpl::stack_slot_size;
+      // Value lives in an input register. Save it on stack.
+      switch (in_sig_bt[i]) {
+        case T_BOOLEAN:
+        case T_CHAR:
+        case T_BYTE:
+        case T_SHORT:
+        case T_INT: {
+          const Register   reg = in_regs[i].first()->as_Register();
+          Address   stackaddr(Z_SP, offset);
+          if (map != NULL) {
+            __ z_st(reg, stackaddr);
+          } else {
+            __ z_lgf(reg, stackaddr);
+          }
+          slot++;
+          assert(slot <= stack_slots, "overflow (after INT or smaller stack slot)");
+          break;
+        }
+        case T_ARRAY:
+        case T_LONG:
+          // handled above
+          break;
+        case T_OBJECT:
+        default: ShouldNotReachHere();
+      }
+    } else if (in_regs[i].first()->is_FloatRegister()) {
       if (in_sig_bt[i] == T_FLOAT) {
         int offset = slot * VMRegImpl::stack_slot_size;
         slot++;
@@ -1908,7 +1935,7 @@
       case T_ARRAY:
         if (is_critical_native) {
           int body_arg = cix;
-          cix -= 2; // Point to length arg.
+          cix -= 1; // Point to length arg.
           unpack_array_argument(masm, in_regs[jix], in_elem_bt[jix], out_regs[body_arg], out_regs[cix], stack_slots);
           break;
         }
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2377,6 +2377,12 @@
   __ store_const(Address(RjvmtiState, JvmtiThreadState::earlyret_state_offset()),
                  JvmtiThreadState::earlyret_inactive, 4, 4, Z_R0_scratch);
 
+  if (state == itos) {
+    // Narrow result if state is itos but result type is smaller.
+    // Need to narrow in the return bytecode rather than in generate_return_entry
+    // since compiled code callers expect the result to already be narrowed.
+    __ narrow(Z_tos, Z_tmp_1); /* fall through */
+  }
   __ remove_activation(state,
                        Z_tmp_1, // retaddr
                        false,   // throw_monitor_exception
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1174,8 +1174,20 @@
   __ pop_i(Z_ARG3);
   __ pop_ptr(Z_tmp_2);
   // Z_tos   : value
-  // Z_ARG3 : index
+  // Z_ARG3  : index
   // Z_tmp_2 : array
+
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(Z_tmp_1, Z_tmp_2);
+  __ z_llgf(Z_tmp_1, Address(Z_tmp_1, Klass::layout_helper_offset()));
+  __ z_tmll(Z_tmp_1, Klass::layout_helper_boolean_diffbit());
+  Label L_skip;
+  __ z_bfalse(L_skip);
+  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ z_nilf(Z_tos, 0x1);
+  __ bind(L_skip);
+
   // No index shift necessary - pass 0.
   index_check(Z_tmp_2, Z_ARG3, 0); // Prefer index in Z_ARG3.
   __ z_stc(Z_tos,
@@ -2321,6 +2333,13 @@
     __ bind(skip_register_finalizer);
   }
 
+  if (state == itos) {
+    // Narrow result if state is itos but result type is smaller.
+    // Need to narrow in the return bytecode rather than in generate_return_entry
+    // since compiled code callers expect the result to already be narrowed.
+    __ narrow(Z_tos, Z_tmp_1); /* fall through */
+  }
+
   __ remove_activation(state, Z_R14);
   __ z_br(Z_R14);
 }
--- a/src/hotspot/cpu/s390/vm_version_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/s390/vm_version_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,11 +24,11 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/assembler.inline.hpp"
 #include "compiler/disassembler.hpp"
 #include "code/compiledIC.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "vm_version_s390.hpp"
--- a/src/hotspot/cpu/sparc/globals_sparc.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/sparc/globals_sparc.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -74,7 +74,7 @@
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
-define_pd_global(bool, UseMembar,            false);
+define_pd_global(bool, UseMembar,            true);
 
 define_pd_global(bool, PreserveFramePointer, false);
 
--- a/src/hotspot/cpu/sparc/jni_sparc.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-#define JNICALL
-
-typedef int jint;
-
-typedef long jlong;
-
-typedef signed char jbyte;
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "compiler/disassembler.hpp"
 #include "gc/shared/cardTableModRefBS.hpp"
@@ -31,7 +32,6 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/klass.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/src/hotspot/cpu/sparc/methodHandles_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/sparc/methodHandles_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,13 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -319,7 +319,7 @@
 #if INCLUDE_JVMCI
   // Check if we need to take lock at entry of synchronized method.  This can
   // only occur on method entry so emit it only for vtos with step 0.
-  if (UseJVMCICompiler && state == vtos && step == 0) {
+  if (EnableJVMCI && state == vtos && step == 0) {
     Label L;
     Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
     __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
@@ -331,7 +331,7 @@
     __ bind(L);
   } else {
 #ifdef ASSERT
-    if (UseJVMCICompiler) {
+    if (EnableJVMCI) {
       Label L;
       Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
       __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
--- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,11 +23,11 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
--- a/src/hotspot/cpu/x86/frame_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/frame_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -436,11 +436,11 @@
   // This is the sp before any possible extension (adapter/locals).
   intptr_t* unextended_sp = interpreter_frame_sender_sp();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (map->update_map()) {
     update_map_with_saved_link(map, (intptr_t**) addr_at(link_offset));
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   return frame(sender_sp, unextended_sp, link(), sender_pc());
 }
--- a/src/hotspot/cpu/x86/globals_x86.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/globals_x86.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -46,11 +46,11 @@
 // the the vep is aligned at CodeEntryAlignment whereas c2 only aligns
 // the uep and the vep doesn't get real alignment but just slops on by
 // only assured that the entry instruction meets the 5 byte size requirement.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 define_pd_global(intx, CodeEntryAlignment,       32);
 #else
 define_pd_global(intx, CodeEntryAlignment,       16);
-#endif // COMPILER2
+#endif // COMPILER2_OR_JVMCI
 define_pd_global(intx, OptoLoopAlignment,        16);
 define_pd_global(intx, InlineFrequencyCount,     100);
 define_pd_global(intx, InlineSmallCode,          1000);
@@ -84,11 +84,7 @@
 define_pd_global(bool, RewriteBytecodes,     true);
 define_pd_global(bool, RewriteFrequentPairs, true);
 
-#ifdef _ALLBSD_SOURCE
 define_pd_global(bool, UseMembar,            true);
-#else
-define_pd_global(bool, UseMembar,            false);
-#endif
 
 // GC Ergo Flags
 define_pd_global(size_t, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
--- a/src/hotspot/cpu/x86/jni_x86.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef _JAVASOFT_JNI_MD_H_
-#define _JAVASOFT_JNI_MD_H_
-
-#if defined(_WIN32)
-  #define JNIEXPORT __declspec(dllexport)
-  #define JNIIMPORT __declspec(dllimport)
-  #define JNICALL __stdcall
-
-  typedef int jint;
-  typedef __int64 jlong;
-#else
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-
-  #define JNICALL
-  typedef int jint;
-#if defined(_LP64)
-  typedef long jlong;
-#else
-  typedef long long jlong;
-#endif
-
-#endif
-
-typedef signed char jbyte;
-
-#endif /* !_JAVASOFT_JNI_MD_H_ */
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/assembler.hpp"
 #include "asm/assembler.inline.hpp"
 #include "compiler/disassembler.hpp"
@@ -32,7 +33,6 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/klass.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/src/hotspot/cpu/x86/methodHandles_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,13 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 
 #define __ _masm->
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -151,7 +151,7 @@
   if (UseAVX < 3) {
     num_xmm_regs = num_xmm_regs/2;
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
     assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
@@ -260,7 +260,7 @@
     }
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (save_vectors) {
     off = ymm0_off;
     int delta = ymm1_off - off;
@@ -270,7 +270,7 @@
       off += delta;
     }
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   // %%% These should all be a waste but we'll keep things as they were for now
   if (true) {
@@ -323,7 +323,7 @@
     __ addptr(rsp, frame::arg_reg_save_area_bytes);
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (restore_vectors) {
     assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
     assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
@@ -2183,7 +2183,7 @@
   // critical natives they are offset down.
   GrowableArray<int> arg_order(2 * total_in_args);
   VMRegPair tmp_vmreg;
-  tmp_vmreg.set1(rbx->as_VMReg());
+  tmp_vmreg.set2(rbx->as_VMReg());
 
   if (!is_critical_native) {
     for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, 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
@@ -3433,6 +3433,8 @@
   }
 
  address generate_libmExp() {
+    StubCodeMark mark(this, "StubRoutines", "libmExp");
+
     address start = __ pc();
 
     const XMMRegister x0  = xmm0;
@@ -3458,6 +3460,8 @@
   }
 
  address generate_libmLog() {
+   StubCodeMark mark(this, "StubRoutines", "libmLog");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3483,6 +3487,8 @@
  }
 
  address generate_libmLog10() {
+   StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3508,6 +3514,8 @@
  }
 
  address generate_libmPow() {
+   StubCodeMark mark(this, "StubRoutines", "libmPow");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3533,6 +3541,8 @@
  }
 
  address generate_libm_reduce_pi04l() {
+   StubCodeMark mark(this, "StubRoutines", "libm_reduce_pi04l");
+
    address start = __ pc();
 
    BLOCK_COMMENT("Entry:");
@@ -3543,6 +3553,8 @@
  }
 
  address generate_libm_sin_cos_huge() {
+   StubCodeMark mark(this, "StubRoutines", "libm_sin_cos_huge");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3556,6 +3568,8 @@
  }
 
  address generate_libmSin() {
+   StubCodeMark mark(this, "StubRoutines", "libmSin");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3579,6 +3593,8 @@
  }
 
  address generate_libmCos() {
+   StubCodeMark mark(this, "StubRoutines", "libmCos");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3604,6 +3620,8 @@
  }
 
  address generate_libm_tan_cot_huge() {
+   StubCodeMark mark(this, "StubRoutines", "libm_tan_cot_huge");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
@@ -3617,6 +3635,8 @@
  }
 
  address generate_libmTan() {
+   StubCodeMark mark(this, "StubRoutines", "libmTan");
+
    address start = __ pc();
 
    const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -4619,6 +4619,8 @@
   }
 
   address generate_libmExp() {
+    StubCodeMark mark(this, "StubRoutines", "libmExp");
+
     address start = __ pc();
 
     const XMMRegister x0  = xmm0;
@@ -4646,6 +4648,8 @@
   }
 
   address generate_libmLog() {
+    StubCodeMark mark(this, "StubRoutines", "libmLog");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4674,6 +4678,8 @@
   }
 
   address generate_libmLog10() {
+    StubCodeMark mark(this, "StubRoutines", "libmLog10");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4701,6 +4707,8 @@
   }
 
   address generate_libmPow() {
+    StubCodeMark mark(this, "StubRoutines", "libmPow");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4731,6 +4739,8 @@
   }
 
   address generate_libmSin() {
+    StubCodeMark mark(this, "StubRoutines", "libmSin");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4770,6 +4780,8 @@
   }
 
   address generate_libmCos() {
+    StubCodeMark mark(this, "StubRoutines", "libmCos");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
@@ -4809,6 +4821,8 @@
   }
 
   address generate_libmTan() {
+    StubCodeMark mark(this, "StubRoutines", "libmTan");
+
     address start = __ pc();
 
     const XMMRegister x0 = xmm0;
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -257,7 +257,7 @@
 #if INCLUDE_JVMCI
   // Check if we need to take lock at entry of synchronized method.  This can
   // only occur on method entry so emit it only for vtos with step 0.
-  if ((UseJVMCICompiler || UseAOT) && state == vtos && step == 0) {
+  if ((EnableJVMCI || UseAOT) && state == vtos && step == 0) {
     Label L;
     __ cmpb(Address(thread, JavaThread::pending_monitorenter_offset()), 0);
     __ jcc(Assembler::zero, L);
@@ -270,7 +270,7 @@
     __ bind(L);
   } else {
 #ifdef ASSERT
-    if (UseJVMCICompiler) {
+    if (EnableJVMCI) {
       Label L;
       __ cmpb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0);
       __ jccb(Assembler::zero, L);
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
@@ -944,7 +944,7 @@
     }
   }
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (MaxVectorSize > 0) {
     if (!is_power_of_2(MaxVectorSize)) {
       warning("MaxVectorSize must be a power of 2");
@@ -996,7 +996,7 @@
     }
 #endif // COMPILER2 && ASSERT
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #ifdef COMPILER2
 #ifdef _LP64
--- a/src/hotspot/cpu/zero/jni_zero.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-
-// Note: please do not change these without also changing jni_md.h in the JDK
-// repository
-#ifndef __has_attribute
-  #define __has_attribute(x) 0
-#endif
-#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
-#else
-  #define JNIEXPORT
-  #define JNIIMPORT
-#endif
-#define JNICALL
-
-typedef int jint;
-typedef signed char jbyte;
-
-#ifdef _LP64
-typedef long jlong;
-#else
-typedef long long jlong;
-#endif
--- a/src/hotspot/os/aix/jvm_aix.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/aix/jvm_aix.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,7 +24,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/aix/jvm_aix.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2013 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_AIX_VM_JVM_AIX_H
-#define OS_AIX_VM_JVM_AIX_H
-
-// HotSpot integration note:
-//
-// This is derived from the JDK classic file:
-// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22)
-// All local includes have been commented out.
-
-#ifndef JVM_MD_H
-#define JVM_MD_H
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-#include <dirent.h>             /* For DIR */
-
-// Must redefine NULL because the macro gets redefined to int 0
-// by dirent.h. This redefinition is included later then the standard definition in
-// globalDefinitions_<compiler>.hpp and leads to assertions in the VM initialization.
-// We definitely need NULL to have the same lengh as an address pointer.
-#ifdef _LP64
-#undef NULL
-#define NULL 0L
-#else
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-#include <sys/param.h>          /* For MAXPATHLEN */
-#include <sys/socket.h>         /* For socklen_t */
-#include <unistd.h>             /* For F_OK, R_OK, W_OK */
-
-#define JNI_ONLOAD_SYMBOLS      {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS    {"JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS      {"JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS    {"Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS  {"Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS  {"Agent_OnAttach"}
-
-#define JNI_LIB_PREFIX "lib"
-#define JNI_LIB_SUFFIX ".so"
-
-#define JVM_MAXPATHLEN MAXPATHLEN
-
-#define JVM_R_OK    R_OK
-#define JVM_W_OK    W_OK
-#define JVM_X_OK    X_OK
-#define JVM_F_OK    F_OK
-
-/*
- * File I/O
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signal definitions */
-
-#define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
-#define SHUTDOWN2_SIGNAL SIGINT
-#define SHUTDOWN3_SIGNAL SIGTERM
-
-#endif /* JVM_MD_H */
-
-#endif // OS_AIX_VM_JVM_AIX_H
--- a/src/hotspot/os/aix/os_aix.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -28,6 +28,7 @@
 #pragma alloca
 
 // no precompiled headers
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -35,7 +36,6 @@
 #include "code/vtableStubs.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_aix.h"
 #include "logging/log.hpp"
 #include "libo4.hpp"
 #include "libperfstat_aix.hpp"
@@ -49,7 +49,6 @@
 #include "os_share_aix.hpp"
 #include "porting_aix.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
@@ -3249,7 +3248,7 @@
   }
 
   // ReduceSignalUsage allows the user to override these handlers
-  // see comments at the very top and jvm_solaris.h
+  // see comments at the very top and jvm_md.h
   if (!ReduceSignalUsage) {
     DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
     DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
--- a/src/hotspot/os/bsd/decoder_machO.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/bsd/decoder_machO.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 
 #ifdef __APPLE__
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "decoder_machO.hpp"
 
 #include <cxxabi.h>
--- a/src/hotspot/os/bsd/jvm_bsd.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/bsd/jvm_bsd.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/bsd/jvm_bsd.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_BSD_VM_JVM_BSD_H
-#define OS_BSD_VM_JVM_BSD_H
-
-/*
-// HotSpot integration note:
-//
-// This is derived from the JDK classic file:
-// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22)
-// All local includes have been commented out.
-*/
-
-#ifndef JVM_MD_H
-#define JVM_MD_H
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-#include <dirent.h>             /* For DIR */
-#include <sys/param.h>          /* For MAXPATHLEN */
-#include <sys/socket.h>         /* For socklen_t */
-#include <unistd.h>             /* For F_OK, R_OK, W_OK */
-
-#define JNI_ONLOAD_SYMBOLS      {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS    {"JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS      {"JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS    {"Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS  {"Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS  {"Agent_OnAttach"}
-
-#define JNI_LIB_PREFIX "lib"
-#ifdef __APPLE__
-#define JNI_LIB_SUFFIX ".dylib"
-#else
-#define JNI_LIB_SUFFIX ".so"
-#endif
-
-// Hack: MAXPATHLEN is 4095 on some Bsd and 4096 on others. This may
-//       cause problems if JVM and the rest of JDK are built on different
-//       Bsd releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
-//       so buffers declared in VM are always >= 4096.
-#define JVM_MAXPATHLEN MAXPATHLEN + 1
-
-#define JVM_R_OK    R_OK
-#define JVM_W_OK    W_OK
-#define JVM_X_OK    X_OK
-#define JVM_F_OK    F_OK
-
-/*
- * File I/O
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signal definitions */
-
-#define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
-#define SHUTDOWN2_SIGNAL SIGINT
-#define SHUTDOWN3_SIGNAL SIGTERM
-
-#ifndef SIGRTMIN
-#ifdef __OpenBSD__
-#define SIGRTMIN        1
-#else
-#define SIGRTMIN        33
-#endif
-#endif
-#ifndef SIGRTMAX
-#ifdef __OpenBSD__
-#define SIGRTMAX        31
-#else
-#define SIGRTMAX        63
-#endif
-#endif
-#endif /* JVM_MD_H */
-
-#endif // OS_BSD_VM_JVM_BSD_H
--- a/src/hotspot/os/bsd/os_bsd.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -31,7 +32,6 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_bsd.h"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
@@ -39,7 +39,6 @@
 #include "os_bsd.inline.hpp"
 #include "os_share_bsd.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
@@ -3240,7 +3239,7 @@
 
 
   // ReduceSignalUsage allows the user to override these handlers
-  // see comments at the very top and jvm_solaris.h
+  // see comments at the very top and jvm_md.h
   if (!ReduceSignalUsage) {
     DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
     DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
--- a/src/hotspot/os/linux/decoder_linux.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/linux/decoder_linux.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,7 +22,7 @@
  *
  */
 
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "utilities/decoder_elf.hpp"
 
 #include <cxxabi.h>
--- a/src/hotspot/os/linux/jvm_linux.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/linux/jvm_linux.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/linux/jvm_linux.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_LINUX_VM_JVM_LINUX_H
-#define OS_LINUX_VM_JVM_LINUX_H
-
-/*
-// HotSpot integration note:
-//
-// This is derived from the JDK classic file:
-// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22)
-// All local includes have been commented out.
-*/
-
-#ifndef JVM_MD_H
-#define JVM_MD_H
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-#include <dirent.h>             /* For DIR */
-#include <sys/param.h>          /* For MAXPATHLEN */
-#include <sys/socket.h>         /* For socklen_t */
-#include <unistd.h>             /* For F_OK, R_OK, W_OK */
-
-#define JNI_ONLOAD_SYMBOLS      {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS    {"JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS      {"JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS    {"Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS  {"Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS  {"Agent_OnAttach"}
-
-#define JNI_LIB_PREFIX "lib"
-#define JNI_LIB_SUFFIX ".so"
-
-// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may
-//       cause problems if JVM and the rest of JDK are built on different
-//       Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
-//       so buffers declared in VM are always >= 4096.
-#define JVM_MAXPATHLEN MAXPATHLEN + 1
-
-#define JVM_R_OK    R_OK
-#define JVM_W_OK    W_OK
-#define JVM_X_OK    X_OK
-#define JVM_F_OK    F_OK
-
-/*
- * File I/O
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signal definitions */
-
-#define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
-#define SHUTDOWN2_SIGNAL SIGINT
-#define SHUTDOWN3_SIGNAL SIGTERM
-
-#endif /* JVM_MD_H */
-
-#endif // OS_LINUX_VM_JVM_LINUX_H
--- a/src/hotspot/os/linux/os_linux.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -31,7 +32,6 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
@@ -39,7 +39,6 @@
 #include "os_linux.inline.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
@@ -4664,7 +4663,7 @@
 #endif
 
   // ReduceSignalUsage allows the user to override these handlers
-  // see comments at the very top and jvm_solaris.h
+  // see comments at the very top and jvm_md.h
   if (!ReduceSignalUsage) {
     DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
     DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
--- a/src/hotspot/os/posix/os_posix.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/posix/os_posix.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,8 +22,8 @@
  *
  */
 
+#include "jvm.h"
 #include "utilities/globalDefinitions.hpp"
-#include "prims/jvm.h"
 #include "runtime/frame.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/os/solaris/jvm_solaris.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/solaris/jvm_solaris.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/solaris/jvm_solaris.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_SOLARIS_VM_JVM_SOLARIS_H
-#define OS_SOLARIS_VM_JVM_SOLARIS_H
-
-/*
-// HotSpot integration note:
-//
-// This is derived from the JDK classic file:
-// "$JDK/src/solaris/javavm/export/jvm_md.h":15 (ver. 1.10 98/04/22)
-// All local includes have been commented out.
-*/
-
-#ifndef JVM_MD_H
-#define JVM_MD_H
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-#include <dirent.h>             /* For DIR */
-#include <sys/param.h>          /* For MAXPATHLEN */
-#include <sys/socket.h>         /* For socklen_t */
-#include <unistd.h>             /* For F_OK, R_OK, W_OK */
-#include <sys/int_types.h>      /* for intptr_t types (64 Bit cleanliness) */
-
-#define JNI_ONLOAD_SYMBOLS      {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS    {"JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS      {"JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS    {"Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS  {"Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS  {"Agent_OnAttach"}
-
-#define JNI_LIB_PREFIX "lib"
-#define JNI_LIB_SUFFIX ".so"
-
-#define JVM_MAXPATHLEN MAXPATHLEN
-
-#define JVM_R_OK    R_OK
-#define JVM_W_OK    W_OK
-#define JVM_X_OK    X_OK
-#define JVM_F_OK    F_OK
-
-/*
- * File I/O
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signal definitions */
-
-#define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
-#define ASYNC_SIGNAL     SIGJVM2           /* Event-based suspend/resume support */
-#define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
-#define SHUTDOWN2_SIGNAL SIGINT
-#define SHUTDOWN3_SIGNAL SIGTERM
-
-/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */
-#define JSIG_VERSION_1_4_1   0x30140100
-
-#endif /* JVM_MD_H */
-
-#endif // OS_SOLARIS_VM_JVM_SOLARIS_H
--- a/src/hotspot/os/solaris/os_solaris.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -31,7 +32,6 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_solaris.h"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
@@ -39,7 +39,6 @@
 #include "os_share_solaris.hpp"
 #include "os_solaris.inline.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
--- a/src/hotspot/os/windows/jvm_windows.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/windows/jvm_windows.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/osThread.hpp"
 
--- a/src/hotspot/os/windows/jvm_windows.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef OS_WINDOWS_VM_JVM_WINDOWS_H
-#define OS_WINDOWS_VM_JVM_WINDOWS_H
-
-#ifndef _JAVASOFT_JVM_MD_H_
-#define _JAVASOFT_JVM_MD_H_
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-// JDK7 requires VS2010
-#if _MSC_VER >= 1600
-// JDK7 minimum platform requirement: Windows XP
-#if _WIN32_WINNT < 0x0501
-#undef _WIN32_WINNT
-#define _WIN32_WINNT  0x0501
-#endif
-#endif
-
-#include <windows.h>
-
-#include <Psapi.h>
-#include <Tlhelp32.h>
-
-typedef int socklen_t;
-
-#define JNI_ONLOAD_SYMBOLS      {"_JNI_OnLoad@8", "JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS    {"_JNI_OnUnload@8", "JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS      {"_JVM_OnLoad@12", "JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS    {"_Agent_OnLoad@12", "Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS  {"_Agent_OnUnload@4", "Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS  {"_Agent_OnAttach@12", "Agent_OnAttach"}
-
-#define JNI_LIB_PREFIX ""
-#define JNI_LIB_SUFFIX ".dll"
-
-struct dirent {
-    char d_name[MAX_PATH];
-};
-
-typedef struct {
-    struct dirent dirent;
-    char *path;
-    HANDLE handle;
-    WIN32_FIND_DATA find_data;
-} DIR;
-
-#include <stdlib.h>
-
-#define JVM_MAXPATHLEN _MAX_PATH
-
-#define JVM_R_OK    4
-#define JVM_W_OK    2
-#define JVM_X_OK    1
-#define JVM_F_OK    0
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT void * JNICALL
-JVM_GetThreadInterruptEvent();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-/*
- * File I/O
- */
-
-#include <sys/stat.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signals */
-
-#define JVM_SIGINT     SIGINT
-#define JVM_SIGTERM    SIGTERM
-
-#define SHUTDOWN1_SIGNAL SIGINT            /* Shutdown Hooks support.    */
-#define SHUTDOWN2_SIGNAL SIGTERM
-
-#endif /* !_JAVASOFT_JVM_MD_H_ */
-
-#endif // OS_WINDOWS_VM_JVM_WINDOWS_H
--- a/src/hotspot/os/windows/os_windows.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,6 +26,7 @@
 #define _WIN32_WINNT 0x0600
 
 // no precompiled headers
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -34,7 +35,6 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_windows.h"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
@@ -42,7 +42,6 @@
 #include "os_share_windows.hpp"
 #include "os_windows.inline.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
@@ -100,6 +99,7 @@
 #include <imagehlp.h>             // For os::dll_address_to_function_name
 // for enumerating dll libraries
 #include <vdmdbg.h>
+#include <psapi.h>
 
 // for timer info max values which include all bits
 #define ALL_64_BITS CONST64(-1)
@@ -3656,7 +3656,7 @@
 
     static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
     static CRITICAL_SECTION crit_sect;
-    static volatile jint process_exiting = 0;
+    static volatile DWORD process_exiting = 0;
     int i, j;
     DWORD res;
     HANDLE hproc, hthr;
@@ -3675,7 +3675,7 @@
       if (what != EPT_THREAD) {
         // Atomically set process_exiting before the critical section
         // to increase the visibility between racing threads.
-        Atomic::cmpxchg((jint)GetCurrentThreadId(), &process_exiting, 0);
+        Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0);
       }
       EnterCriticalSection(&crit_sect);
 
@@ -3793,7 +3793,7 @@
 
     if (!registered &&
         OrderAccess::load_acquire(&process_exiting) != 0 &&
-        process_exiting != (jint)GetCurrentThreadId()) {
+        process_exiting != GetCurrentThreadId()) {
       // Some other thread is about to call exit(), so we don't let
       // the current unregistered thread proceed to exit() or _endthreadex()
       while (true) {
--- a/src/hotspot/os/windows/threadCritical_windows.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os/windows/threadCritical_windows.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -36,7 +36,7 @@
 //
 
 static bool initialized = false;
-static volatile jint lock_count = -1;
+static volatile int lock_count = -1;
 static HANDLE lock_event;
 static DWORD lock_owner = -1;
 
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/assembler.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -32,12 +33,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_aix.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_ppc.hpp"
 #include "os_share_aix.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "porting_aix.hpp"
 #include "runtime/arguments.hpp"
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -31,11 +32,9 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_bsd.h"
 #include "memory/allocation.inline.hpp"
 #include "os_share_bsd.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -73,7 +73,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -84,7 +84,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -29,6 +29,7 @@
 #endif
 
 // no precompiled headers
+#include "jvm.h"
 #include "assembler_zero.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -36,12 +37,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_bsd.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_zero.hpp"
 #include "os_share_bsd.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -33,11 +34,9 @@
 #include "code/vtableStubs.hpp"
 #include "code/nativeInst.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
@@ -234,8 +233,17 @@
 }
 
 intptr_t* _get_previous_fp() {
-  register intptr_t **ebp __asm__ (SPELL_REG_FP);
-  return (intptr_t*) *ebp;   // we want what it points to.
+  register intptr_t **fp __asm__ (SPELL_REG_FP);
+
+  // fp is for this frame (_get_previous_fp). We want the fp for the
+  // caller of os::current_frame*(), so go up two frames. However, for
+  // optimized builds, _get_previous_fp() will be inlined, so only go
+  // up 1 frame in that case.
+  #ifdef _NMT_NOINLINE_
+    return **(intptr_t***)fp;
+  #else
+    return *fp;
+  #endif
 }
 
 
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "assembler_arm.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -30,12 +31,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_arm.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/assembler.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -32,12 +33,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_ppc.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,6 +26,7 @@
 // This file is organized as os_linux_x86.cpp.
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/assembler.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -35,12 +36,10 @@
 #include "code/vtableStubs.hpp"
 #include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_s390.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -31,12 +32,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_sparc.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_sparc/vm_version_linux_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,58 +27,326 @@
 #include "runtime/os.hpp"
 #include "vm_version_sparc.hpp"
 
-static bool cpuinfo_field_contains(const char* field, const char* value) {
-  char line[1024];
-  bool rv = false;
+
+#define CPUINFO_LINE_SIZE 1024
+
+
+class CPUinfo {
+public:
+  CPUinfo(const char* field) : _string(NULL) {
+
+    char line[CPUINFO_LINE_SIZE];
+    FILE* fp = fopen("/proc/cpuinfo", "r");
 
-  FILE* fp = fopen("/proc/cpuinfo", "r");
-  if (fp == NULL) {
-    return rv;
-  }
+    if (fp != NULL) {
+      while (fgets(line, sizeof(line), fp) != NULL) {
+        assert(strlen(line) < sizeof(line) - 1,
+               "buffer too small (%d)", CPUINFO_LINE_SIZE);
+
+        const char* vstr = match_field(line, field);
 
-  while (fgets(line, sizeof(line), fp) != NULL) {
-    assert(strlen(line) < sizeof(line) - 1, "buffer line[1024] is too small.");
-    if (strncmp(line, field, strlen(field)) == 0) {
-      if (strstr(line, value) != NULL) {
-        rv = true;
+        if (vstr != NULL) {
+          // We have a matching line and a valid starting point to the value of
+          // the field, copy the string for keeps.
+          _string = strdup(vstr);
+          break;
+        }
       }
-      break;
+      fclose(fp);
     }
   }
 
-  fclose(fp);
-  return rv;
+  ~CPUinfo() { os::free((void*)_string); }
+
+  const char* value() const { return _string; }
+
+  bool valid() const { return _string != NULL; }
+
+  bool match(const char* s) const {
+    return valid() ? strcmp(_string, s) == 0 : false;
+  }
+
+private:
+  const char* _string;
+
+  const char* match_field(char line[CPUINFO_LINE_SIZE], const char* field);
+  const char* match_alo(const char* text, const char* exp);
+  const char* match_seq(const char* text, const char* seq);
+};
+
+/* Given a line of text read from /proc/cpuinfo, determine if the property header
+ * matches the field specified, according to the following regexp: "<field>"\W+:\W+
+ *
+ * If we have a matching expression, return a pointer to the first character after
+ * the matching pattern, i.e. the "value", otherwise return NULL.
+ */
+const char* CPUinfo::match_field(char line[CPUINFO_LINE_SIZE], const char* field) {
+  return match_alo(match_seq(match_alo(match_seq(line, field), "\t "), ":"), "\t ");
 }
 
-static bool detect_niagara() {
-  return cpuinfo_field_contains("cpu", "Niagara");
+/* Match a sequence of at-least-one character in the string expression (exp) to
+ * the text input.
+ */
+const char* CPUinfo::match_alo(const char* text, const char* exp) {
+  if (text == NULL) return NULL;
+
+  const char* chp;
+
+  for (chp = &text[0]; *chp != '\0'; chp++) {
+    if (strchr(exp, *chp) == NULL) break;
+  }
+
+  return text < chp ? chp : NULL;
 }
 
-static bool detect_M_family() {
-  return cpuinfo_field_contains("cpu", "SPARC-M");
-}
+/* Match an exact sequence of characters as specified by the string expression
+ * (seq) to the text input.
+ */
+const char* CPUinfo::match_seq(const char* text, const char* seq) {
+  if (text == NULL) return NULL;
 
-static bool detect_blkinit() {
-  return cpuinfo_field_contains("cpucaps", "blkinit");
+  while (*seq != '\0') {
+    if (*seq != *text++) break; else seq++;
+  }
+
+  return *seq == '\0' ? text : NULL;
 }
 
-int VM_Version::platform_features(int features) {
-  // Default to generic v9
-  features = generic_v9_m;
+
+typedef struct {
+  const uint32_t    hash;
+  bool              seen;
+  const char* const name;
+  const uint64_t    mask;
+} FeatureEntry;
+
+
+static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]);
+
+
+void VM_Version::platform_features() {
+
+  // Some of the features reported via "cpucaps", such as; 'flush', 'stbar',
+  // 'swap', 'muldiv', 'ultra3', 'blkinit', 'n2', 'mul32', 'div32', 'fsmuld'
+  // and 'v8plus', are either SPARC V8, supported by all HW or simply nonsense
+  // (the 'ultra3' "property").
+  //
+  // Entries marked as 'NYI' are not yet supported via "cpucaps" but are
+  // expected to have the names used in the table below (these are SPARC M7
+  // features or more recent).
+  //
+  // NOTE: Table sorted on lookup/hash ID.
 
-  if (detect_niagara()) {
-    log_info(os, cpu)("Detected Linux on Niagara");
-    features = niagara1_m | T_family_m;
+  static FeatureEntry s_feature_tbl[] = {
+    { 0x006f, false, "v9",         ISA_v9_msk },            // Mandatory
+    { 0x00a6, false, "md5",        ISA_md5_msk },
+    { 0x00ce, false, "adi",        ISA_adi_msk },           // NYI
+    { 0x00d7, false, "ima",        ISA_ima_msk },
+    { 0x00d9, false, "aes",        ISA_aes_msk },
+    { 0x00db, false, "hpc",        ISA_hpc_msk },
+    { 0x00dc, false, "des",        ISA_des_msk },
+    { 0x00ed, false, "sha1",       ISA_sha1_msk },
+    { 0x00f2, false, "vis",        ISA_vis1_msk },
+    { 0x0104, false, "vis2",       ISA_vis2_msk },
+    { 0x0105, false, "vis3",       ISA_vis3_msk },
+    { 0x0114, false, "sha512",     ISA_sha512_msk },
+    { 0x0119, false, "sha256",     ISA_sha256_msk },
+    { 0x011a, false, "fmaf",       ISA_fmaf_msk },
+    { 0x0132, false, "popc",       ISA_popc_msk },
+    { 0x0140, false, "crc32c",     ISA_crc32c_msk },
+    { 0x0147, false, "vis3b",      ISA_vis3b_msk },         // NYI
+    { 0x017e, false, "pause",      ISA_pause_msk },
+    { 0x0182, false, "mwait",      ISA_mwait_msk },         // NYI
+    { 0x018b, false, "mpmul",      ISA_mpmul_msk },
+    { 0x018e, false, "sparc5",     ISA_sparc5_msk },        // NYI
+    { 0x01a9, false, "cbcond",     ISA_cbcond_msk },
+    { 0x01c3, false, "vamask",     ISA_vamask_msk },        // NYI
+    { 0x01ca, false, "kasumi",     ISA_kasumi_msk },
+    { 0x01e3, false, "xmpmul",     ISA_xmpmul_msk },        // NYI
+    { 0x022c, false, "montmul",    ISA_mont_msk },
+    { 0x0234, false, "montsqr",    ISA_mont_msk },
+    { 0x0238, false, "camellia",   ISA_camellia_msk },
+    { 0x024a, false, "ASIBlkInit", ISA_blk_init_msk },
+    { 0x0284, false, "xmontmul",   ISA_xmont_msk },         // NYI
+    { 0x02e6, false, "pause_nsec", ISA_pause_nsec_msk },    // NYI
+
+    { 0x0000, false, NULL, 0 }
+  };
+
+  CPUinfo caps("cpucaps");      // Read "cpucaps" from /proc/cpuinfo.
+
+  assert(caps.valid(), "must be");
+
+  _features = parse_features(s_feature_tbl, caps.value());
+
+  assert(has_v9(), "must be");  // Basic SPARC-V9 required (V8 not supported).
+
+  CPUinfo type("type");
+
+  bool is_sun4v = type.match("sun4v");   // All Oracle SPARC + Fujitsu Athena+
+  bool is_sun4u = type.match("sun4u");   // All other Fujitsu
+
+  uint64_t synthetic = 0;
+
+  if (is_sun4v) {
+    // Indirect and direct branches are equally fast.
+    synthetic = CPU_fast_ind_br_msk;
+    // Fast IDIV, BIS and LD available on Niagara Plus.
+    if (has_vis2()) {
+      synthetic |= (CPU_fast_idiv_msk | CPU_fast_ld_msk);
+      // ...on Core C4 however, we prefer not to use BIS.
+      if (!has_sparc5()) {
+        synthetic |= CPU_fast_bis_msk;
+      }
+    }
+    // Niagara Core C3 supports fast RDPC and block zeroing.
+    if (has_ima()) {
+      synthetic |= (CPU_fast_rdpc_msk | CPU_blk_zeroing_msk);
+    }
+    // Niagara Core C3 and C4 have slow CMOVE.
+    if (!has_ima()) {
+      synthetic |= CPU_fast_cmove_msk;
+    }
+  } else if (is_sun4u) {
+    // SPARC64 only have fast IDIV and RDPC.
+    synthetic |= (CPU_fast_idiv_msk | CPU_fast_rdpc_msk);
+  } else {
+    log_info(os, cpu)("Unable to derive CPU features: %s", type.value());
   }
 
-  if (detect_M_family()) {
-    log_info(os, cpu)("Detected Linux on M family");
-    features = sun4v_m | generic_v9_m | M_family_m | T_family_m;
+  _features += synthetic;   // Including CPU derived/synthetic features.
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+static uint32_t uhash32(const char name[]);
+
+static void update_table(FeatureEntry feature_tbl[], uint32_t hv,
+                         const char* ch1p,
+                         const char* endp);
+
+/* Given a feature table, parse the input text holding the string value of
+ * 'cpucaps' as reported by '/proc/cpuinfo', in order to complete the table
+ * with information on each admissible feature (whether present or not).
+ *
+ * Return the composite bit-mask representing the features found.
+ */
+static uint64_t parse_features(FeatureEntry feature_tbl[], const char input[]) {
+  log_info(os, cpu)("Parse CPU features: %s\n", input);
+
+#ifdef ASSERT
+  // Verify that hash value entries in the table are unique and ordered.
+
+  uint32_t prev = 0;
+
+  for (uint k = 0; feature_tbl[k].name != NULL; k++) {
+    feature_tbl[k].seen = false;
+
+    assert(feature_tbl[k].hash == uhash32(feature_tbl[k].name),
+           "feature '%s' has mismatching hash 0x%08x (expected 0x%08x).\n",
+           feature_tbl[k].name,
+           feature_tbl[k].hash,
+           uhash32(feature_tbl[k].name));
+
+    assert(prev < feature_tbl[k].hash,
+           "feature '%s' has invalid hash 0x%08x (previous is 0x%08x).\n",
+           feature_tbl[k].name,
+           feature_tbl[k].hash,
+           prev);
+
+    prev = feature_tbl[k].hash;
+  }
+#endif
+  // Identify features from the input, consisting of a string with features
+  // separated by commas (or whitespace), e.g. "flush,muldiv,v9,mul32,div32,
+  // v8plus,popc,vis".
+
+  uint32_t hv = 0;
+  const char* ch1p = &input[0];
+  uint i = 0;
+
+  do {
+    char ch = input[i];
+
+    if (isalnum(ch) || ch == '_') {
+      hv += (ch - 32u);
+    }
+    else if (isspace(ch) || ch == ',' || ch == '\0') { // end-of-token
+      if (ch1p < &input[i]) {
+        update_table(feature_tbl, hv, ch1p, &input[i]);
+      }
+      ch1p = &input[i + 1]; hv = 0;
+    } else {
+      // Handle non-accepted input robustly.
+      log_info(os, cpu)("Bad token in feature string: '%c' (0x%02x).\n", ch, ch);
+      ch1p = &input[i + 1]; hv = 0;
+    }
+  }
+  while (input[i++] != '\0');
+
+  // Compute actual bit-mask representation.
+
+  uint64_t mask = 0;
+
+  for (uint k = 0; feature_tbl[k].name != NULL; k++) {
+    mask |= feature_tbl[k].seen ? feature_tbl[k].mask : 0;
   }
 
-  if (detect_blkinit()) {
-    features |= blk_init_instructions_m;
+  return mask;
+}
+
+static uint32_t uhash32(const char name[]) {
+  uint32_t hv = 0;
+
+  for (uint i = 0; name[i] != '\0'; i++) {
+    hv += (name[i] - 32u);
   }
 
-  return features;
+  return hv;
 }
+
+static bool verify_match(const char name[], const char* ch1p, const char* endp);
+
+static void update_table(FeatureEntry feature_tbl[], uint32_t hv, const char* ch1p, const char* endp) {
+  assert(ch1p < endp, "at least one character");
+
+  // Look for a hash value in the table. Since this table is a small one (and
+  // is expected to stay small), we use a simple linear search (iff the table
+  // grows large, we may consider to adopt a binary ditto, or a perfect hash).
+
+  for (uint k = 0; feature_tbl[k].name != NULL; k++) {
+    uint32_t hash = feature_tbl[k].hash;
+
+    if (hash < hv) continue;
+
+    if (hash == hv) {
+      const char* name = feature_tbl[k].name;
+
+      if (verify_match(name, ch1p, endp)) {
+        feature_tbl[k].seen = true;
+        break;
+      }
+    }
+
+    // Either a non-matching feature (when hash == hv) or hash > hv. In either
+    // case we break out of the loop and terminate the search (note that the
+    // table is assumed to be uniquely sorted on the hash).
+
+    break;
+  }
+}
+
+static bool verify_match(const char name[], const char* ch1p, const char* endp) {
+  size_t len = strlen(name);
+
+  if (len != static_cast<size_t>(endp - ch1p)) {
+    return false;
+  }
+
+  for (uint i = 0; ch1p + i < endp; i++) {
+    if (name[i] != ch1p[i]) return false;
+  }
+
+  return true;
+}
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -31,11 +32,9 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -74,7 +74,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -85,7 +85,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "assembler_zero.inline.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -31,12 +32,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_zero.hpp"
 #include "os_share_linux.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "macroAssembler_sparc.hpp"
 #include "classfile/classLoader.hpp"
@@ -32,12 +33,10 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_solaris.h"
 #include "memory/allocation.inline.hpp"
 #include "nativeInst_sparc.hpp"
 #include "os_share_solaris.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -31,11 +32,9 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_solaris.h"
 #include "memory/allocation.inline.hpp"
 #include "os_share_solaris.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
--- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 // no precompiled headers
+#include "jvm.h"
 #include "asm/macroAssembler.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -30,13 +31,11 @@
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
 #include "interpreter/interpreter.hpp"
-#include "jvm_windows.h"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "nativeInst_x86.hpp"
 #include "os_share_windows.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/extendedPC.hpp"
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -81,7 +81,7 @@
 
     frame ret_frame(ret_sp, ret_fp, addr.pc());
     if (!ret_frame.safe_for_sender(jt)) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr.pc());
       if (!ret_frame2.safe_for_sender(jt)) {
@@ -92,7 +92,7 @@
 #else
       // nothing else to try if the frame isn't good
       return false;
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
     }
     *fr_addr = ret_frame;
     return true;
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -490,6 +490,8 @@
 
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_checkcast_arraycopy", address, StubRoutines::_checkcast_arraycopy);
 
+    SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_generic_arraycopy", address, StubRoutines::_generic_arraycopy);
+
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_encryptBlock", address, StubRoutines::_aescrypt_encryptBlock);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_aescrypt_decryptBlock", address, StubRoutines::_aescrypt_decryptBlock);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_stub_routines_cipherBlockChaining_encryptAESCrypt", address, StubRoutines::_cipherBlockChaining_encryptAESCrypt);
--- a/src/hotspot/share/aot/aotLoader.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/aot/aotLoader.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,12 +22,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 
 #include "aot/aotCodeHeap.hpp"
 #include "aot/aotLoader.inline.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 #include "oops/method.hpp"
-#include "prims/jvm.h"
 #include "runtime/os.hpp"
 #include "runtime/timerTrace.hpp"
 
--- a/src/hotspot/share/c1/c1_CFGPrinter.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/c1/c1_CFGPrinter.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,13 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "c1/c1_CFGPrinter.hpp"
 #include "c1/c1_IR.hpp"
 #include "c1/c1_InstructionPrinter.hpp"
 #include "c1/c1_LIR.hpp"
 #include "c1/c1_LinearScan.hpp"
 #include "c1/c1_ValueStack.hpp"
-#include "prims/jvm.h"
 
 #ifndef PRODUCT
 
--- a/src/hotspot/share/c1/c1_Canonicalizer.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/c1/c1_Canonicalizer.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -40,6 +40,10 @@
   void set_constant(jlong x)                     { set_canonical(new Constant(new LongConstant(x))); }
   void set_constant(jfloat x)                    { set_canonical(new Constant(new FloatConstant(x))); }
   void set_constant(jdouble x)                   { set_canonical(new Constant(new DoubleConstant(x))); }
+#ifdef _WINDOWS
+  // jint is defined as long in jni_md.h, so convert from int to jint
+  void set_constant(int x)                       { set_constant((jint)x); }
+#endif
   void move_const_to_right(Op2* x);
   void do_Op2(Op2* x);
   void do_UnsafeRawOp(UnsafeRawOp* x);
--- a/src/hotspot/share/c1/c1_Compiler.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/c1/c1_Compiler.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -213,7 +213,7 @@
   case vmIntrinsics::_updateCRC32:
   case vmIntrinsics::_updateBytesCRC32:
   case vmIntrinsics::_updateByteBufferCRC32:
-#if defined(SPARC) || defined(S390) || defined(PPC64)
+#if defined(SPARC) || defined(S390) || defined(PPC64) || defined(AARCH64)
   case vmIntrinsics::_updateBytesCRC32C:
   case vmIntrinsics::_updateDirectByteBufferCRC32C:
 #endif
--- a/src/hotspot/share/c1/c1_LinearScan.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/c1/c1_LinearScan.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2507,7 +2507,7 @@
 // use).
 ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL);
 ConstantIntValue*      LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1);
-ConstantIntValue*      LinearScan::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0);
+ConstantIntValue*      LinearScan::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue((jint)0);
 ConstantIntValue*      LinearScan::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1);
 ConstantIntValue*      LinearScan::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2);
 LocationValue*         _illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location());
--- a/src/hotspot/share/ci/ciEnv.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/ci/ciEnv.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "ci/ciConstant.hpp"
 #include "ci/ciEnv.hpp"
 #include "ci/ciField.hpp"
@@ -49,7 +50,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/init.hpp"
 #include "runtime/reflection.hpp"
--- a/src/hotspot/share/ci/ciFlags.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/ci/ciFlags.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,9 +25,9 @@
 #ifndef SHARE_VM_CI_CIFLAGS_HPP
 #define SHARE_VM_CI_CIFLAGS_HPP
 
+#include "jvm.h"
 #include "ci/ciClassList.hpp"
 #include "memory/allocation.hpp"
-#include "prims/jvm.h"
 #include "utilities/accessFlags.hpp"
 #include "utilities/ostream.hpp"
 
--- a/src/hotspot/share/ci/ciReplay.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/ci/ciReplay.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "ci/ciMethodData.hpp"
 #include "ci/ciReplay.hpp"
 #include "ci/ciSymbol.hpp"
@@ -33,7 +34,6 @@
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
 
@@ -790,7 +790,7 @@
         while (field_signature[rank] == '[') {
           rank++;
         }
-        int* dims = NEW_RESOURCE_ARRAY(int, rank);
+        jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
         dims[0] = length;
         for (int i = 1; i < rank; i++) {
           dims[i] = 1; // These aren't relevant to the compiler
--- a/src/hotspot/share/classfile/altHashing.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/altHashing.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -42,15 +42,15 @@
 juint AltHashing::compute_seed() {
   jlong nanos = os::javaTimeNanos();
   jlong now = os::javaTimeMillis();
-  int SEED_MATERIAL[8] = {
-            (int) object_hash(SystemDictionary::String_klass()),
-            (int) object_hash(SystemDictionary::System_klass()),
-            os::random(),  // current thread isn't a java thread
-            (int) (((julong)nanos) >> 32),
-            (int) nanos,
-            (int) (((julong)now) >> 32),
-            (int) now,
-            (int) (os::javaTimeNanos() >> 2)
+  jint SEED_MATERIAL[8] = {
+            (jint) object_hash(SystemDictionary::String_klass()),
+            (jint) object_hash(SystemDictionary::System_klass()),
+            (jint) os::random(),  // current thread isn't a java thread
+            (jint) (((julong)nanos) >> 32),
+            (jint) nanos,
+            (jint) (((julong)now) >> 32),
+            (jint) now,
+            (jint) (os::javaTimeNanos() >> 2)
   };
 
   return murmur3_32(SEED_MATERIAL, 8);
@@ -167,7 +167,7 @@
 }
 
 // Hash used for the seed.
-juint AltHashing::murmur3_32(juint seed, const int* data, int len) {
+juint AltHashing::murmur3_32(juint seed, const jint* data, int len) {
   juint h1 = seed;
 
   int off = 0;
@@ -202,6 +202,6 @@
   return h1;
 }
 
-juint AltHashing::murmur3_32(const int* data, int len) {
+juint AltHashing::murmur3_32(const jint* data, int len) {
   return murmur3_32(0, data, len);
 }
--- a/src/hotspot/share/classfile/altHashing.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/altHashing.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -43,8 +43,8 @@
   static juint Integer_rotateLeft(juint i, int distance) {
     return (i << distance) | (i >> (32 - distance));
   }
-  static juint murmur3_32(const int* data, int len);
-  static juint murmur3_32(juint seed, const int* data, int len);
+  static juint murmur3_32(const jint* data, int len);
+  static juint murmur3_32(juint seed, const jint* data, int len);
 
  public:
   static juint compute_seed();
--- a/src/hotspot/share/classfile/classFileParser.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "aot/aotLoader.hpp"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
@@ -54,7 +55,6 @@
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/classfile/classLoader.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
@@ -53,7 +54,6 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -604,40 +604,27 @@
 
 const int _boot_loader_dictionary_size    = 1009;
 const int _default_loader_dictionary_size = 107;
-const int _prime_array_size         = 8;                       // array of primes for system dictionary size
-const int _average_depth_goal       = 3;                       // goal for lookup length
-const int _primelist[_prime_array_size] = {107, 1009, 2017, 4049, 5051, 10103, 20201, 40423};
-
-// Calculate a "good" dictionary size based
-// on predicted or current loaded classes count.
-static int calculate_dictionary_size(int classcount) {
-  int newsize = _primelist[0];
-  if (classcount > 0 && !DumpSharedSpaces) {
-    int index = 0;
-    int desiredsize = classcount/_average_depth_goal;
-    for (newsize = _primelist[index]; index < _prime_array_size -1;
-         newsize = _primelist[++index]) {
-      if (desiredsize <=  newsize) {
-        break;
-      }
-    }
-  }
-  return newsize;
-}
 
 Dictionary* ClassLoaderData::create_dictionary() {
   assert(!is_anonymous(), "anonymous class loader data do not have a dictionary");
   int size;
+  bool resizable = false;
   if (_the_null_class_loader_data == NULL) {
     size = _boot_loader_dictionary_size;
+    resizable = true;
   } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
     size = 1;  // there's only one class in relection class loader and no initiated classes
   } else if (is_system_class_loader_data()) {
-    size = calculate_dictionary_size(PredictedLoadedClassCount);
+    size = _boot_loader_dictionary_size;
+    resizable = true;
   } else {
     size = _default_loader_dictionary_size;
+    resizable = true;
   }
-  return new Dictionary(this, size);
+  if (!DynamicallyResizeSystemDictionaries || DumpSharedSpaces || UseSharedSpaces) {
+    resizable = false;
+  }
+  return new Dictionary(this, size, resizable);
 }
 
 // Unloading support
@@ -1325,6 +1312,19 @@
   }
 }
 
+int ClassLoaderDataGraph::resize_if_needed() {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+  int resized = 0;
+  if (Dictionary::does_any_dictionary_needs_resizing()) {
+    FOR_ALL_DICTIONARY(cld) {
+      if (cld->dictionary()->resize_if_needed()) {
+        resized++;
+      }
+    }
+  }
+  return resized;
+}
+
 void ClassLoaderDataGraph::post_class_unload_events() {
 #if INCLUDE_TRACE
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -143,6 +143,8 @@
     }
   }
 
+  static int resize_if_needed();
+
   static bool has_metaspace_oom()           { return _metaspace_oom; }
   static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
 
--- a/src/hotspot/share/classfile/compactHashtable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/compactHashtable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/compactHashtable.inline.hpp"
 #include "classfile/javaClasses.hpp"
 #include "logging/logMessage.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceShared.hpp"
-#include "prims/jvm.h"
 #include "runtime/vmThread.hpp"
 #include "utilities/numberSeq.hpp"
 #include <sys/stat.h>
--- a/src/hotspot/share/classfile/dictionary.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/dictionary.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -29,6 +29,7 @@
 #include "classfile/protectionDomainCache.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
+#include "gc/shared/gcLocker.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/iterator.hpp"
@@ -39,6 +40,11 @@
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/hashtable.inline.hpp"
 
+// Optimization: if any dictionary needs resizing, we set this flag,
+// so that we dont't have to walk all dictionaries to check if any actually
+// needs resizing, which is costly to do at Safepoint.
+bool Dictionary::_some_dictionary_needs_resizing = false;
+
 size_t Dictionary::entry_size() {
   if (DumpSharedSpaces) {
     return SystemDictionaryShared::dictionary_entry_size();
@@ -47,15 +53,17 @@
   }
 }
 
-Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size)
-  : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) {
+Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable)
+  : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false),
+  Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) {
 };
 
 
 Dictionary::Dictionary(ClassLoaderData* loader_data,
                        int table_size, HashtableBucket<mtClass>* t,
-                       int number_of_entries)
-  : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
+                       int number_of_entries, bool resizable)
+  : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false),
+  Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) {
 };
 
 Dictionary::~Dictionary() {
@@ -96,6 +104,60 @@
   FREE_C_HEAP_ARRAY(char, entry);
 }
 
+const int _resize_load_trigger = 5;       // load factor that will trigger the resize
+const double _resize_factor    = 2.0;     // by how much we will resize using current number of entries
+const int _resize_max_size     = 40423;   // the max dictionary size allowed
+const int _primelist[] = {107, 1009, 2017, 4049, 5051, 10103, 20201, _resize_max_size};
+const int _prime_array_size = sizeof(_primelist)/sizeof(int);
+
+// Calculate next "good" dictionary size based on requested count
+static int calculate_dictionary_size(int requested) {
+  int newsize = _primelist[0];
+  int index = 0;
+  for (newsize = _primelist[index]; index < (_prime_array_size - 1);
+       newsize = _primelist[++index]) {
+    if (requested <= newsize) {
+      break;
+    }
+  }
+  return newsize;
+}
+
+bool Dictionary::does_any_dictionary_needs_resizing() {
+  return Dictionary::_some_dictionary_needs_resizing;
+}
+
+void Dictionary::check_if_needs_resize() {
+  if (_resizable == true) {
+    if (number_of_entries() > (_resize_load_trigger*table_size())) {
+      _needs_resizing = true;
+      Dictionary::_some_dictionary_needs_resizing = true;
+    }
+  }
+}
+
+bool Dictionary::resize_if_needed() {
+  int desired_size = 0;
+  if (_needs_resizing == true) {
+    desired_size = calculate_dictionary_size((int)(_resize_factor*number_of_entries()));
+    if (desired_size >= _resize_max_size) {
+      desired_size = _resize_max_size;
+      // We have reached the limit, turn resizing off
+      _resizable = false;
+    }
+    if ((desired_size != 0) && (desired_size != table_size())) {
+      if (!resize(desired_size)) {
+        // Something went wrong, turn resizing off
+        _resizable = false;
+      }
+    }
+  }
+
+  _needs_resizing = false;
+  Dictionary::_some_dictionary_needs_resizing = false;
+
+  return (desired_size != 0);
+}
 
 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
 #ifdef ASSERT
@@ -264,14 +326,16 @@
 // also cast to volatile;  we do this to ensure store order is maintained
 // by the compilers.
 
-void Dictionary::add_klass(int index, unsigned int hash, Symbol* class_name,
+void Dictionary::add_klass(unsigned int hash, Symbol* class_name,
                            InstanceKlass* obj) {
   assert_locked_or_safepoint(SystemDictionary_lock);
   assert(obj != NULL, "adding NULL obj");
   assert(obj->name() == class_name, "sanity check on name");
 
   DictionaryEntry* entry = new_entry(hash, obj);
+  int index = hash_to_index(hash);
   add_entry(index, entry);
+  check_if_needs_resize();
 }
 
 
@@ -299,8 +363,11 @@
 }
 
 
-InstanceKlass* Dictionary::find(int index, unsigned int hash, Symbol* name,
+InstanceKlass* Dictionary::find(unsigned int hash, Symbol* name,
                                 Handle protection_domain) {
+  NoSafepointVerifier nsv;
+
+  int index = hash_to_index(hash);
   DictionaryEntry* entry = get_entry(index, hash, name);
   if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
     return entry->instance_klass();
@@ -350,13 +417,24 @@
 }
 
 
-bool Dictionary::is_valid_protection_domain(int index, unsigned int hash,
+bool Dictionary::is_valid_protection_domain(unsigned int hash,
                                             Symbol* name,
                                             Handle protection_domain) {
+  int index = hash_to_index(hash);
   DictionaryEntry* entry = get_entry(index, hash, name);
   return entry->is_valid_protection_domain(protection_domain);
 }
 
+#if INCLUDE_CDS
+static bool is_jfr_event_class(Klass *k) {
+  while (k) {
+    if (k->name()->equals("jdk/jfr/Event")) {
+      return true;
+    }
+    k = k->super();
+  }
+  return false;
+}
 
 void Dictionary::reorder_dictionary_for_sharing() {
 
@@ -368,14 +446,22 @@
     while (p != NULL) {
       DictionaryEntry* next = p->next();
       InstanceKlass*ik = p->instance_klass();
-      // we cannot include signed classes in the archive because the certificates
-      // used during dump time may be different than those used during
-      // runtime (due to expiration, etc).
       if (ik->signers() != NULL) {
+        // We cannot include signed classes in the archive because the certificates
+        // used during dump time may be different than those used during
+        // runtime (due to expiration, etc).
         ResourceMark rm;
         tty->print_cr("Preload Warning: Skipping %s from signed JAR",
                        ik->name()->as_C_string());
         free_entry(p);
+      } else if (is_jfr_event_class(ik)) {
+        // We cannot include JFR event classes because they need runtime-specific
+        // instrumentation in order to work with -XX:FlightRecorderOptions=retransform=false.
+        // There are only a small number of these classes, so it's not worthwhile to
+        // support them and make CDS more complicated.
+        ResourceMark rm;
+        tty->print_cr("Skipping JFR event class %s", ik->name()->as_C_string());
+        free_entry(p);
       } else {
         p->set_next(master_list);
         master_list = p;
@@ -400,7 +486,7 @@
     set_entry(index, p);
   }
 }
-
+#endif
 
 SymbolPropertyTable::SymbolPropertyTable(int table_size)
   : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))
--- a/src/hotspot/share/classfile/dictionary.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/dictionary.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -43,6 +43,11 @@
 class Dictionary : public Hashtable<InstanceKlass*, mtClass> {
   friend class VMStructs;
 
+  static bool _some_dictionary_needs_resizing;
+  bool _resizable;
+  bool _needs_resizing;
+  void check_if_needs_resize();
+
   ClassLoaderData* _loader_data;  // backpointer to owning loader
   ClassLoaderData* loader_data() const { return _loader_data; }
 
@@ -51,13 +56,16 @@
 protected:
   static size_t entry_size();
 public:
-  Dictionary(ClassLoaderData* loader_data, int table_size);
-  Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
+  Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false);
+  Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries, bool resizable = false);
   ~Dictionary();
 
+  static bool does_any_dictionary_needs_resizing();
+  bool resize_if_needed();
+
   DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);
 
-  void add_klass(int index, unsigned int hash, Symbol* class_name, InstanceKlass* obj);
+  void add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj);
 
   InstanceKlass* find_class(int index, unsigned int hash, Symbol* name);
 
@@ -79,8 +87,8 @@
   void do_unloading();
 
   // Protection domains
-  InstanceKlass* find(int index, unsigned int hash, Symbol* name, Handle protection_domain);
-  bool is_valid_protection_domain(int index, unsigned int hash,
+  InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
+  bool is_valid_protection_domain(unsigned int hash,
                                   Symbol* name,
                                   Handle protection_domain);
   void add_protection_domain(int index, unsigned int hash,
@@ -88,7 +96,7 @@
                              Handle protection_domain, TRAPS);
 
   // Sharing support
-  void reorder_dictionary_for_sharing();
+  void reorder_dictionary_for_sharing() NOT_CDS_RETURN;
 
   void print_on(outputStream* st) const;
   void verify();
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2258,8 +2258,9 @@
 
 void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
   ResourceMark rm(THREAD);
-  Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset));
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k()));
+  Handle mname(THREAD, stackFrame->obj_field(java_lang_StackFrameInfo::_memberName_offset));
+  Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
+  InstanceKlass* holder = InstanceKlass::cast(clazz);
   Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
 
   short version = stackFrame->short_field(_version_offset);
@@ -2270,7 +2271,6 @@
 
 void java_lang_StackFrameInfo::compute_offsets() {
   Klass* k = SystemDictionary::StackFrameInfo_klass();
-  compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(),  vmSymbols::class_signature());
   compute_offset(_memberName_offset,     k, vmSymbols::memberName_name(),  vmSymbols::object_signature());
   compute_offset(_bci_offset,            k, vmSymbols::bci_name(),         vmSymbols::short_signature());
   STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
@@ -3679,7 +3679,6 @@
 int java_lang_StackTraceElement::classLoaderName_offset;
 int java_lang_StackTraceElement::declaringClass_offset;
 int java_lang_StackTraceElement::declaringClassObject_offset;
-int java_lang_StackFrameInfo::_declaringClass_offset;
 int java_lang_StackFrameInfo::_memberName_offset;
 int java_lang_StackFrameInfo::_bci_offset;
 int java_lang_StackFrameInfo::_version_offset;
@@ -3732,11 +3731,6 @@
   element->obj_field_put(declaringClassObject_offset, value);
 }
 
-// Support for java_lang_StackFrameInfo
-void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
-  element->obj_field_put(_declaringClass_offset, value);
-}
-
 void java_lang_StackFrameInfo::set_version(oop element, short value) {
   element->short_field_put(_version_offset, value);
 }
--- a/src/hotspot/share/classfile/javaClasses.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1370,7 +1370,6 @@
 
 class java_lang_StackFrameInfo: AllStatic {
 private:
-  static int _declaringClass_offset;
   static int _memberName_offset;
   static int _bci_offset;
   static int _version_offset;
@@ -1379,7 +1378,6 @@
 
 public:
   // Setters
-  static void set_declaringClass(oop info, oop value);
   static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, TRAPS);
   static void set_bci(oop info, int value);
 
--- a/src/hotspot/share/classfile/modules.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/modules.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
 */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
@@ -40,7 +41,6 @@
 #include "logging/logStream.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "aot/aotLoader.hpp"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
@@ -61,7 +62,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayKlass.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiEnvBase.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "prims/methodHandles.hpp"
@@ -371,7 +371,6 @@
   ClassLoaderData* loader_data = class_loader_data(class_loader);
   Dictionary* dictionary = loader_data->dictionary();
   unsigned int d_hash = dictionary->compute_hash(child_name);
-  int d_index = dictionary->hash_to_index(d_hash);
   unsigned int p_hash = placeholders()->compute_hash(child_name);
   int p_index = placeholders()->hash_to_index(p_hash);
   // can't throw error holding a lock
@@ -379,7 +378,7 @@
   bool throw_circularity_error = false;
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    Klass* childk = find_class(d_index, d_hash, child_name, dictionary);
+    Klass* childk = find_class(d_hash, child_name, dictionary);
     Klass* quicksuperk;
     // to support // loading: if child done loading, just return superclass
     // if class_name, & class_loader don't match:
@@ -487,9 +486,9 @@
 
     Symbol*  kn = klass->name();
     unsigned int d_hash = dictionary->compute_hash(kn);
-    int d_index = dictionary->hash_to_index(d_hash);
 
     MutexLocker mu(SystemDictionary_lock, THREAD);
+    int d_index = dictionary->hash_to_index(d_hash);
     dictionary->add_protection_domain(d_index, d_hash, klass,
                                       protection_domain, THREAD);
   }
@@ -555,7 +554,6 @@
   ClassLoaderData* loader_data = class_loader_data(class_loader);
   Dictionary* dictionary = loader_data->dictionary();
   unsigned int d_hash = dictionary->compute_hash(name);
-  int d_index = dictionary->hash_to_index(d_hash);
   unsigned int p_hash = placeholders()->compute_hash(name);
   int p_index = placeholders()->hash_to_index(p_hash);
 
@@ -579,7 +577,7 @@
  if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // Check if classloading completed while we were loading superclass or waiting
-    return find_class(d_index, d_hash, name, dictionary);
+    return find_class(d_hash, name, dictionary);
   }
 
   // must loop to both handle other placeholder updates
@@ -589,7 +587,7 @@
   while (super_load_in_progress) {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // Check if classloading completed while we were loading superclass or waiting
-    InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
+    InstanceKlass* check = find_class(d_hash, name, dictionary);
     if (check != NULL) {
       // Klass is already loaded, so just return it
       return check;
@@ -670,6 +668,7 @@
   class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
   ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
   Dictionary* dictionary = loader_data->dictionary();
+  unsigned int d_hash = dictionary->compute_hash(name);
 
   // Do lookup to see if class already exist and the protection domain
   // has the right access
@@ -677,11 +676,10 @@
   // All subsequent calls use find_class, and set has_loaded_class so that
   // before we return a result we call out to java to check for valid protection domain
   // to allow returning the Klass* and add it to the pd_set if it is valid
-  unsigned int d_hash = dictionary->compute_hash(name);
-  int d_index = dictionary->hash_to_index(d_hash);
-  Klass* probe = dictionary->find(d_index, d_hash, name, protection_domain);
-  if (probe != NULL) return probe;
-
+  {
+    Klass* probe = dictionary->find(d_hash, name, protection_domain);
+    if (probe != NULL) return probe;
+  }
 
   // Non-bootstrap class loaders will call out to class loader and
   // define via jvm/jni_DefineClass which will acquire the
@@ -716,7 +714,7 @@
 
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
-    InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
+    InstanceKlass* check = find_class(d_hash, name, dictionary);
     if (check != NULL) {
       // Klass is already loaded, so just return it
       class_has_been_loaded = true;
@@ -800,7 +798,7 @@
                 double_lock_wait(lockObject, THREAD);
               }
               // Check if classloading completed while we were waiting
-              InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
+              InstanceKlass* check = find_class(d_hash, name, dictionary);
               if (check != NULL) {
                 // Klass is already loaded, so just return it
                 k = check;
@@ -825,7 +823,7 @@
         // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
         // one final check if the load has already completed
         // class loaders holding the ObjectLock shouldn't find the class here
-        InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
+        InstanceKlass* check = find_class(d_hash, name, dictionary);
         if (check != NULL) {
         // Klass is already loaded, so return it after checking/adding protection domain
           k = check;
@@ -858,7 +856,7 @@
         if (k == NULL && HAS_PENDING_EXCEPTION
           && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
           MutexLocker mu(SystemDictionary_lock, THREAD);
-          InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
+          InstanceKlass* check = find_class(d_hash, name, dictionary);
           if (check != NULL) {
             // Klass is already loaded, so just use it
             k = check;
@@ -873,7 +871,7 @@
       if (!HAS_PENDING_EXCEPTION && k != NULL &&
         k->class_loader() != class_loader()) {
 
-        check_constraints(d_index, d_hash, k, class_loader, false, THREAD);
+        check_constraints(d_hash, k, class_loader, false, THREAD);
 
         // Need to check for a PENDING_EXCEPTION again; check_constraints
         // can throw and doesn't use the CHECK macro.
@@ -881,7 +879,7 @@
           { // Grabbing the Compile_lock prevents systemDictionary updates
             // during compilations.
             MutexLocker mu(Compile_lock, THREAD);
-            update_dictionary(d_index, d_hash, p_index, p_hash,
+            update_dictionary(d_hash, p_index, p_hash,
               k, class_loader, THREAD);
           }
 
@@ -923,7 +921,7 @@
   if (protection_domain() == NULL) return k;
 
   // Check the protection domain has the right access
-  if (dictionary->is_valid_protection_domain(d_index, d_hash, name,
+  if (dictionary->is_valid_protection_domain(d_hash, name,
                                              protection_domain)) {
     return k;
   }
@@ -965,8 +963,7 @@
 
   Dictionary* dictionary = loader_data->dictionary();
   unsigned int d_hash = dictionary->compute_hash(class_name);
-  int d_index = dictionary->hash_to_index(d_hash);
-  return dictionary->find(d_index, d_hash, class_name,
+  return dictionary->find(d_hash, class_name,
                           protection_domain);
 }
 
@@ -1644,8 +1641,7 @@
   Symbol*  name_h = k->name();
   Dictionary* dictionary = loader_data->dictionary();
   unsigned int d_hash = dictionary->compute_hash(name_h);
-  int d_index = dictionary->hash_to_index(d_hash);
-  check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
+  check_constraints(d_hash, k, class_loader_h, true, CHECK);
 
   // Register class just loaded with class loader (placed in Vector)
   // Note we do this before updating the dictionary, as this can
@@ -1673,7 +1669,7 @@
 
     // Add to systemDictionary - so other classes can see it.
     // Grabs and releases SystemDictionary_lock
-    update_dictionary(d_index, d_hash, p_index, p_hash,
+    update_dictionary(d_hash, p_index, p_hash,
                       k, class_loader_h, THREAD);
   }
   k->eager_initialize(THREAD);
@@ -1715,7 +1711,6 @@
   Dictionary* dictionary = loader_data->dictionary();
 
   unsigned int d_hash = dictionary->compute_hash(name_h);
-  int d_index = dictionary->hash_to_index(d_hash);
 
   // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
   unsigned int p_hash = placeholders()->compute_hash(name_h);
@@ -1726,7 +1721,7 @@
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // First check if class already defined
     if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
-      InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
+      InstanceKlass* check = find_class(d_hash, name_h, dictionary);
       if (check != NULL) {
         return check;
       }
@@ -1748,7 +1743,7 @@
         placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
         SystemDictionary_lock->notify_all();
 #ifdef ASSERT
-        InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
+        InstanceKlass* check = find_class(d_hash, name_h, dictionary);
         assert(check != NULL, "definer missed recording success");
 #endif
         return probe->instance_klass();
@@ -1823,10 +1818,11 @@
 // ----------------------------------------------------------------------------
 // Lookup
 
-InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash,
+InstanceKlass* SystemDictionary::find_class(unsigned int hash,
                                             Symbol* class_name,
                                             Dictionary* dictionary) {
   assert_locked_or_safepoint(SystemDictionary_lock);
+  int index = dictionary->hash_to_index(hash);
   return dictionary->find_class(index, hash, class_name);
 }
 
@@ -1856,8 +1852,7 @@
 
   Dictionary* dictionary = loader_data->dictionary();
   unsigned int d_hash = dictionary->compute_hash(class_name);
-  int d_index = dictionary->hash_to_index(d_hash);
-  return find_class(d_index, d_hash, class_name, dictionary);
+  return find_class(d_hash, class_name, dictionary);
 }
 
 
@@ -2210,7 +2205,7 @@
 // if defining is true, then LinkageError if already in dictionary
 // if initiating loader, then ok if InstanceKlass matches existing entry
 
-void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
+void SystemDictionary::check_constraints(unsigned int d_hash,
                                          InstanceKlass* k,
                                          Handle class_loader, bool defining,
                                          TRAPS) {
@@ -2222,7 +2217,7 @@
 
     MutexLocker mu(SystemDictionary_lock, THREAD);
 
-    InstanceKlass* check = find_class(d_index, d_hash, name, loader_data->dictionary());
+    InstanceKlass* check = find_class(d_hash, name, loader_data->dictionary());
     if (check != NULL) {
       // if different InstanceKlass - duplicate class definition,
       // else - ok, class loaded by a different thread in parallel,
@@ -2270,7 +2265,7 @@
 
 // Update class loader data dictionary - done after check_constraint and add_to_hierachy
 // have been called.
-void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
+void SystemDictionary::update_dictionary(unsigned int d_hash,
                                          int p_index, unsigned int p_hash,
                                          InstanceKlass* k,
                                          Handle class_loader,
@@ -2305,13 +2300,13 @@
 
     // Make a new dictionary entry.
     Dictionary* dictionary = loader_data->dictionary();
-    InstanceKlass* sd_check = find_class(d_index, d_hash, name, dictionary);
+    InstanceKlass* sd_check = find_class(d_hash, name, dictionary);
     if (sd_check == NULL) {
-      dictionary->add_klass(d_index, d_hash, name, k);
+      dictionary->add_klass(d_hash, name, k);
       notice_modification();
     }
   #ifdef ASSERT
-    sd_check = find_class(d_index, d_hash, name, dictionary);
+    sd_check = find_class(d_hash, name, dictionary);
     assert (sd_check != NULL, "should have entry in dictionary");
     // Note: there may be a placeholder entry: for circularity testing
     // or for parallel defines
@@ -2388,16 +2383,14 @@
 
   Dictionary* dictionary1 = loader_data1->dictionary();
   unsigned int d_hash1 = dictionary1->compute_hash(constraint_name);
-  int d_index1 = dictionary1->hash_to_index(d_hash1);
 
   Dictionary* dictionary2 = loader_data2->dictionary();
   unsigned int d_hash2 = dictionary2->compute_hash(constraint_name);
-  int d_index2 = dictionary2->hash_to_index(d_hash2);
 
   {
     MutexLocker mu_s(SystemDictionary_lock, THREAD);
-    InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, dictionary1);
-    InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, dictionary2);
+    InstanceKlass* klass1 = find_class(d_hash1, constraint_name, dictionary1);
+    InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2);
     return constraints()->add_entry(constraint_name, klass1, class_loader1,
                                     klass2, class_loader2);
   }
@@ -2855,9 +2848,11 @@
   return _pd_cache_table->get(protection_domain);
 }
 
+#if INCLUDE_CDS
 void SystemDictionary::reorder_dictionary_for_sharing() {
   ClassLoaderData::the_null_class_loader_data()->dictionary()->reorder_dictionary_for_sharing();
 }
+#endif
 
 size_t SystemDictionary::count_bytes_for_buckets() {
   return ClassLoaderData::the_null_class_loader_data()->dictionary()->count_bytes_for_buckets();
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -384,7 +384,7 @@
 
 public:
   // Sharing support.
-  static void reorder_dictionary_for_sharing();
+  static void reorder_dictionary_for_sharing() NOT_CDS_RETURN;
   static void combine_shared_dictionaries();
   static size_t count_bytes_for_buckets();
   static size_t count_bytes_for_table();
@@ -655,11 +655,8 @@
   // Setup link to hierarchy
   static void add_to_hierarchy(InstanceKlass* k, TRAPS);
 
-  // We pass in the hashtable index so we can calculate it outside of
-  // the SystemDictionary_lock.
-
   // Basic find on loaded classes
-  static InstanceKlass* find_class(int index, unsigned int hash,
+  static InstanceKlass* find_class(unsigned int hash,
                                    Symbol* name, Dictionary* dictionary);
   static InstanceKlass* find_class(Symbol* class_name, ClassLoaderData* loader_data);
 
@@ -685,10 +682,10 @@
   static void initialize_preloaded_classes(TRAPS);
 
   // Class loader constraints
-  static void check_constraints(int index, unsigned int hash,
+  static void check_constraints(unsigned int hash,
                                 InstanceKlass* k, Handle loader,
                                 bool defining, TRAPS);
-  static void update_dictionary(int d_index, unsigned int d_hash,
+  static void update_dictionary(unsigned int d_hash,
                                 int p_index, unsigned int p_hash,
                                 InstanceKlass* k, Handle loader,
                                 TRAPS);
--- a/src/hotspot/share/classfile/verifier.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/verifier.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classFileStream.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/stackMapTable.hpp"
@@ -40,7 +41,6 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
-#include "prims/jvm.h"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/src/hotspot/share/classfile/vmSymbols.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/vmSymbols.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/vmSymbols.hpp"
 #include "compiler/compilerDirectives.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/handles.inline.hpp"
 #include "utilities/xmlstream.hpp"
 
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -429,7 +429,6 @@
   template(append_name,                               "append")                                   \
   template(klass_name,                                "klass")                                    \
   template(array_klass_name,                          "array_klass")                              \
-  template(declaringClass_name,                       "declaringClass")                           \
   template(memberName_name,                           "memberName")                               \
   template(mid_name,                                  "mid")                                      \
   template(cpref_name,                                "cpref")                                    \
--- a/src/hotspot/share/code/codeBlob.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/codeBlob.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "code/codeBlob.hpp"
 #include "code/codeCache.hpp"
 #include "code/relocInfo.hpp"
@@ -33,7 +34,6 @@
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"
-#include "prims/jvm.h"
 #include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/code/codeBlob.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/codeBlob.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -49,21 +49,35 @@
 // CodeBlob - superclass for all entries in the CodeCache.
 //
 // Subtypes are:
-//   CompiledMethod       : Compiled Java methods (include method that calls to native code)
-//     nmethod            : JIT Compiled Java methods
-//   RuntimeBlob          : Non-compiled method code; generated glue code
-//     RuntimeStub        : Call to VM runtime methods
-//     DeoptimizationBlob : Used for deoptimization
-//     ExceptionBlob      : Used for stack unrolling
-//     SafepointBlob      : Used to handle illegal instruction exceptions
+//  CompiledMethod       : Compiled Java methods (include method that calls to native code)
+//   nmethod             : JIT Compiled Java methods
+//   AOTCompiledMethod   : AOT Compiled Java methods - Not in the CodeCache!
+//                         AOTCompiledMethod objects are allocated in the C-Heap, the code they
+//                         point to is allocated in the AOTCodeHeap which is in the C-Heap as
+//                         well (i.e. it's the memory where the shared library was loaded to)
+//  RuntimeBlob          : Non-compiled method code; generated glue code
+//   BufferBlob          : Used for non-relocatable code such as interpreter, stubroutines, etc.
+//    AdapterBlob        : Used to hold C2I/I2C adapters
+//    MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
+//   RuntimeStub         : Call to VM runtime methods
+//   SingletonBlob       : Super-class for all blobs that exist in only one instance
+//    DeoptimizationBlob : Used for deoptimization
+//    ExceptionBlob      : Used for stack unrolling
+//    SafepointBlob      : Used to handle illegal instruction exceptions
+//    UncommonTrapBlob   : Used to handle uncommon traps
 //
 //
-// Layout:
+// Layout (all except AOTCompiledMethod) : continuous in the CodeCache
 //   - header
 //   - relocation
 //   - content space
 //     - instruction space
 //   - data space
+//
+// Layout (AOTCompiledMethod) : in the C-Heap
+//   - header -\
+//     ...     |
+//   - code  <-/
 
 
 class CodeBlobLayout;
--- a/src/hotspot/share/code/nmethod.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/nmethod.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "code/codeCache.hpp"
 #include "code/compiledIC.hpp"
 #include "code/dependencies.hpp"
@@ -41,7 +42,6 @@
 #include "memory/resourceArea.hpp"
 #include "oops/methodData.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiImpl.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/orderAccess.inline.hpp"
@@ -409,6 +409,7 @@
 #if INCLUDE_JVMCI
   _jvmci_installed_code   = NULL;
   _speculation_log        = NULL;
+  _jvmci_installed_code_triggers_unloading = false;
 #endif
 }
 
@@ -461,8 +462,8 @@
   AbstractCompiler* compiler,
   int comp_level
 #if INCLUDE_JVMCI
-  , Handle installed_code,
-  Handle speculationLog
+  , jweak installed_code,
+  jweak speculationLog
 #endif
 )
 {
@@ -642,8 +643,8 @@
   AbstractCompiler* compiler,
   int comp_level
 #if INCLUDE_JVMCI
-  , Handle installed_code,
-  Handle speculation_log
+  , jweak installed_code,
+  jweak speculation_log
 #endif
   )
   : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
@@ -671,8 +672,14 @@
     set_ctable_begin(header_begin() + _consts_offset);
 
 #if INCLUDE_JVMCI
-    _jvmci_installed_code = installed_code();
-    _speculation_log = (instanceOop)speculation_log();
+    _jvmci_installed_code = installed_code;
+    _speculation_log = speculation_log;
+    oop obj = JNIHandles::resolve(installed_code);
+    if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) {
+      _jvmci_installed_code_triggers_unloading = false;
+    } else {
+      _jvmci_installed_code_triggers_unloading = true;
+    }
 
     if (compiler->is_jvmci()) {
       // JVMCI might not produce any stub sections
@@ -1026,8 +1033,6 @@
                   " unloadable, Method*(" INTPTR_FORMAT
                   "), cause(" INTPTR_FORMAT ")",
                   p2i(this), p2i(_method), p2i(cause));
-    if (!Universe::heap()->is_gc_active())
-      cause->klass()->print_on(&ls);
   }
   // Unlink the osr method, so we do not look this up again
   if (is_osr_method()) {
@@ -1077,14 +1082,8 @@
 #if INCLUDE_JVMCI
   // The method can only be unloaded after the pointer to the installed code
   // Java wrapper is no longer alive. Here we need to clear out this weak
-  // reference to the dead object. Nulling out the reference has to happen
-  // after the method is unregistered since the original value may be still
-  // tracked by the rset.
+  // reference to the dead object.
   maybe_invalidate_installed_code();
-  // Clear these out after the nmethod has been unregistered and any
-  // updates to the InstalledCode instance have been performed.
-  _jvmci_installed_code = NULL;
-  _speculation_log = NULL;
 #endif
 
   // The Method* is gone at this point
@@ -1246,10 +1245,6 @@
       MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       if (nmethod_needs_unregister) {
         Universe::heap()->unregister_nmethod(this);
-#ifdef JVMCI
-        _jvmci_installed_code = NULL;
-        _speculation_log = NULL;
-#endif
       }
       flush_dependencies(NULL);
     }
@@ -1314,6 +1309,11 @@
     CodeCache::drop_scavenge_root_nmethod(this);
   }
 
+#if INCLUDE_JVMCI
+  assert(_jvmci_installed_code == NULL, "should have been nulled out when transitioned to zombie");
+  assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie");
+#endif
+
   CodeBlob::flush();
   CodeCache::free(this);
 }
@@ -1500,29 +1500,18 @@
 
 #if INCLUDE_JVMCI
 bool nmethod::do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred) {
-  bool is_unloaded = false;
-  // Follow JVMCI method
-  BarrierSet* bs = Universe::heap()->barrier_set();
   if (_jvmci_installed_code != NULL) {
-    if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) {
-      if (!is_alive->do_object_b(_jvmci_installed_code)) {
+    if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
+      if (_jvmci_installed_code_triggers_unloading) {
+        // jweak reference processing has already cleared the referent
+        make_unloaded(is_alive, NULL);
+        return true;
+      } else {
         clear_jvmci_installed_code();
       }
-    } else {
-      if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
-        return true;
-      }
     }
   }
-
-  if (_speculation_log != NULL) {
-    if (!is_alive->do_object_b(_speculation_log)) {
-      bs->write_ref_nmethod_pre(&_speculation_log, this);
-      _speculation_log = NULL;
-      bs->write_ref_nmethod_post(&_speculation_log, this);
-    }
-  }
-  return is_unloaded;
+  return false;
 }
 #endif
 
@@ -1594,15 +1583,6 @@
     // (See comment above.)
   }
 
-#if INCLUDE_JVMCI
-  if (_jvmci_installed_code != NULL) {
-    f->do_oop((oop*) &_jvmci_installed_code);
-  }
-  if (_speculation_log != NULL) {
-    f->do_oop((oop*) &_speculation_log);
-  }
-#endif
-
   RelocIterator iter(this, low_boundary);
 
   while (iter.next()) {
@@ -2860,43 +2840,49 @@
 
 #if INCLUDE_JVMCI
 void nmethod::clear_jvmci_installed_code() {
-  // write_ref_method_pre/post can only be safely called at a
-  // safepoint or while holding the CodeCache_lock
-  assert(CodeCache_lock->is_locked() ||
-         SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency");
+  assert_locked_or_safepoint(Patching_lock);
   if (_jvmci_installed_code != NULL) {
-    // This must be done carefully to maintain nmethod remembered sets properly
-    BarrierSet* bs = Universe::heap()->barrier_set();
-    bs->write_ref_nmethod_pre(&_jvmci_installed_code, this);
+    JNIHandles::destroy_weak_global(_jvmci_installed_code);
     _jvmci_installed_code = NULL;
-    bs->write_ref_nmethod_post(&_jvmci_installed_code, this);
+  }
+}
+
+void nmethod::clear_speculation_log() {
+  assert_locked_or_safepoint(Patching_lock);
+  if (_speculation_log != NULL) {
+    JNIHandles::destroy_weak_global(_speculation_log);
+    _speculation_log = NULL;
   }
 }
 
 void nmethod::maybe_invalidate_installed_code() {
   assert(Patching_lock->is_locked() ||
          SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency");
-  oop installed_code = jvmci_installed_code();
+  oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
   if (installed_code != NULL) {
+    // Update the values in the InstalledCode instance if it still refers to this nmethod
     nmethod* nm = (nmethod*)InstalledCode::address(installed_code);
-    if (nm == NULL || nm != this) {
-      // The link has been broken or the InstalledCode instance is
-      // associated with another nmethod so do nothing.
-      return;
+    if (nm == this) {
+      if (!is_alive()) {
+        // Break the link between nmethod and InstalledCode such that the nmethod
+        // can subsequently be flushed safely.  The link must be maintained while
+        // the method could have live activations since invalidateInstalledCode
+        // might want to invalidate all existing activations.
+        InstalledCode::set_address(installed_code, 0);
+        InstalledCode::set_entryPoint(installed_code, 0);
+      } else if (is_not_entrant()) {
+        // Remove the entry point so any invocation will fail but keep
+        // the address link around that so that existing activations can
+        // be invalidated.
+        InstalledCode::set_entryPoint(installed_code, 0);
+      }
     }
-    if (!is_alive()) {
-      // Break the link between nmethod and InstalledCode such that the nmethod
-      // can subsequently be flushed safely.  The link must be maintained while
-      // the method could have live activations since invalidateInstalledCode
-      // might want to invalidate all existing activations.
-      InstalledCode::set_address(installed_code, 0);
-      InstalledCode::set_entryPoint(installed_code, 0);
-    } else if (is_not_entrant()) {
-      // Remove the entry point so any invocation will fail but keep
-      // the address link around that so that existing activations can
-      // be invalidated.
-      InstalledCode::set_entryPoint(installed_code, 0);
-    }
+  }
+  if (!is_alive()) {
+    // Clear these out after the nmethod has been unregistered and any
+    // updates to the InstalledCode instance have been performed.
+    clear_jvmci_installed_code();
+    clear_speculation_log();
   }
 }
 
@@ -2916,45 +2902,49 @@
   {
     MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
     // This relationship can only be checked safely under a lock
-    assert(nm == NULL || !nm->is_alive() || nm->jvmci_installed_code() == installedCode(), "sanity check");
+    assert(!nm->is_alive() || nm->jvmci_installed_code() == installedCode(), "sanity check");
   }
 #endif
 
   if (nm->is_alive()) {
-    // The nmethod state machinery maintains the link between the
-    // HotSpotInstalledCode and nmethod* so as long as the nmethod appears to be
-    // alive assume there is work to do and deoptimize the nmethod.
+    // Invalidating the InstalledCode means we want the nmethod
+    // to be deoptimized.
     nm->mark_for_deoptimization();
     VM_Deoptimize op;
     VMThread::execute(&op);
   }
 
+  // Multiple threads could reach this point so we now need to
+  // lock and re-check the link to the nmethod so that only one
+  // thread clears it.
   MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
-  // Check that it's still associated with the same nmethod and break
-  // the link if it is.
   if (InstalledCode::address(installedCode) == nativeMethod) {
-    InstalledCode::set_address(installedCode, 0);
+      InstalledCode::set_address(installedCode, 0);
   }
 }
 
+oop nmethod::jvmci_installed_code() {
+  return JNIHandles::resolve(_jvmci_installed_code);
+}
+
+oop nmethod::speculation_log() {
+  return JNIHandles::resolve(_speculation_log);
+}
+
 char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) {
   if (!this->is_compiled_by_jvmci()) {
     return NULL;
   }
-  oop installedCode = this->jvmci_installed_code();
-  if (installedCode != NULL) {
-    oop installedCodeName = NULL;
-    if (installedCode->is_a(InstalledCode::klass())) {
-      installedCodeName = InstalledCode::name(installedCode);
+  oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
+  if (installed_code != NULL) {
+    oop installed_code_name = NULL;
+    if (installed_code->is_a(InstalledCode::klass())) {
+      installed_code_name = InstalledCode::name(installed_code);
     }
-    if (installedCodeName != NULL) {
-      return java_lang_String::as_utf8_string(installedCodeName, buf, (int)buflen);
-    } else {
-      jio_snprintf(buf, buflen, "null");
-      return buf;
+    if (installed_code_name != NULL) {
+      return java_lang_String::as_utf8_string(installed_code_name, buf, (int)buflen);
     }
   }
-  jio_snprintf(buf, buflen, "noInstalledCode");
-  return buf;
+  return NULL;
 }
 #endif
--- a/src/hotspot/share/code/nmethod.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/nmethod.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -63,9 +63,22 @@
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
 
 #if INCLUDE_JVMCI
-  // Needed to keep nmethods alive that are not the default nmethod for the associated Method.
-  oop       _jvmci_installed_code;
-  oop       _speculation_log;
+  // A weak reference to an InstalledCode object associated with
+  // this nmethod.
+  jweak     _jvmci_installed_code;
+
+  // A weak reference to a SpeculationLog object associated with
+  // this nmethod.
+  jweak     _speculation_log;
+
+  // Determines whether this nmethod is unloaded when the
+  // referent in _jvmci_installed_code is cleared. This
+  // will be false if the referent is initialized to a
+  // HotSpotNMethod object whose isDefault field is true.
+  // That is, installed code other than a "default"
+  // HotSpotNMethod causes nmethod unloading.
+  // This field is ignored once _jvmci_installed_code is NULL.
+  bool _jvmci_installed_code_triggers_unloading;
 #endif
 
   // To support simple linked-list chaining of nmethods:
@@ -192,8 +205,8 @@
           AbstractCompiler* compiler,
           int comp_level
 #if INCLUDE_JVMCI
-          , Handle installed_code,
-          Handle speculation_log
+          , jweak installed_code,
+          jweak speculation_log
 #endif
           );
 
@@ -236,8 +249,8 @@
                               AbstractCompiler* compiler,
                               int comp_level
 #if INCLUDE_JVMCI
-                              , Handle installed_code = Handle(),
-                              Handle speculation_log = Handle()
+                              , jweak installed_code = NULL,
+                              jweak speculation_log = NULL
 #endif
   );
 
@@ -433,27 +446,46 @@
   void set_method(Method* method) { _method = method; }
 
 #if INCLUDE_JVMCI
-  oop jvmci_installed_code() { return _jvmci_installed_code ; }
+  // Gets the InstalledCode object associated with this nmethod
+  // which may be NULL if this nmethod was not compiled by JVMCI
+  // or the weak reference has been cleared.
+  oop jvmci_installed_code();
+
+  // Copies the value of the name field in the InstalledCode
+  // object (if any) associated with this nmethod into buf.
+  // Returns the value of buf if it was updated otherwise NULL.
   char* jvmci_installed_code_name(char* buf, size_t buflen);
 
-  // Update the state of any InstalledCode instance associated with
+  // Updates the state of the InstalledCode (if any) associated with
   // this nmethod based on the current value of _state.
   void maybe_invalidate_installed_code();
 
-  // Helper function to invalidate InstalledCode instances
+  // Deoptimizes the nmethod (if any) in the address field of a given
+  // InstalledCode object. The address field is zeroed upon return.
   static void invalidate_installed_code(Handle installed_code, TRAPS);
 
-  oop speculation_log() { return _speculation_log ; }
+  // Gets the SpeculationLog object associated with this nmethod
+  // which may be NULL if this nmethod was not compiled by JVMCI
+  // or the weak reference has been cleared.
+  oop speculation_log();
 
  private:
+  // Deletes the weak reference (if any) to the InstalledCode object
+  // associated with this nmethod.
   void clear_jvmci_installed_code();
 
+  // Deletes the weak reference (if any) to the SpeculationLog object
+  // associated with this nmethod.
+  void clear_speculation_log();
+
  public:
 #endif
 
  protected:
   virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred);
 #if INCLUDE_JVMCI
+  // See comment for _jvmci_installed_code_triggers_unloading field.
+  // Returns whether this nmethod was unloaded.
   virtual bool do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred);
 #endif
 
--- a/src/hotspot/share/code/relocInfo.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/relocInfo.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -489,7 +489,7 @@
 #ifndef _LP64
   _target = (address) (intptr_t)unpack_1_int();
 #else
-  int32_t lo, hi;
+  jint lo, hi;
   unpack_2_ints(lo, hi);
   jlong t = jlong_from(hi, lo);;
   _target = (address) t;
--- a/src/hotspot/share/code/scopeDesc.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/code/scopeDesc.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -228,7 +228,7 @@
     }
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (NOT_JVMCI(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
     st->print_cr("   Objects");
     for (int i = 0; i < _objects->length(); i++) {
@@ -239,7 +239,7 @@
       st->cr();
     }
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 #endif
--- a/src/hotspot/share/compiler/compileBroker.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -40,7 +41,6 @@
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/nativeLookup.hpp"
 #include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
@@ -108,7 +108,7 @@
 
 bool CompileBroker::_initialized = false;
 volatile bool CompileBroker::_should_block = false;
-volatile jint CompileBroker::_print_compilation_warning = 0;
+volatile int  CompileBroker::_print_compilation_warning = 0;
 volatile jint CompileBroker::_should_compile_new_jobs = run_compilation;
 
 // The installed compiler(s)
--- a/src/hotspot/share/compiler/compileBroker.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/compileBroker.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -217,7 +217,7 @@
   static int _sum_nmethod_code_size;
   static long _peak_compilation_time;
 
-  static volatile jint _print_compilation_warning;
+  static volatile int _print_compilation_warning;
 
   static JavaThread* make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, bool compiler_thread, TRAPS);
   static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count);
--- a/src/hotspot/share/compiler/compileLog.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/compileLog.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "ci/ciMethod.hpp"
 #include "code/codeCache.hpp"
 #include "compiler/compileLog.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/method.hpp"
-#include "prims/jvm.h"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
 
--- a/src/hotspot/share/compiler/compilerOracle.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/compilerOracle.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "compiler/compilerOracle.hpp"
 #include "compiler/methodMatcher.hpp"
 #include "memory/allocation.inline.hpp"
@@ -31,7 +32,6 @@
 #include "oops/klass.hpp"
 #include "oops/method.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/compiler/oopMap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/oopMap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -268,9 +268,9 @@
 #if !defined(TIERED) && !defined(INCLUDE_JVMCI)
   COMPILER1_PRESENT(ShouldNotReachHere();)
 #endif // !defined(TIERED) && !defined(INCLUDE_JVMCI)
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::add(derived, base);
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 
@@ -461,12 +461,12 @@
 #if !defined(TIERED) && !defined(INCLUDE_JVMCI)
   COMPILER1_PRESENT(return false);
 #endif // !TIERED
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   OopMapStream oms(this,OopMapValue::derived_oop_value);
   return oms.is_done();
 #else
   return false;
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 }
 
 #endif //PRODUCT
@@ -726,7 +726,7 @@
 
 //------------------------------DerivedPointerTable---------------------------
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
 class DerivedPointerEntry : public CHeapObj<mtCompiler> {
  private:
@@ -819,4 +819,4 @@
   _active = false;
 }
 
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/compiler/oopMap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/compiler/oopMap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -427,7 +427,7 @@
 // oops, it is filled in with references to all locations that contains a
 // derived oop (assumed to be very few).  When the GC is complete, the derived
 // pointers are updated based on their base pointers new value and an offset.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 class DerivedPointerTable : public AllStatic {
   friend class VMStructs;
  private:
@@ -463,6 +463,6 @@
     }
   }
 };
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #endif // SHARE_VM_COMPILER_OOPMAP_HPP
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -39,14 +39,16 @@
 class WorkGang;
 
 class CMSHeap : public GenCollectedHeap {
+
+protected:
+  virtual void check_gen_kinds();
+
 public:
   CMSHeap(GenCollectorPolicy *policy);
 
   // Returns JNI_OK on success
   virtual jint initialize();
 
-  virtual void check_gen_kinds();
-
   // Convenience function to be used in situations where the heap type can be
   // asserted to be this type.
   static CMSHeap* heap();
@@ -70,10 +72,6 @@
   // supports. Caller does not hold the Heap_lock on entry.
   void collect(GCCause::Cause cause);
 
-  bool is_in_closed_subset(const void* p) const {
-    return is_in_reserved(p);
-  }
-
   bool card_mark_must_follow_store() const {
     return true;
   }
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -57,6 +57,7 @@
 // Defaults are 0 so things will break badly if incorrectly initialized.
 size_t CompactibleFreeListSpace::IndexSetStart  = 0;
 size_t CompactibleFreeListSpace::IndexSetStride = 0;
+size_t CompactibleFreeListSpace::_min_chunk_size_in_bytes = 0;
 
 size_t MinChunkSize = 0;
 
@@ -66,8 +67,8 @@
 
   // MinChunkSize should be a multiple of MinObjAlignment and be large enough
   // for chunks to contain a FreeChunk.
-  size_t min_chunk_size_in_bytes = align_up(sizeof(FreeChunk), MinObjAlignmentInBytes);
-  MinChunkSize = min_chunk_size_in_bytes / BytesPerWord;
+  _min_chunk_size_in_bytes = align_up(sizeof(FreeChunk), MinObjAlignmentInBytes);
+  MinChunkSize = _min_chunk_size_in_bytes / BytesPerWord;
 
   assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
   IndexSetStart  = MinChunkSize;
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -118,6 +118,7 @@
   };
   static size_t IndexSetStart;
   static size_t IndexSetStride;
+  static size_t _min_chunk_size_in_bytes;
 
  private:
   enum FitStrategyOptions {
@@ -134,6 +135,7 @@
   // A lock protecting the free lists and free blocks;
   // mutable because of ubiquity of locking even for otherwise const methods
   mutable Mutex _freelistLock;
+
   // Locking verifier convenience function
   void assert_locked() const PRODUCT_RETURN;
   void assert_locked(const Mutex* lock) const PRODUCT_RETURN;
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2296,7 +2296,7 @@
   // way with the marking information used by GC.
   NoRefDiscovery no_discovery(ref_processor());
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTableDeactivate dpt_deact;
 #endif
 
@@ -2869,7 +2869,7 @@
   print_eden_and_survivor_chunk_arrays();
 
   {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
     if (CMSParallelInitialMarkEnabled) {
@@ -4171,7 +4171,7 @@
   print_eden_and_survivor_chunk_arrays();
 
   {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
 
--- a/src/hotspot/share/gc/cms/vmStructs_cms.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/cms/vmStructs_cms.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -30,7 +30,8 @@
                    static_field) \
   nonstatic_field(CompactibleFreeListSpace,    _collector,                                    CMSCollector*)                         \
   nonstatic_field(CompactibleFreeListSpace,    _bt,                                           BlockOffsetArrayNonContigSpace)        \
-                                                                                                                                     \
+     static_field(CompactibleFreeListSpace,    _min_chunk_size_in_bytes,                      size_t)                                \
+  nonstatic_field(CMSBitMap,                   _bmStartWord,                                  HeapWord*)                             \
   nonstatic_field(CMSBitMap,                   _bmWordSize,                                   size_t)                                \
   nonstatic_field(CMSBitMap,                   _shifter,                                      const int)                             \
   nonstatic_field(CMSBitMap,                   _bm,                                           BitMapView)                            \
@@ -63,6 +64,7 @@
   declare_toplevel_type(LinearAllocBlock)
 
 #define VM_INT_CONSTANTS_CMS(declare_constant)                            \
+  declare_constant(CompactibleFreeListSpace::IndexSetSize)                \
   declare_constant(Generation::ConcurrentMarkSweep)                       \
 
 #endif // SHARE_VM_GC_CMS_VMSTRUCTS_CMS_HPP
--- a/src/hotspot/share/gc/g1/concurrentG1Refine.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,370 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
-#include "gc/g1/concurrentG1RefineThread.hpp"
-#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
-#include "logging/log.hpp"
-#include "runtime/java.hpp"
-#include "runtime/thread.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/pair.hpp"
-#include <math.h>
-
-// Arbitrary but large limits, to simplify some of the zone calculations.
-// The general idea is to allow expressions like
-//   MIN2(x OP y, max_XXX_zone)
-// without needing to check for overflow in "x OP y", because the
-// ranges for x and y have been restricted.
-STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
-const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
-const size_t max_green_zone = max_yellow_zone / 2;
-const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
-STATIC_ASSERT(max_yellow_zone <= max_red_zone);
-
-// Range check assertions for green zone values.
-#define assert_zone_constraints_g(green)                        \
-  do {                                                          \
-    size_t azc_g_green = (green);                               \
-    assert(azc_g_green <= max_green_zone,                       \
-           "green exceeds max: " SIZE_FORMAT, azc_g_green);     \
-  } while (0)
-
-// Range check assertions for green and yellow zone values.
-#define assert_zone_constraints_gy(green, yellow)                       \
-  do {                                                                  \
-    size_t azc_gy_green = (green);                                      \
-    size_t azc_gy_yellow = (yellow);                                    \
-    assert_zone_constraints_g(azc_gy_green);                            \
-    assert(azc_gy_yellow <= max_yellow_zone,                            \
-           "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow);          \
-    assert(azc_gy_green <= azc_gy_yellow,                               \
-           "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")",  \
-           azc_gy_green, azc_gy_yellow);                                \
-  } while (0)
-
-// Range check assertions for green, yellow, and red zone values.
-#define assert_zone_constraints_gyr(green, yellow, red)                 \
-  do {                                                                  \
-    size_t azc_gyr_green = (green);                                     \
-    size_t azc_gyr_yellow = (yellow);                                   \
-    size_t azc_gyr_red = (red);                                         \
-    assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow);          \
-    assert(azc_gyr_red <= max_red_zone,                                 \
-           "red exceeds max: " SIZE_FORMAT, azc_gyr_red);               \
-    assert(azc_gyr_yellow <= azc_gyr_red,                               \
-           "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")",    \
-           azc_gyr_yellow, azc_gyr_red);                                \
-  } while (0)
-
-// Logging tag sequence for refinement control updates.
-#define CTRL_TAGS gc, ergo, refine
-
-// For logging zone values, ensuring consistency of level and tags.
-#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__)
-
-// Package for pair of refinement thread activation and deactivation
-// thresholds.  The activation and deactivation levels are resp. the first
-// and second values of the pair.
-typedef Pair<size_t, size_t> Thresholds;
-inline size_t activation_level(const Thresholds& t) { return t.first; }
-inline size_t deactivation_level(const Thresholds& t) { return t.second; }
-
-static Thresholds calc_thresholds(size_t green_zone,
-                                  size_t yellow_zone,
-                                  uint worker_i) {
-  double yellow_size = yellow_zone - green_zone;
-  double step = yellow_size / ConcurrentG1Refine::thread_num();
-  if (worker_i == 0) {
-    // Potentially activate worker 0 more aggressively, to keep
-    // available buffers near green_zone value.  When yellow_size is
-    // large we don't want to allow a full step to accumulate before
-    // doing any processing, as that might lead to significantly more
-    // than green_zone buffers to be processed by update_rs.
-    step = MIN2(step, ParallelGCThreads / 2.0);
-  }
-  size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
-  size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
-  return Thresholds(green_zone + activate_offset,
-                    green_zone + deactivate_offset);
-}
-
-ConcurrentG1Refine::ConcurrentG1Refine(size_t green_zone,
-                                       size_t yellow_zone,
-                                       size_t red_zone,
-                                       size_t min_yellow_zone_size) :
-  _threads(NULL),
-  _sample_thread(NULL),
-  _n_worker_threads(thread_num()),
-  _green_zone(green_zone),
-  _yellow_zone(yellow_zone),
-  _red_zone(red_zone),
-  _min_yellow_zone_size(min_yellow_zone_size)
-{
-  assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
-}
-
-static size_t calc_min_yellow_zone_size() {
-  size_t step = G1ConcRefinementThresholdStep;
-  uint n_workers = ConcurrentG1Refine::thread_num();
-  if ((max_yellow_zone / step) < n_workers) {
-    return max_yellow_zone;
-  } else {
-    return step * n_workers;
-  }
-}
-
-static size_t calc_init_green_zone() {
-  size_t green = G1ConcRefinementGreenZone;
-  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
-    green = ParallelGCThreads;
-  }
-  return MIN2(green, max_green_zone);
-}
-
-static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
-  size_t config = G1ConcRefinementYellowZone;
-  size_t size = 0;
-  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
-    size = green * 2;
-  } else if (green < config) {
-    size = config - green;
-  }
-  size = MAX2(size, min_size);
-  size = MIN2(size, max_yellow_zone);
-  return MIN2(green + size, max_yellow_zone);
-}
-
-static size_t calc_init_red_zone(size_t green, size_t yellow) {
-  size_t size = yellow - green;
-  if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
-    size_t config = G1ConcRefinementRedZone;
-    if (yellow < config) {
-      size = MAX2(size, config - yellow);
-    }
-  }
-  return MIN2(yellow + size, max_red_zone);
-}
-
-ConcurrentG1Refine* ConcurrentG1Refine::create(jint* ecode) {
-  size_t min_yellow_zone_size = calc_min_yellow_zone_size();
-  size_t green_zone = calc_init_green_zone();
-  size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size);
-  size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
-
-  LOG_ZONES("Initial Refinement Zones: "
-            "green: " SIZE_FORMAT ", "
-            "yellow: " SIZE_FORMAT ", "
-            "red: " SIZE_FORMAT ", "
-            "min yellow size: " SIZE_FORMAT,
-            green_zone, yellow_zone, red_zone, min_yellow_zone_size);
-
-  ConcurrentG1Refine* cg1r = new ConcurrentG1Refine(green_zone,
-                                                    yellow_zone,
-                                                    red_zone,
-                                                    min_yellow_zone_size);
-
-  if (cg1r == NULL) {
-    *ecode = JNI_ENOMEM;
-    vm_shutdown_during_initialization("Could not create ConcurrentG1Refine");
-    return NULL;
-  }
-
-  cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC);
-  if (cg1r->_threads == NULL) {
-    *ecode = JNI_ENOMEM;
-    vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread");
-    return NULL;
-  }
-
-  uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
-
-  ConcurrentG1RefineThread *next = NULL;
-  for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) {
-    Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
-    ConcurrentG1RefineThread* t =
-      new ConcurrentG1RefineThread(cg1r,
-                                   next,
-                                   worker_id_offset,
-                                   i,
-                                   activation_level(thresholds),
-                                   deactivation_level(thresholds));
-    assert(t != NULL, "Conc refine should have been created");
-    if (t->osthread() == NULL) {
-      *ecode = JNI_ENOMEM;
-      vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread");
-      return NULL;
-    }
-
-    assert(t->cg1r() == cg1r, "Conc refine thread should refer to this");
-    cg1r->_threads[i] = t;
-    next = t;
-  }
-
-  cg1r->_sample_thread = new G1YoungRemSetSamplingThread();
-  if (cg1r->_sample_thread->osthread() == NULL) {
-    *ecode = JNI_ENOMEM;
-    vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread");
-    return NULL;
-  }
-
-  *ecode = JNI_OK;
-  return cg1r;
-}
-
-void ConcurrentG1Refine::stop() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    _threads[i]->stop();
-  }
-  _sample_thread->stop();
-}
-
-void ConcurrentG1Refine::update_thread_thresholds() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
-    _threads[i]->update_thresholds(activation_level(thresholds),
-                                   deactivation_level(thresholds));
-  }
-}
-
-ConcurrentG1Refine::~ConcurrentG1Refine() {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    delete _threads[i];
-  }
-  FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
-
-  delete _sample_thread;
-}
-
-void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
-  worker_threads_do(tc);
-  tc->do_thread(_sample_thread);
-}
-
-void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
-  for (uint i = 0; i < _n_worker_threads; i++) {
-    tc->do_thread(_threads[i]);
-  }
-}
-
-uint ConcurrentG1Refine::thread_num() {
-  return G1ConcRefinementThreads;
-}
-
-void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
-  for (uint i = 0; i < _n_worker_threads; ++i) {
-    _threads[i]->print_on(st);
-    st->cr();
-  }
-  _sample_thread->print_on(st);
-  st->cr();
-}
-
-static size_t calc_new_green_zone(size_t green,
-                                  double update_rs_time,
-                                  size_t update_rs_processed_buffers,
-                                  double goal_ms) {
-  // Adjust green zone based on whether we're meeting the time goal.
-  // Limit to max_green_zone.
-  const double inc_k = 1.1, dec_k = 0.9;
-  if (update_rs_time > goal_ms) {
-    if (green > 0) {
-      green = static_cast<size_t>(green * dec_k);
-    }
-  } else if (update_rs_time < goal_ms &&
-             update_rs_processed_buffers > green) {
-    green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
-    green = MIN2(green, max_green_zone);
-  }
-  return green;
-}
-
-static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) {
-  size_t size = green * 2;
-  size = MAX2(size, min_yellow_size);
-  return MIN2(green + size, max_yellow_zone);
-}
-
-static size_t calc_new_red_zone(size_t green, size_t yellow) {
-  return MIN2(yellow + (yellow - green), max_red_zone);
-}
-
-void ConcurrentG1Refine::update_zones(double update_rs_time,
-                                      size_t update_rs_processed_buffers,
-                                      double goal_ms) {
-  log_trace( CTRL_TAGS )("Updating Refinement Zones: "
-                         "update_rs time: %.3fms, "
-                         "update_rs buffers: " SIZE_FORMAT ", "
-                         "update_rs goal time: %.3fms",
-                         update_rs_time,
-                         update_rs_processed_buffers,
-                         goal_ms);
-
-  _green_zone = calc_new_green_zone(_green_zone,
-                                    update_rs_time,
-                                    update_rs_processed_buffers,
-                                    goal_ms);
-  _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
-  _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
-
-  assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
-  LOG_ZONES("Updated Refinement Zones: "
-            "green: " SIZE_FORMAT ", "
-            "yellow: " SIZE_FORMAT ", "
-            "red: " SIZE_FORMAT,
-            _green_zone, _yellow_zone, _red_zone);
-}
-
-void ConcurrentG1Refine::adjust(double update_rs_time,
-                                size_t update_rs_processed_buffers,
-                                double goal_ms) {
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-
-  if (G1UseAdaptiveConcRefinement) {
-    update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
-    update_thread_thresholds();
-
-    // Change the barrier params
-    if (_n_worker_threads == 0) {
-      // Disable dcqs notification when there are no threads to notify.
-      dcqs.set_process_completed_threshold(INT_MAX);
-    } else {
-      // Worker 0 is the primary; wakeup is via dcqs notification.
-      STATIC_ASSERT(max_yellow_zone <= INT_MAX);
-      size_t activate = _threads[0]->activation_threshold();
-      dcqs.set_process_completed_threshold((int)activate);
-    }
-    dcqs.set_max_completed_queue((int)red_zone());
-  }
-
-  size_t curr_queue_size = dcqs.completed_buffers_num();
-  if (curr_queue_size >= yellow_zone()) {
-    dcqs.set_completed_queue_padding(curr_queue_size);
-  } else {
-    dcqs.set_completed_queue_padding(0);
-  }
-  dcqs.notify_if_necessary();
-}
--- a/src/hotspot/share/gc/g1/concurrentG1Refine.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
-#define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
-
-#include "memory/allocation.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-// Forward decl
-class CardTableEntryClosure;
-class ConcurrentG1RefineThread;
-class G1YoungRemSetSamplingThread;
-class outputStream;
-class ThreadClosure;
-
-class ConcurrentG1Refine: public CHeapObj<mtGC> {
-  G1YoungRemSetSamplingThread* _sample_thread;
-
-  ConcurrentG1RefineThread** _threads;
-  uint _n_worker_threads;
- /*
-  * The value of the update buffer queue length falls into one of 3 zones:
-  * green, yellow, red. If the value is in [0, green) nothing is
-  * done, the buffers are left unprocessed to enable the caching effect of the
-  * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
-  * threads are gradually activated. In [yellow, red) all threads are
-  * running. If the length becomes red (max queue length) the mutators start
-  * processing the buffers.
-  *
-  * There are some interesting cases (when G1UseAdaptiveConcRefinement
-  * is turned off):
-  * 1) green = yellow = red = 0. In this case the mutator will process all
-  *    buffers. Except for those that are created by the deferred updates
-  *    machinery during a collection.
-  * 2) green = 0. Means no caching. Can be a good way to minimize the
-  *    amount of time spent updating rsets during a collection.
-  */
-  size_t _green_zone;
-  size_t _yellow_zone;
-  size_t _red_zone;
-  size_t _min_yellow_zone_size;
-
-  ConcurrentG1Refine(size_t green_zone,
-                     size_t yellow_zone,
-                     size_t red_zone,
-                     size_t min_yellow_zone_size);
-
-  // Update green/yellow/red zone values based on how well goals are being met.
-  void update_zones(double update_rs_time,
-                    size_t update_rs_processed_buffers,
-                    double goal_ms);
-
-  // Update thread thresholds to account for updated zone values.
-  void update_thread_thresholds();
-
- public:
-  ~ConcurrentG1Refine();
-
-  // Returns ConcurrentG1Refine instance if succeeded to create/initialize ConcurrentG1Refine and ConcurrentG1RefineThread.
-  // Otherwise, returns NULL with error code.
-  static ConcurrentG1Refine* create(jint* ecode);
-
-  void stop();
-
-  void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
-
-  // Iterate over all concurrent refinement threads
-  void threads_do(ThreadClosure *tc);
-
-  // Iterate over all worker refinement threads
-  void worker_threads_do(ThreadClosure * tc);
-
-  // The RS sampling thread has nothing to do with refinement, but is here for now.
-  G1YoungRemSetSamplingThread * sampling_thread() const { return _sample_thread; }
-
-  static uint thread_num();
-
-  void print_worker_threads_on(outputStream* st) const;
-
-  size_t green_zone() const      { return _green_zone;  }
-  size_t yellow_zone() const     { return _yellow_zone; }
-  size_t red_zone() const        { return _red_zone;    }
-};
-
-#endif // SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
--- a/src/hotspot/share/gc/g1/concurrentG1RefineThread.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
-#include "gc/g1/concurrentG1RefineThread.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1RemSet.hpp"
-#include "gc/shared/suspendibleThreadSet.hpp"
-#include "logging/log.hpp"
-#include "memory/resourceArea.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/mutexLocker.hpp"
-
-ConcurrentG1RefineThread::
-ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
-                         uint worker_id_offset, uint worker_id,
-                         size_t activate, size_t deactivate) :
-  ConcurrentGCThread(),
-  _worker_id_offset(worker_id_offset),
-  _worker_id(worker_id),
-  _active(false),
-  _next(next),
-  _monitor(NULL),
-  _cg1r(cg1r),
-  _vtime_accum(0.0),
-  _activation_threshold(activate),
-  _deactivation_threshold(deactivate)
-{
-
-  // Each thread has its own monitor. The i-th thread is responsible for signaling
-  // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
-  // thread. Monitors are also used to wake up the threads during termination.
-  // The 0th (primary) worker is notified by mutator threads and has a special monitor.
-  if (!is_primary()) {
-    _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
-                           Monitor::_safepoint_check_never);
-  } else {
-    _monitor = DirtyCardQ_CBL_mon;
-  }
-
-  // set name
-  set_name("G1 Refine#%d", worker_id);
-  create_and_start();
-}
-
-void ConcurrentG1RefineThread::update_thresholds(size_t activate,
-                                                 size_t deactivate) {
-  assert(deactivate < activate, "precondition");
-  _activation_threshold = activate;
-  _deactivation_threshold = deactivate;
-}
-
-void ConcurrentG1RefineThread::wait_for_completed_buffers() {
-  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
-  while (!should_terminate() && !is_active()) {
-    _monitor->wait(Mutex::_no_safepoint_check_flag);
-  }
-}
-
-bool ConcurrentG1RefineThread::is_active() {
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  return is_primary() ? dcqs.process_completed_buffers() : _active;
-}
-
-void ConcurrentG1RefineThread::activate() {
-  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
-  if (!is_primary()) {
-    set_active(true);
-  } else {
-    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-    dcqs.set_process_completed(true);
-  }
-  _monitor->notify();
-}
-
-void ConcurrentG1RefineThread::deactivate() {
-  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
-  if (!is_primary()) {
-    set_active(false);
-  } else {
-    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-    dcqs.set_process_completed(false);
-  }
-}
-
-void ConcurrentG1RefineThread::run_service() {
-  _vtime_start = os::elapsedVTime();
-
-  while (!should_terminate()) {
-    // Wait for work
-    wait_for_completed_buffers();
-    if (should_terminate()) {
-      break;
-    }
-
-    size_t buffers_processed = 0;
-    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-    log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                          _worker_id, _activation_threshold, dcqs.completed_buffers_num());
-
-    {
-      SuspendibleThreadSetJoiner sts_join;
-
-      while (!should_terminate()) {
-        if (sts_join.should_yield()) {
-          sts_join.yield();
-          continue;             // Re-check for termination after yield delay.
-        }
-
-        size_t curr_buffer_num = dcqs.completed_buffers_num();
-        // If the number of the buffers falls down into the yellow zone,
-        // that means that the transition period after the evacuation pause has ended.
-        if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
-          dcqs.set_completed_queue_padding(0);
-        }
-
-        // Check if we need to activate the next thread.
-        if ((_next != NULL) &&
-            !_next->is_active() &&
-            (curr_buffer_num > _next->_activation_threshold)) {
-          _next->activate();
-        }
-
-        // Process the next buffer, if there are enough left.
-        if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
-          break; // Deactivate, number of buffers fell below threshold.
-        }
-        ++buffers_processed;
-      }
-    }
-
-    deactivate();
-    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
-                          ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
-                          _worker_id, _deactivation_threshold,
-                          dcqs.completed_buffers_num(),
-                          buffers_processed);
-
-    if (os::supports_vtime()) {
-      _vtime_accum = (os::elapsedVTime() - _vtime_start);
-    } else {
-      _vtime_accum = 0.0;
-    }
-  }
-
-  log_debug(gc, refine)("Stopping %d", _worker_id);
-}
-
-void ConcurrentG1RefineThread::stop_service() {
-  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
-  _monitor->notify();
-}
--- a/src/hotspot/share/gc/g1/concurrentG1RefineThread.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP
-#define SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP
-
-#include "gc/g1/dirtyCardQueue.hpp"
-#include "gc/shared/concurrentGCThread.hpp"
-
-// Forward Decl.
-class CardTableEntryClosure;
-class ConcurrentG1Refine;
-
-// One or more G1 Concurrent Refinement Threads may be active if concurrent
-// refinement is in progress.
-class ConcurrentG1RefineThread: public ConcurrentGCThread {
-  friend class VMStructs;
-  friend class G1CollectedHeap;
-
-  double _vtime_start;  // Initial virtual time.
-  double _vtime_accum;  // Accumulated virtual time.
-  uint _worker_id;
-  uint _worker_id_offset;
-
-  // The refinement threads collection is linked list. A predecessor can activate a successor
-  // when the number of the rset update buffer crosses a certain threshold. A successor
-  // would self-deactivate when the number of the buffers falls below the threshold.
-  bool _active;
-  ConcurrentG1RefineThread* _next;
-  Monitor* _monitor;
-  ConcurrentG1Refine* _cg1r;
-
-  // This thread's activation/deactivation thresholds
-  size_t _activation_threshold;
-  size_t _deactivation_threshold;
-
-  void wait_for_completed_buffers();
-
-  void set_active(bool x) { _active = x; }
-  bool is_active();
-  void activate();
-  void deactivate();
-
-  bool is_primary() { return (_worker_id == 0); }
-
-  void run_service();
-  void stop_service();
-
-public:
-  // Constructor
-  ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
-                           uint worker_id_offset, uint worker_id,
-                           size_t activate, size_t deactivate);
-
-  void update_thresholds(size_t activate, size_t deactivate);
-  size_t activation_threshold() const { return _activation_threshold; }
-
-  // Total virtual time so far.
-  double vtime_accum() { return _vtime_accum; }
-
-  ConcurrentG1Refine* cg1r() { return _cg1r;     }
-};
-
-#endif // SHARE_VM_GC_G1_CONCURRENTG1REFINETHREAD_HPP
--- a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -111,16 +111,31 @@
   }
 };
 
-// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
+double ConcurrentMarkThread::mmu_sleep_time(G1Policy* g1_policy, bool remark) {
+  // There are 3 reasons to use SuspendibleThreadSetJoiner.
+  // 1. To avoid concurrency problem.
+  //    - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called
+  //      concurrently from ConcurrentMarkThread and VMThread.
+  // 2. If currently a gc is running, but it has not yet updated the MMU,
+  //    we will not forget to consider that pause in the MMU calculation.
+  // 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished.
+  //    And then sleep for predicted amount of time by delay_to_keep_mmu().
+  SuspendibleThreadSetJoiner sts_join;
+
+  const G1Analytics* analytics = g1_policy->analytics();
+  double now = os::elapsedTime();
+  double prediction_ms = remark ? analytics->predict_remark_time_ms()
+                                : analytics->predict_cleanup_time_ms();
+  G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
+  return mmu_tracker->when_ms(now, prediction_ms);
+}
+
 void ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
-  const G1Analytics* analytics = g1_policy->analytics();
   if (g1_policy->adaptive_young_list_length()) {
-    double now = os::elapsedTime();
-    double prediction_ms = remark ? analytics->predict_remark_time_ms()
-                                  : analytics->predict_cleanup_time_ms();
-    G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
-    jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms);
-    os::sleep(this, sleep_time_ms, false);
+    jlong sleep_time_ms = mmu_sleep_time(g1_policy, remark);
+    if (!cm()->has_aborted() && sleep_time_ms > 0) {
+      os::sleep(this, sleep_time_ms, false);
+    }
   }
 }
 
@@ -349,9 +364,11 @@
       if (!cm()->has_aborted()) {
         delay_to_keep_mmu(g1_policy, false /* cleanup */);
 
-        CMCleanUp cl_cl(_cm);
-        VM_CGC_Operation op(&cl_cl, "Pause Cleanup");
-        VMThread::execute(&op);
+        if (!cm()->has_aborted()) {
+          CMCleanUp cl_cl(_cm);
+          VM_CGC_Operation op(&cl_cl, "Pause Cleanup");
+          VMThread::execute(&op);
+        }
       } else {
         // We don't want to update the marking status if a GC pause
         // is already underway.
--- a/src/hotspot/share/gc/g1/concurrentMarkThread.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/concurrentMarkThread.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -55,7 +55,9 @@
   ConcurrentGCPhaseManager::Stack _phase_manager_stack;
 
   void sleepBeforeNextCycle();
+  // Delay marking to meet MMU.
   void delay_to_keep_mmu(G1Policy* g1_policy, bool remark);
+  double mmu_sleep_time(G1Policy* g1_policy, bool remark);
 
   void run_service();
   void stop_service();
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -29,14 +29,14 @@
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
 #include "gc/g1/bufferingOopClosure.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
-#include "gc/g1/concurrentG1RefineThread.hpp"
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1Allocator.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectionSet.hpp"
 #include "gc/g1/g1CollectorPolicy.hpp"
 #include "gc/g1/g1CollectorState.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
+#include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
@@ -54,6 +54,7 @@
 #include "gc/g1/g1SerialFullCollector.hpp"
 #include "gc/g1/g1StringDedup.hpp"
 #include "gc/g1/g1YCTypes.hpp"
+#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
@@ -1541,6 +1542,7 @@
 
 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* collector_policy) :
   CollectedHeap(),
+  _young_gen_sampling_thread(NULL),
   _collector_policy(collector_policy),
   _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
   _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
@@ -1554,7 +1556,7 @@
   _bot(NULL),
   _hot_card_cache(NULL),
   _g1_rem_set(NULL),
-  _cg1r(NULL),
+  _cr(NULL),
   _g1mm(NULL),
   _preserved_marks_set(true /* in_c_heap */),
   _secondary_free_list("Secondary Free List", new SecondaryFreeRegionListMtSafeChecker()),
@@ -1633,10 +1635,19 @@
 
 jint G1CollectedHeap::initialize_concurrent_refinement() {
   jint ecode = JNI_OK;
-  _cg1r = ConcurrentG1Refine::create(&ecode);
+  _cr = G1ConcurrentRefine::create(&ecode);
   return ecode;
 }
 
+jint G1CollectedHeap::initialize_young_gen_sampling_thread() {
+  _young_gen_sampling_thread = new G1YoungRemSetSamplingThread();
+  if (_young_gen_sampling_thread->osthread() == NULL) {
+    vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread");
+    return JNI_ENOMEM;
+  }
+  return JNI_OK;
+}
+
 jint G1CollectedHeap::initialize() {
   CollectedHeap::pre_initialize();
   os::enable_vtime();
@@ -1789,10 +1800,15 @@
     return ecode;
   }
 
+  ecode = initialize_young_gen_sampling_thread();
+  if (ecode != JNI_OK) {
+    return ecode;
+  }
+
   JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
                                                 DirtyCardQ_FL_lock,
-                                                (int)concurrent_g1_refine()->yellow_zone(),
-                                                (int)concurrent_g1_refine()->red_zone(),
+                                                (int)concurrent_refine()->yellow_zone(),
+                                                (int)concurrent_refine()->red_zone(),
                                                 Shared_DirtyCardQ_lock,
                                                 NULL,  // fl_owner
                                                 true); // init_free_ids
@@ -1836,7 +1852,8 @@
   // Stop all concurrent threads. We do this to make sure these threads
   // do not continue to execute and access resources (e.g. logging)
   // that are destroyed during shutdown.
-  _cg1r->stop();
+  _cr->stop();
+  _young_gen_sampling_thread->stop();
   _cmThread->stop();
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::stop();
@@ -2390,9 +2407,8 @@
   st->print(" %-20s", "garbage-first heap");
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
             capacity()/K, used_unlocked()/K);
-  st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
+  st->print(" [" PTR_FORMAT ", " PTR_FORMAT ")",
             p2i(_hrm.reserved().start()),
-            p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords),
             p2i(_hrm.reserved().end()));
   st->cr();
   st->print("  region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
@@ -2437,7 +2453,8 @@
   _cmThread->print_on(st);
   st->cr();
   _cm->print_worker_threads_on(st);
-  _cg1r->print_worker_threads_on(st); // also prints the sample thread
+  _cr->print_threads_on(st);
+  _young_gen_sampling_thread->print_on(st);
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::print_worker_threads_on(st);
   }
@@ -2447,7 +2464,8 @@
   workers()->threads_do(tc);
   tc->do_thread(_cmThread);
   _cm->threads_do(tc);
-  _cg1r->threads_do(tc); // also iterates over the sample thread
+  _cr->threads_do(tc);
+  tc->do_thread(_young_gen_sampling_thread);
   if (G1StringDedup::is_enabled()) {
     G1StringDedup::threads_do(tc);
   }
@@ -2579,7 +2597,7 @@
   // FIXME: what is this about?
   // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
   // is set.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
 #endif
   // always_do_update_barrier = true;
@@ -2992,7 +3010,7 @@
 
       _verifier->check_bitmaps("GC Start");
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
       DerivedPointerTable::clear();
 #endif
 
@@ -3622,7 +3640,7 @@
 
 class G1KlassCleaningTask : public StackObj {
   BoolObjectClosure*                      _is_alive;
-  volatile jint                           _clean_klass_tree_claimed;
+  volatile int                            _clean_klass_tree_claimed;
   ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
 
  public:
@@ -3638,7 +3656,7 @@
       return false;
     }
 
-    return Atomic::cmpxchg(1, (jint*)&_clean_klass_tree_claimed, 0) == 0;
+    return Atomic::cmpxchg(1, &_clean_klass_tree_claimed, 0) == 0;
   }
 
   InstanceKlass* claim_next_klass() {
@@ -3675,7 +3693,7 @@
 
 class G1ResolvedMethodCleaningTask : public StackObj {
   BoolObjectClosure* _is_alive;
-  volatile jint      _resolved_method_task_claimed;
+  volatile int       _resolved_method_task_claimed;
 public:
   G1ResolvedMethodCleaningTask(BoolObjectClosure* is_alive) :
       _is_alive(is_alive), _resolved_method_task_claimed(0) {}
@@ -3684,7 +3702,7 @@
     if (_resolved_method_task_claimed) {
       return false;
     }
-    return Atomic::cmpxchg(1, (jint*)&_resolved_method_task_claimed, 0) == 0;
+    return Atomic::cmpxchg(1, &_resolved_method_task_claimed, 0) == 0;
   }
 
   // These aren't big, one thread can do it all.
@@ -4421,7 +4439,7 @@
   purge_code_root_memory();
 
   redirty_logged_cards();
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   double start = os::elapsedTime();
   DerivedPointerTable::update_pointers();
   g1_policy()->phase_times()->record_derived_pointer_table_update_time((os::elapsedTime() - start) * 1000.0);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -73,10 +73,11 @@
 class G1Policy;
 class G1HotCardCache;
 class G1RemSet;
+class G1YoungRemSetSamplingThread;
 class HeapRegionRemSetIterator;
 class G1ConcurrentMark;
 class ConcurrentMarkThread;
-class ConcurrentG1Refine;
+class G1ConcurrentRefine;
 class GenerationCounters;
 class STWGCTimer;
 class G1NewTracer;
@@ -142,6 +143,8 @@
   friend class G1CheckCSetFastTableClosure;
 
 private:
+  G1YoungRemSetSamplingThread* _young_gen_sampling_thread;
+
   WorkGang* _workers;
   G1CollectorPolicy* _collector_policy;
 
@@ -553,6 +556,8 @@
   // during GC into global variables.
   void merge_per_thread_state_info(G1ParScanThreadStateSet* per_thread_states);
 public:
+  G1YoungRemSetSamplingThread* sampling_thread() const { return _young_gen_sampling_thread; }
+
   WorkGang* workers() const { return _workers; }
 
   G1Allocator* allocator() {
@@ -806,7 +811,7 @@
   ConcurrentMarkThread* _cmThread;
 
   // The concurrent refiner.
-  ConcurrentG1Refine* _cg1r;
+  G1ConcurrentRefine* _cr;
 
   // The parallel task queues
   RefToScanQueueSet *_task_queues;
@@ -959,6 +964,7 @@
 
 private:
   jint initialize_concurrent_refinement();
+  jint initialize_young_gen_sampling_thread();
 public:
   // Initialize the G1CollectedHeap to have the initial and
   // maximum sizes and remembered and barrier sets
@@ -1389,7 +1395,7 @@
 
   // Refinement
 
-  ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+  G1ConcurrentRefine* concurrent_refine() const { return _cr; }
 
   // Optimized nmethod scanning support routines
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
+#include "gc/g1/g1ConcurrentRefineThread.hpp"
+#include "logging/log.hpp"
+#include "runtime/java.hpp"
+#include "runtime/thread.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/pair.hpp"
+#include <math.h>
+
+// Arbitrary but large limits, to simplify some of the zone calculations.
+// The general idea is to allow expressions like
+//   MIN2(x OP y, max_XXX_zone)
+// without needing to check for overflow in "x OP y", because the
+// ranges for x and y have been restricted.
+STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
+const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
+const size_t max_green_zone = max_yellow_zone / 2;
+const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
+STATIC_ASSERT(max_yellow_zone <= max_red_zone);
+
+// Range check assertions for green zone values.
+#define assert_zone_constraints_g(green)                        \
+  do {                                                          \
+    size_t azc_g_green = (green);                               \
+    assert(azc_g_green <= max_green_zone,                       \
+           "green exceeds max: " SIZE_FORMAT, azc_g_green);     \
+  } while (0)
+
+// Range check assertions for green and yellow zone values.
+#define assert_zone_constraints_gy(green, yellow)                       \
+  do {                                                                  \
+    size_t azc_gy_green = (green);                                      \
+    size_t azc_gy_yellow = (yellow);                                    \
+    assert_zone_constraints_g(azc_gy_green);                            \
+    assert(azc_gy_yellow <= max_yellow_zone,                            \
+           "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow);          \
+    assert(azc_gy_green <= azc_gy_yellow,                               \
+           "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")",  \
+           azc_gy_green, azc_gy_yellow);                                \
+  } while (0)
+
+// Range check assertions for green, yellow, and red zone values.
+#define assert_zone_constraints_gyr(green, yellow, red)                 \
+  do {                                                                  \
+    size_t azc_gyr_green = (green);                                     \
+    size_t azc_gyr_yellow = (yellow);                                   \
+    size_t azc_gyr_red = (red);                                         \
+    assert_zone_constraints_gy(azc_gyr_green, azc_gyr_yellow);          \
+    assert(azc_gyr_red <= max_red_zone,                                 \
+           "red exceeds max: " SIZE_FORMAT, azc_gyr_red);               \
+    assert(azc_gyr_yellow <= azc_gyr_red,                               \
+           "yellow (" SIZE_FORMAT ") exceeds red (" SIZE_FORMAT ")",    \
+           azc_gyr_yellow, azc_gyr_red);                                \
+  } while (0)
+
+// Logging tag sequence for refinement control updates.
+#define CTRL_TAGS gc, ergo, refine
+
+// For logging zone values, ensuring consistency of level and tags.
+#define LOG_ZONES(...) log_debug( CTRL_TAGS )(__VA_ARGS__)
+
+// Package for pair of refinement thread activation and deactivation
+// thresholds.  The activation and deactivation levels are resp. the first
+// and second values of the pair.
+typedef Pair<size_t, size_t> Thresholds;
+inline size_t activation_level(const Thresholds& t) { return t.first; }
+inline size_t deactivation_level(const Thresholds& t) { return t.second; }
+
+static Thresholds calc_thresholds(size_t green_zone,
+                                  size_t yellow_zone,
+                                  uint worker_i) {
+  double yellow_size = yellow_zone - green_zone;
+  double step = yellow_size / G1ConcurrentRefine::thread_num();
+  if (worker_i == 0) {
+    // Potentially activate worker 0 more aggressively, to keep
+    // available buffers near green_zone value.  When yellow_size is
+    // large we don't want to allow a full step to accumulate before
+    // doing any processing, as that might lead to significantly more
+    // than green_zone buffers to be processed by update_rs.
+    step = MIN2(step, ParallelGCThreads / 2.0);
+  }
+  size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
+  size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
+  return Thresholds(green_zone + activate_offset,
+                    green_zone + deactivate_offset);
+}
+
+G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone,
+                                       size_t yellow_zone,
+                                       size_t red_zone,
+                                       size_t min_yellow_zone_size) :
+  _threads(NULL),
+  _n_worker_threads(thread_num()),
+  _green_zone(green_zone),
+  _yellow_zone(yellow_zone),
+  _red_zone(red_zone),
+  _min_yellow_zone_size(min_yellow_zone_size)
+{
+  assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
+}
+
+static size_t calc_min_yellow_zone_size() {
+  size_t step = G1ConcRefinementThresholdStep;
+  uint n_workers = G1ConcurrentRefine::thread_num();
+  if ((max_yellow_zone / step) < n_workers) {
+    return max_yellow_zone;
+  } else {
+    return step * n_workers;
+  }
+}
+
+static size_t calc_init_green_zone() {
+  size_t green = G1ConcRefinementGreenZone;
+  if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
+    green = ParallelGCThreads;
+  }
+  return MIN2(green, max_green_zone);
+}
+
+static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
+  size_t config = G1ConcRefinementYellowZone;
+  size_t size = 0;
+  if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
+    size = green * 2;
+  } else if (green < config) {
+    size = config - green;
+  }
+  size = MAX2(size, min_size);
+  size = MIN2(size, max_yellow_zone);
+  return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_init_red_zone(size_t green, size_t yellow) {
+  size_t size = yellow - green;
+  if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
+    size_t config = G1ConcRefinementRedZone;
+    if (yellow < config) {
+      size = MAX2(size, config - yellow);
+    }
+  }
+  return MIN2(yellow + size, max_red_zone);
+}
+
+G1ConcurrentRefine* G1ConcurrentRefine::create(jint* ecode) {
+  size_t min_yellow_zone_size = calc_min_yellow_zone_size();
+  size_t green_zone = calc_init_green_zone();
+  size_t yellow_zone = calc_init_yellow_zone(green_zone, min_yellow_zone_size);
+  size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
+
+  LOG_ZONES("Initial Refinement Zones: "
+            "green: " SIZE_FORMAT ", "
+            "yellow: " SIZE_FORMAT ", "
+            "red: " SIZE_FORMAT ", "
+            "min yellow size: " SIZE_FORMAT,
+            green_zone, yellow_zone, red_zone, min_yellow_zone_size);
+
+  G1ConcurrentRefine* cr = new G1ConcurrentRefine(green_zone,
+                                                  yellow_zone,
+                                                  red_zone,
+                                                  min_yellow_zone_size);
+
+  if (cr == NULL) {
+    *ecode = JNI_ENOMEM;
+    vm_shutdown_during_initialization("Could not create G1ConcurrentRefine");
+    return NULL;
+  }
+
+  cr->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, cr->_n_worker_threads, mtGC);
+  if (cr->_threads == NULL) {
+    *ecode = JNI_ENOMEM;
+    vm_shutdown_during_initialization("Could not allocate an array for G1ConcurrentRefineThread");
+    return NULL;
+  }
+
+  uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
+
+  G1ConcurrentRefineThread *next = NULL;
+  for (uint i = cr->_n_worker_threads - 1; i != UINT_MAX; i--) {
+    Thresholds thresholds = calc_thresholds(green_zone, yellow_zone, i);
+    G1ConcurrentRefineThread* t =
+      new G1ConcurrentRefineThread(cr,
+                                   next,
+                                   worker_id_offset,
+                                   i,
+                                   activation_level(thresholds),
+                                   deactivation_level(thresholds));
+    assert(t != NULL, "Conc refine should have been created");
+    if (t->osthread() == NULL) {
+      *ecode = JNI_ENOMEM;
+      vm_shutdown_during_initialization("Could not create G1ConcurrentRefineThread");
+      return NULL;
+    }
+
+    assert(t->cr() == cr, "Conc refine thread should refer to this");
+    cr->_threads[i] = t;
+    next = t;
+  }
+
+  *ecode = JNI_OK;
+  return cr;
+}
+
+void G1ConcurrentRefine::stop() {
+  for (uint i = 0; i < _n_worker_threads; i++) {
+    _threads[i]->stop();
+  }
+}
+
+void G1ConcurrentRefine::update_thread_thresholds() {
+  for (uint i = 0; i < _n_worker_threads; i++) {
+    Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, i);
+    _threads[i]->update_thresholds(activation_level(thresholds),
+                                   deactivation_level(thresholds));
+  }
+}
+
+G1ConcurrentRefine::~G1ConcurrentRefine() {
+  for (uint i = 0; i < _n_worker_threads; i++) {
+    delete _threads[i];
+  }
+  FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
+}
+
+void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
+  for (uint i = 0; i < _n_worker_threads; i++) {
+    tc->do_thread(_threads[i]);
+  }
+}
+
+uint G1ConcurrentRefine::thread_num() {
+  return G1ConcRefinementThreads;
+}
+
+void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
+  for (uint i = 0; i < _n_worker_threads; ++i) {
+    _threads[i]->print_on(st);
+    st->cr();
+  }
+}
+
+static size_t calc_new_green_zone(size_t green,
+                                  double update_rs_time,
+                                  size_t update_rs_processed_buffers,
+                                  double goal_ms) {
+  // Adjust green zone based on whether we're meeting the time goal.
+  // Limit to max_green_zone.
+  const double inc_k = 1.1, dec_k = 0.9;
+  if (update_rs_time > goal_ms) {
+    if (green > 0) {
+      green = static_cast<size_t>(green * dec_k);
+    }
+  } else if (update_rs_time < goal_ms &&
+             update_rs_processed_buffers > green) {
+    green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
+    green = MIN2(green, max_green_zone);
+  }
+  return green;
+}
+
+static size_t calc_new_yellow_zone(size_t green, size_t min_yellow_size) {
+  size_t size = green * 2;
+  size = MAX2(size, min_yellow_size);
+  return MIN2(green + size, max_yellow_zone);
+}
+
+static size_t calc_new_red_zone(size_t green, size_t yellow) {
+  return MIN2(yellow + (yellow - green), max_red_zone);
+}
+
+void G1ConcurrentRefine::update_zones(double update_rs_time,
+                                      size_t update_rs_processed_buffers,
+                                      double goal_ms) {
+  log_trace( CTRL_TAGS )("Updating Refinement Zones: "
+                         "update_rs time: %.3fms, "
+                         "update_rs buffers: " SIZE_FORMAT ", "
+                         "update_rs goal time: %.3fms",
+                         update_rs_time,
+                         update_rs_processed_buffers,
+                         goal_ms);
+
+  _green_zone = calc_new_green_zone(_green_zone,
+                                    update_rs_time,
+                                    update_rs_processed_buffers,
+                                    goal_ms);
+  _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
+  _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
+
+  assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
+  LOG_ZONES("Updated Refinement Zones: "
+            "green: " SIZE_FORMAT ", "
+            "yellow: " SIZE_FORMAT ", "
+            "red: " SIZE_FORMAT,
+            _green_zone, _yellow_zone, _red_zone);
+}
+
+void G1ConcurrentRefine::adjust(double update_rs_time,
+                                size_t update_rs_processed_buffers,
+                                double goal_ms) {
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+
+  if (G1UseAdaptiveConcRefinement) {
+    update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
+    update_thread_thresholds();
+
+    // Change the barrier params
+    if (_n_worker_threads == 0) {
+      // Disable dcqs notification when there are no threads to notify.
+      dcqs.set_process_completed_threshold(INT_MAX);
+    } else {
+      // Worker 0 is the primary; wakeup is via dcqs notification.
+      STATIC_ASSERT(max_yellow_zone <= INT_MAX);
+      size_t activate = _threads[0]->activation_threshold();
+      dcqs.set_process_completed_threshold((int)activate);
+    }
+    dcqs.set_max_completed_queue((int)red_zone());
+  }
+
+  size_t curr_queue_size = dcqs.completed_buffers_num();
+  if (curr_queue_size >= yellow_zone()) {
+    dcqs.set_completed_queue_padding(curr_queue_size);
+  } else {
+    dcqs.set_completed_queue_padding(0);
+  }
+  dcqs.notify_if_necessary();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP
+#define SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Forward decl
+class CardTableEntryClosure;
+class G1ConcurrentRefineThread;
+class outputStream;
+class ThreadClosure;
+
+class G1ConcurrentRefine : public CHeapObj<mtGC> {
+  G1ConcurrentRefineThread** _threads;
+  uint _n_worker_threads;
+ /*
+  * The value of the update buffer queue length falls into one of 3 zones:
+  * green, yellow, red. If the value is in [0, green) nothing is
+  * done, the buffers are left unprocessed to enable the caching effect of the
+  * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement
+  * threads are gradually activated. In [yellow, red) all threads are
+  * running. If the length becomes red (max queue length) the mutators start
+  * processing the buffers.
+  *
+  * There are some interesting cases (when G1UseAdaptiveConcRefinement
+  * is turned off):
+  * 1) green = yellow = red = 0. In this case the mutator will process all
+  *    buffers. Except for those that are created by the deferred updates
+  *    machinery during a collection.
+  * 2) green = 0. Means no caching. Can be a good way to minimize the
+  *    amount of time spent updating rsets during a collection.
+  */
+  size_t _green_zone;
+  size_t _yellow_zone;
+  size_t _red_zone;
+  size_t _min_yellow_zone_size;
+
+  G1ConcurrentRefine(size_t green_zone,
+                     size_t yellow_zone,
+                     size_t red_zone,
+                     size_t min_yellow_zone_size);
+
+  // Update green/yellow/red zone values based on how well goals are being met.
+  void update_zones(double update_rs_time,
+                    size_t update_rs_processed_buffers,
+                    double goal_ms);
+
+  // Update thread thresholds to account for updated zone values.
+  void update_thread_thresholds();
+
+ public:
+  ~G1ConcurrentRefine();
+
+  // Returns a G1ConcurrentRefine instance if succeeded to create/initialize G1ConcurrentRefine and G1ConcurrentRefineThreads.
+  // Otherwise, returns NULL with error code.
+  static G1ConcurrentRefine* create(jint* ecode);
+
+  void stop();
+
+  void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
+
+  // Iterate over all concurrent refinement threads applying the given closure.
+  void threads_do(ThreadClosure *tc);
+
+  static uint thread_num();
+
+  void print_threads_on(outputStream* st) const;
+
+  size_t green_zone() const      { return _green_zone;  }
+  size_t yellow_zone() const     { return _yellow_zone; }
+  size_t red_zone() const        { return _red_zone;    }
+};
+
+#endif // SHARE_VM_GC_G1_G1CONCURRENTREFINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
+#include "gc/g1/g1ConcurrentRefineThread.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
+#include "gc/shared/suspendibleThreadSet.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/mutexLocker.hpp"
+
+G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr,
+                                                   G1ConcurrentRefineThread *next,
+                                                   uint worker_id_offset,
+                                                   uint worker_id,
+                                                   size_t activate,
+                                                   size_t deactivate) :
+  ConcurrentGCThread(),
+  _worker_id_offset(worker_id_offset),
+  _worker_id(worker_id),
+  _active(false),
+  _next(next),
+  _monitor(NULL),
+  _cr(cr),
+  _vtime_accum(0.0),
+  _activation_threshold(activate),
+  _deactivation_threshold(deactivate)
+{
+
+  // Each thread has its own monitor. The i-th thread is responsible for signaling
+  // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
+  // thread. Monitors are also used to wake up the threads during termination.
+  // The 0th (primary) worker is notified by mutator threads and has a special monitor.
+  if (!is_primary()) {
+    _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
+                           Monitor::_safepoint_check_never);
+  } else {
+    _monitor = DirtyCardQ_CBL_mon;
+  }
+
+  // set name
+  set_name("G1 Refine#%d", worker_id);
+  create_and_start();
+}
+
+void G1ConcurrentRefineThread::update_thresholds(size_t activate,
+                                                 size_t deactivate) {
+  assert(deactivate < activate, "precondition");
+  _activation_threshold = activate;
+  _deactivation_threshold = deactivate;
+}
+
+void G1ConcurrentRefineThread::wait_for_completed_buffers() {
+  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+  while (!should_terminate() && !is_active()) {
+    _monitor->wait(Mutex::_no_safepoint_check_flag);
+  }
+}
+
+bool G1ConcurrentRefineThread::is_active() {
+  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+  return is_primary() ? dcqs.process_completed_buffers() : _active;
+}
+
+void G1ConcurrentRefineThread::activate() {
+  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+  if (!is_primary()) {
+    set_active(true);
+  } else {
+    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+    dcqs.set_process_completed(true);
+  }
+  _monitor->notify();
+}
+
+void G1ConcurrentRefineThread::deactivate() {
+  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+  if (!is_primary()) {
+    set_active(false);
+  } else {
+    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+    dcqs.set_process_completed(false);
+  }
+}
+
+void G1ConcurrentRefineThread::run_service() {
+  _vtime_start = os::elapsedVTime();
+
+  while (!should_terminate()) {
+    // Wait for work
+    wait_for_completed_buffers();
+    if (should_terminate()) {
+      break;
+    }
+
+    size_t buffers_processed = 0;
+    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+    log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
+                          _worker_id, _activation_threshold, dcqs.completed_buffers_num());
+
+    {
+      SuspendibleThreadSetJoiner sts_join;
+
+      while (!should_terminate()) {
+        if (sts_join.should_yield()) {
+          sts_join.yield();
+          continue;             // Re-check for termination after yield delay.
+        }
+
+        size_t curr_buffer_num = dcqs.completed_buffers_num();
+        // If the number of the buffers falls down into the yellow zone,
+        // that means that the transition period after the evacuation pause has ended.
+        if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cr()->yellow_zone()) {
+          dcqs.set_completed_queue_padding(0);
+        }
+
+        // Check if we need to activate the next thread.
+        if ((_next != NULL) &&
+            !_next->is_active() &&
+            (curr_buffer_num > _next->_activation_threshold)) {
+          _next->activate();
+        }
+
+        // Process the next buffer, if there are enough left.
+        if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
+          break; // Deactivate, number of buffers fell below threshold.
+        }
+        ++buffers_processed;
+      }
+    }
+
+    deactivate();
+    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
+                          ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
+                          _worker_id, _deactivation_threshold,
+                          dcqs.completed_buffers_num(),
+                          buffers_processed);
+
+    if (os::supports_vtime()) {
+      _vtime_accum = (os::elapsedVTime() - _vtime_start);
+    } else {
+      _vtime_accum = 0.0;
+    }
+  }
+
+  log_debug(gc, refine)("Stopping %d", _worker_id);
+}
+
+void G1ConcurrentRefineThread::stop_service() {
+  MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+  _monitor->notify();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP
+#define SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP
+
+#include "gc/g1/dirtyCardQueue.hpp"
+#include "gc/shared/concurrentGCThread.hpp"
+
+// Forward Decl.
+class CardTableEntryClosure;
+class G1ConcurrentRefine;
+
+// One or more G1 Concurrent Refinement Threads may be active if concurrent
+// refinement is in progress.
+class G1ConcurrentRefineThread: public ConcurrentGCThread {
+  friend class VMStructs;
+  friend class G1CollectedHeap;
+
+  double _vtime_start;  // Initial virtual time.
+  double _vtime_accum;  // Accumulated virtual time.
+  uint _worker_id;
+  uint _worker_id_offset;
+
+  // The refinement threads collection is linked list. A predecessor can activate a successor
+  // when the number of the rset update buffer crosses a certain threshold. A successor
+  // would self-deactivate when the number of the buffers falls below the threshold.
+  bool _active;
+  G1ConcurrentRefineThread* _next;
+  Monitor* _monitor;
+  G1ConcurrentRefine* _cr;
+
+  // This thread's activation/deactivation thresholds
+  size_t _activation_threshold;
+  size_t _deactivation_threshold;
+
+  void wait_for_completed_buffers();
+
+  void set_active(bool x) { _active = x; }
+  bool is_active();
+  void activate();
+  void deactivate();
+
+  bool is_primary() { return (_worker_id == 0); }
+
+  void run_service();
+  void stop_service();
+
+public:
+  // Constructor
+  G1ConcurrentRefineThread(G1ConcurrentRefine* cr, G1ConcurrentRefineThread* next,
+                           uint worker_id_offset, uint worker_id,
+                           size_t activate, size_t deactivate);
+
+  void update_thresholds(size_t activate, size_t deactivate);
+  size_t activation_threshold() const { return _activation_threshold; }
+
+  // Total virtual time so far.
+  double vtime_accum() { return _vtime_accum; }
+
+  G1ConcurrentRefine* cr() { return _cr;     }
+};
+
+#endif // SHARE_VM_GC_G1_G1CONCURRENTREFINETHREAD_HPP
--- a/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1DefaultPolicy.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/concurrentMarkThread.inline.hpp"
 #include "gc/g1/g1Analytics.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1CollectionSet.hpp"
 #include "gc/g1/g1ConcurrentMark.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1DefaultPolicy.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
 #include "gc/g1/g1IHOPControl.hpp"
@@ -745,7 +745,7 @@
   } else {
     update_rs_time_goal_ms -= scan_hcc_time_ms;
   }
-  _g1->concurrent_g1_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
+  _g1->concurrent_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
                                       phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS),
                                       update_rs_time_goal_ms);
 
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -414,7 +414,7 @@
 
   debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
   trace_phase(_gc_par_phases[RedirtyCards]);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   debug_time("DerivedPointerTable Update", _cur_derived_pointer_table_update_time_ms);
 #endif
 
--- a/src/hotspot/share/gc/g1/g1MMUTracker.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MMUTracker.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -112,19 +112,7 @@
   }
 }
 
-// basically the _internal call does not remove expired entries
-// this is for trying things out in the future and a couple
-// of other places (debugging)
-
 double G1MMUTrackerQueue::when_sec(double current_time, double pause_time) {
-  MutexLockerEx x(MMUTracker_lock, Mutex::_no_safepoint_check_flag);
-  remove_expired_entries(current_time);
-
-  return when_internal(current_time, pause_time);
-}
-
-double G1MMUTrackerQueue::when_internal(double current_time,
-                                        double pause_time) {
   // if the pause is over the maximum, just assume that it's the maximum
   double adjusted_pause_time =
     (pause_time > max_gc_time()) ? max_gc_time() : pause_time;
--- a/src/hotspot/share/gc/g1/g1MMUTracker.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MMUTracker.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -134,8 +134,6 @@
   void remove_expired_entries(double current_time);
   double calculate_gc_time(double current_time);
 
-  double when_internal(double current_time, double pause_time);
-
 public:
   G1MMUTrackerQueue(double time_slice, double max_gc_time);
 
--- a/src/hotspot/share/gc/g1/g1MarkSweep.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1MarkSweep.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -62,7 +62,7 @@
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
   HandleMark hm;  // Discard invalid handles created during gc
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::clear();
 #endif
 #ifdef ASSERT
@@ -96,7 +96,7 @@
   // Prepare compaction.
   mark_sweep_phase2();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Don't add any more derived pointers during phase3
   DerivedPointerTable::set_active(false);
 #endif
@@ -111,7 +111,7 @@
   BiasedLocking::restore_marks();
   GenMarkSweep::deallocate_stacks();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Now update the derived pointers.
   DerivedPointerTable::update_pointers();
 #endif
@@ -204,7 +204,7 @@
 
   if (VerifyDuringGC) {
     HandleMark hm;  // handle scope
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTableDeactivate dpt_deact;
 #endif
     g1h->prepare_for_verify();
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,10 +23,10 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/dirtyCardQueue.hpp"
 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1FromCardCache.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
@@ -298,7 +298,7 @@
 }
 
 uint G1RemSet::num_par_rem_sets() {
-  return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
+  return MAX2(DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::thread_num(), ParallelGCThreads);
 }
 
 void G1RemSet::initialize(size_t capacity, uint max_regions) {
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
-#include "gc/g1/concurrentG1RefineThread.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
+#include "gc/g1/g1ConcurrentRefineThread.hpp"
 #include "gc/g1/g1RemSet.inline.hpp"
 #include "gc/g1/g1RemSetSummary.hpp"
 #include "gc/g1/g1YoungRemSetSamplingThread.hpp"
@@ -45,7 +45,7 @@
   }
 
   virtual void do_thread(Thread* t) {
-    ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
+    G1ConcurrentRefineThread* crt = (G1ConcurrentRefineThread*) t;
     _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
     _counter++;
   }
@@ -59,12 +59,13 @@
 
   _num_coarsenings = HeapRegionRemSet::n_coarsenings();
 
-  ConcurrentG1Refine * cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  G1ConcurrentRefine* cg1r = g1h->concurrent_refine();
   if (_rs_threads_vtimes != NULL) {
     GetRSThreadVTimeClosure p(this);
-    cg1r->worker_threads_do(&p);
+    cg1r->threads_do(&p);
   }
-  set_sampling_thread_vtime(cg1r->sampling_thread()->vtime_accum());
+  set_sampling_thread_vtime(g1h->sampling_thread()->vtime_accum());
 }
 
 void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) {
@@ -85,7 +86,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(ConcurrentG1Refine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::thread_num()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
 
@@ -98,7 +99,7 @@
   _num_processed_buf_mutator(0),
   _num_processed_buf_rs_threads(0),
   _num_coarsenings(0),
-  _num_vtimes(ConcurrentG1Refine::thread_num()),
+  _num_vtimes(G1ConcurrentRefine::thread_num()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
   _sampling_thread_vtime(0.0f) {
   update();
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -214,52 +214,3 @@
     }
   }
 }
-
-void G1SATBCardTableModRefBS::write_ref_nmethod_post(oop* dst, nmethod* nm) {
-  oop obj = oopDesc::load_heap_oop(dst);
-  if (obj != NULL) {
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
-    HeapRegion* hr = g1h->heap_region_containing(obj);
-    hr->add_strong_code_root(nm);
-  }
-}
-
-class G1EnsureLastRefToRegion : public OopClosure {
-  G1CollectedHeap* _g1h;
-  HeapRegion* _hr;
-  oop* _dst;
-
-  bool _value;
-public:
-  G1EnsureLastRefToRegion(G1CollectedHeap* g1h, HeapRegion* hr, oop* dst) :
-    _g1h(g1h), _hr(hr), _dst(dst), _value(true) {}
-
-  void do_oop(oop* p) {
-    if (_value && p != _dst) {
-      oop obj = oopDesc::load_heap_oop(p);
-      if (obj != NULL) {
-        HeapRegion* hr = _g1h->heap_region_containing(obj);
-        if (hr == _hr) {
-          // Another reference to the same region.
-          _value = false;
-        }
-      }
-    }
-  }
-  void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-  bool value() const        { return _value;  }
-};
-
-void G1SATBCardTableModRefBS::write_ref_nmethod_pre(oop* dst, nmethod* nm) {
-  oop obj = oopDesc::load_heap_oop(dst);
-  if (obj != NULL) {
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
-    HeapRegion* hr = g1h->heap_region_containing(obj);
-    G1EnsureLastRefToRegion ensure_last_ref(g1h, hr, dst);
-    nm->oops_do(&ensure_last_ref);
-    if (ensure_last_ref.value()) {
-      // Last reference to this region, remove the nmethod from the rset.
-      hr->remove_strong_code_root(nm);
-    }
-  }
-}
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -95,9 +95,6 @@
     jbyte val = _byte_map[card_index];
     return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
   }
-  virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm);
-  virtual void write_ref_nmethod_post(oop* dst, nmethod* nm);
-
 };
 
 template<>
--- a/src/hotspot/share/gc/g1/g1_globals.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/g1_globals.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -74,10 +74,10 @@
           "in milliseconds.")                                               \
           range(1.0, DBL_MAX)                                               \
                                                                             \
-  product(intx, G1RefProcDrainInterval, 10,                                 \
+  product(int, G1RefProcDrainInterval, 10,                                  \
           "The number of discovered reference objects to process before "   \
           "draining concurrent marking work queues.")                       \
-          range(1, max_intx)                                                \
+          range(1, INT_MAX)                                                 \
                                                                             \
   experimental(double, G1LastPLABAverageOccupancy, 50.0,                    \
                "The expected average occupancy of the last PLAB in "        \
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,8 +23,8 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/g1/concurrentG1Refine.hpp"
 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/g1CardLiveData.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/satbMarkQueue.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -192,7 +192,7 @@
 
     allocate_stacks();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -203,7 +203,7 @@
 
     mark_sweep_phase2();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     // Don't add any more derived pointers during phase3
     assert(DerivedPointerTable::is_active(), "Sanity");
     DerivedPointerTable::set_active(false);
@@ -252,7 +252,7 @@
     CodeCache::gc_epilogue();
     JvmtiExport::gc_epilogue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
 #endif
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1032,7 +1032,7 @@
   CodeCache::gc_epilogue();
   JvmtiExport::gc_epilogue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   DerivedPointerTable::update_pointers();
 #endif
 
@@ -1783,7 +1783,7 @@
 
     CodeCache::gc_prologue();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -1799,7 +1799,7 @@
       && GCCause::is_user_requested_gc(gc_cause);
     summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     assert(DerivedPointerTable::is_active(), "Sanity");
     DerivedPointerTable::set_active(false);
 #endif
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -331,7 +331,7 @@
 
     save_to_space_top_before_gc();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::clear();
 #endif
 
@@ -601,7 +601,7 @@
       assert(young_gen->to_space()->is_empty(), "to space should be empty now");
     }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
 #endif
 
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -92,7 +92,7 @@
   mark_sweep_phase2();
 
   // Don't add any more derived pointers during phase3
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_active(), "Sanity");
   DerivedPointerTable::set_active(false);
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/serial/serialHeap.hpp"
+
+SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {}
+
+void SerialHeap::check_gen_kinds() {
+  assert(young_gen()->kind() == Generation::DefNew,
+         "Wrong youngest generation type");
+  assert(old_gen()->kind() == Generation::MarkSweepCompact,
+         "Wrong generation kind");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/serial/serialHeap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SERIAL_SERIALHEAP_HPP
+#define SHARE_VM_GC_SERIAL_SERIALHEAP_HPP
+
+#include "gc/shared/genCollectedHeap.hpp"
+
+class GenCollectorPolicy;
+
+class SerialHeap : public GenCollectedHeap {
+protected:
+  virtual void check_gen_kinds();
+
+public:
+  SerialHeap(GenCollectorPolicy* policy);
+
+  virtual Name kind() const {
+    return CollectedHeap::SerialHeap;
+  }
+
+  virtual const char* name() const {
+    return "Serial";
+  }
+
+  // override
+  virtual bool is_in_closed_subset(const void* p) const {
+    return is_in(p);
+  }
+
+  virtual bool card_mark_must_follow_store() const {
+    return false;
+  }
+
+};
+
+#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
--- a/src/hotspot/share/gc/shared/ageTable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/ageTable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "gc/shared/ageTable.inline.hpp"
 #include "gc/shared/ageTableTracer.hpp"
 #include "gc/shared/collectedHeap.hpp"
@@ -30,7 +31,6 @@
 #include "memory/resourceArea.hpp"
 #include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "utilities/copy.hpp"
 
 /* Copyright (c) 1992, 2016, Oracle and/or its affiliates, and Stanford University.
--- a/src/hotspot/share/gc/shared/allocTracer.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/allocTracer.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,9 +26,11 @@
 #include "gc/shared/allocTracer.hpp"
 #include "runtime/handles.hpp"
 #include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-void AllocTracer::send_allocation_outside_tlab_event(Klass* klass, size_t alloc_size) {
+void AllocTracer::send_allocation_outside_tlab(Klass* klass, HeapWord* obj, size_t alloc_size, Thread* thread) {
+  TRACE_ALLOCATION(obj, alloc_size, thread);
   EventObjectAllocationOutsideTLAB event;
   if (event.should_commit()) {
     event.set_objectClass(klass);
@@ -37,7 +39,8 @@
   }
 }
 
-void AllocTracer::send_allocation_in_new_tlab_event(Klass* klass, size_t tlab_size, size_t alloc_size) {
+void AllocTracer::send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread) {
+  TRACE_ALLOCATION(obj, tlab_size, thread);
   EventObjectAllocationInNewTLAB event;
   if (event.should_commit()) {
     event.set_objectClass(klass);
--- a/src/hotspot/share/gc/shared/allocTracer.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/allocTracer.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -30,8 +30,8 @@
 
 class AllocTracer : AllStatic {
   public:
-    static void send_allocation_outside_tlab_event(Klass* klass, size_t alloc_size);
-    static void send_allocation_in_new_tlab_event(Klass* klass, size_t tlab_size, size_t alloc_size);
+    static void send_allocation_outside_tlab(Klass* klass, HeapWord* obj, size_t alloc_size, Thread* thread);
+    static void send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread);
     static void send_allocation_requiring_gc_event(size_t size, uint gcId);
 };
 
--- a/src/hotspot/share/gc/shared/barrierSet.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -120,9 +120,6 @@
   static void static_write_ref_array_pre(HeapWord* start, size_t count);
   static void static_write_ref_array_post(HeapWord* start, size_t count);
 
-  virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm) {}
-  virtual void write_ref_nmethod_post(oop* dst, nmethod* nm) {}
-
 protected:
   virtual void write_ref_array_work(MemRegion mr) = 0;
 
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -241,7 +241,7 @@
 void CollectedHeap::pre_initialize() {
   // Used for ReduceInitialCardMarks (when COMPILER2 is used);
   // otherwise remains unused.
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   _defer_initial_card_mark = is_server_compilation_mode_vm() &&  ReduceInitialCardMarks && can_elide_tlab_store_barriers()
                              && (DeferInitialCardMark || card_mark_must_follow_store());
 #else
@@ -313,7 +313,7 @@
     return NULL;
   }
 
-  AllocTracer::send_allocation_in_new_tlab_event(klass, new_tlab_size * HeapWordSize, size * HeapWordSize);
+  AllocTracer::send_allocation_in_new_tlab(klass, obj, new_tlab_size * HeapWordSize, size * HeapWordSize, thread);
 
   if (ZeroTLAB) {
     // ..and clear it.
@@ -545,7 +545,7 @@
          " to threads list is doomed to failure!");
   for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
      if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
      // The deferred store barriers must all have been flushed to the
      // card-table (or other remembered set structure) before GC starts
      // processing the card-table (or other remembered set).
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -81,9 +81,10 @@
 //
 // CollectedHeap
 //   GenCollectedHeap
+//     SerialHeap
+//     CMSHeap
 //   G1CollectedHeap
 //   ParallelScavengeHeap
-//   CMSHeap
 //
 class CollectedHeap : public CHeapObj<mtInternal> {
   friend class VMStructs;
@@ -193,7 +194,7 @@
 
  public:
   enum Name {
-    GenCollectedHeap,
+    SerialHeap,
     ParallelScavengeHeap,
     G1CollectedHeap,
     CMSHeap
--- a/src/hotspot/share/gc/shared/collectedHeap.inline.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/collectedHeap.inline.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -156,7 +156,7 @@
            "Unexpected exception, will result in uninitialized storage");
     THREAD->incr_allocated_bytes(size * HeapWordSize);
 
-    AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);
+    AllocTracer::send_allocation_outside_tlab(klass, result, size * HeapWordSize, THREAD);
 
     return result;
   }
--- a/src/hotspot/share/gc/shared/gcId.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcId.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,8 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "gc/shared/gcId.hpp"
-#include "prims/jvm.h"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
 
--- a/src/hotspot/share/gc/shared/gcTimer.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcTimer.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,7 +26,6 @@
 #define SHARE_VM_GC_SHARED_GCTIMER_HPP
 
 #include "memory/allocation.hpp"
-#include "prims/jni_md.h"
 #include "utilities/macros.hpp"
 #include "utilities/ticks.hpp"
 
--- a/src/hotspot/share/gc/shared/gcTraceTime.inline.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/gcTraceTime.inline.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -32,7 +32,6 @@
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/universe.hpp"
-#include "prims/jni_md.h"
 #include "utilities/ticks.hpp"
 
 #define LOG_STOP_HEAP_FORMAT SIZE_FORMAT "M->" SIZE_FORMAT "M("  SIZE_FORMAT "M)"
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -153,13 +153,6 @@
   _gen_policy->initialize_gc_policy_counters();
 }
 
-void GenCollectedHeap::check_gen_kinds() {
-  assert(young_gen()->kind() == Generation::DefNew,
-         "Wrong youngest generation type");
-  assert(old_gen()->kind() == Generation::MarkSweepCompact,
-         "Wrong generation kind");
-}
-
 void GenCollectedHeap::ref_processing_init() {
   _young_gen->ref_processor_init();
   _old_gen->ref_processor_init();
@@ -984,7 +977,7 @@
 GenCollectedHeap* GenCollectedHeap::heap() {
   CollectedHeap* heap = Universe::heap();
   assert(heap != NULL, "Uninitialized access to GenCollectedHeap::heap()");
-  assert(heap->kind() == CollectedHeap::GenCollectedHeap ||
+  assert(heap->kind() == CollectedHeap::SerialHeap ||
          heap->kind() == CollectedHeap::CMSHeap, "Not a GenCollectedHeap");
   return (GenCollectedHeap*) heap;
 }
@@ -1067,11 +1060,11 @@
 };
 
 void GenCollectedHeap::gc_epilogue(bool full) {
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
   size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
   guarantee(is_client_compilation_mode_vm() || actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
-#endif /* COMPILER2 || INCLUDE_JVMCI */
+#endif // COMPILER2_OR_JVMCI
 
   resize_all_tlabs();
 
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -83,6 +83,12 @@
                           bool run_verification, bool clear_soft_refs,
                           bool restore_marks_for_biased_locking);
 
+  // Reserve aligned space for the heap as needed by the contained generations.
+  char* allocate(size_t alignment, ReservedSpace* heap_rs);
+
+  // Initialize ("weak") refs processing support
+  void ref_processing_init();
+
 protected:
 
   // The set of potentially parallel tasks in root scanning.
@@ -134,31 +140,18 @@
   // we absolutely __must__ clear soft refs?
   bool must_clear_all_soft_refs();
 
+  GenCollectedHeap(GenCollectorPolicy *policy);
+
+  virtual void check_gen_kinds() = 0;
+
 public:
-  GenCollectedHeap(GenCollectorPolicy *policy);
 
   // Returns JNI_OK on success
   virtual jint initialize();
 
-  // Reserve aligned space for the heap as needed by the contained generations.
-  char* allocate(size_t alignment, ReservedSpace* heap_rs);
-
   // Does operations required after initialization has been done.
   void post_initialize();
 
-  virtual void check_gen_kinds();
-
-  // Initialize ("weak") refs processing support
-  virtual void ref_processing_init();
-
-  virtual Name kind() const {
-    return CollectedHeap::GenCollectedHeap;
-  }
-
-  virtual const char* name() const {
-    return "Serial";
-  }
-
   Generation* young_gen() const { return _young_gen; }
   Generation* old_gen()   const { return _old_gen; }
 
@@ -215,11 +208,6 @@
   // assertion checking or verification only.
   bool is_in(const void* p) const;
 
-  // override
-  virtual bool is_in_closed_subset(const void* p) const {
-    return is_in(p);
-  }
-
   // Returns true if the reference is to an object in the reserved space
   // for the young generation.
   // Assumes the the young gen address range is less than that of the old gen.
@@ -286,10 +274,6 @@
     return true;
   }
 
-  virtual bool card_mark_must_follow_store() const {
-    return false;
-  }
-
   // We don't need barriers for stores to objects in the
   // young gen and, a fortiori, for initializing stores to
   // objects therein. This applies to DefNew+Tenured and ParNew+CMS
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/gc/shared/weakProcessor.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,10 +26,13 @@
 #include "gc/shared/weakProcessor.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/jniHandles.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
 
 void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
   JNIHandles::weak_oops_do(is_alive, keep_alive);
   JvmtiExport::weak_oops_do(is_alive, keep_alive);
+  TRACE_WEAK_OOPS_DO(is_alive, keep_alive);
 }
 
 void WeakProcessor::oops_do(OopClosure* closure) {
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -87,14 +87,15 @@
 // State accessors
 
 void InterpreterRuntime::set_bcp_and_mdp(address bcp, JavaThread *thread) {
-  last_frame(thread).interpreter_frame_set_bcp(bcp);
+  LastFrameAccessor last_frame(thread);
+  last_frame.set_bcp(bcp);
   if (ProfileInterpreter) {
     // ProfileTraps uses MDOs independently of ProfileInterpreter.
     // That is why we must check both ProfileInterpreter and mdo != NULL.
-    MethodData* mdo = last_frame(thread).interpreter_frame_method()->method_data();
+    MethodData* mdo = last_frame.method()->method_data();
     if (mdo != NULL) {
       NEEDS_CLEANUP;
-      last_frame(thread).interpreter_frame_set_mdp(mdo->bci_to_dp(last_frame(thread).interpreter_frame_bci()));
+      last_frame.set_mdp(mdo->bci_to_dp(last_frame.bci()));
     }
   }
 }
@@ -105,8 +106,9 @@
 
 IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
   // access constant pool
-  ConstantPool* pool = method(thread)->constants();
-  int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) : get_index_u1(thread, Bytecodes::_ldc);
+  LastFrameAccessor last_frame(thread);
+  ConstantPool* pool = last_frame.method()->constants();
+  int index = wide ? last_frame.get_index_u2(Bytecodes::_ldc_w) : last_frame.get_index_u1(Bytecodes::_ldc);
   constantTag tag = pool->tag_at(index);
 
   assert (tag.is_unresolved_klass() || tag.is_klass(), "wrong ldc call");
@@ -119,13 +121,14 @@
   assert(bytecode == Bytecodes::_fast_aldc ||
          bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
   ResourceMark rm(thread);
-  methodHandle m (thread, method(thread));
-  Bytecode_loadconstant ldc(m, bci(thread));
+  LastFrameAccessor last_frame(thread);
+  methodHandle m (thread, last_frame.method());
+  Bytecode_loadconstant ldc(m, last_frame.bci());
   oop result = ldc.resolve_constant(CHECK);
 #ifdef ASSERT
   {
     // The bytecode wrappers aren't GC-safe so construct a new one
-    Bytecode_loadconstant ldc2(m, bci(thread));
+    Bytecode_loadconstant ldc2(m, last_frame.bci());
     oop coop = m->constants()->resolved_references()->obj_at(ldc2.cache_index());
     assert(result == coop, "expected result for assembly code");
   }
@@ -182,10 +185,11 @@
 
 IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address))
   // We may want to pass in more arguments - could make this slightly faster
-  ConstantPool* constants = method(thread)->constants();
-  int          i = get_index_u2(thread, Bytecodes::_multianewarray);
-  Klass* klass = constants->klass_at(i, CHECK);
-  int   nof_dims = number_of_dimensions(thread);
+  LastFrameAccessor last_frame(thread);
+  ConstantPool* constants = last_frame.method()->constants();
+  int          i = last_frame.get_index_u2(Bytecodes::_multianewarray);
+  Klass* klass   = constants->klass_at(i, CHECK);
+  int   nof_dims = last_frame.number_of_dimensions();
   assert(klass->is_klass(), "not a class");
   assert(nof_dims >= 1, "multianewarray rank must be nonzero");
 
@@ -217,8 +221,9 @@
 // Quicken instance-of and check-cast bytecodes
 IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread))
   // Force resolving; quicken the bytecode
-  int which = get_index_u2(thread, Bytecodes::_checkcast);
-  ConstantPool* cpool = method(thread)->constants();
+  LastFrameAccessor last_frame(thread);
+  int which = last_frame.get_index_u2(Bytecodes::_checkcast);
+  ConstantPool* cpool = last_frame.method()->constants();
   // We'd expect to assert that we're only here to quicken bytecodes, but in a multithreaded
   // program we might have seen an unquick'd bytecode in the interpreter but have another
   // thread quicken the bytecode before we get here.
@@ -257,8 +262,9 @@
 // If necessary, create an MDO to hold the information, and record it.
 void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
   assert(ProfileTraps, "call me only if profiling");
-  methodHandle trap_method(thread, method(thread));
-  int trap_bci = trap_method->bci_from(bcp(thread));
+  LastFrameAccessor last_frame(thread);
+  methodHandle trap_method(thread, last_frame.method());
+  int trap_bci = trap_method->bci_from(last_frame.bcp());
   note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
 }
 
@@ -391,12 +397,13 @@
 // invoke w/o arguments (i.e., as if one were inside the call).
 IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception))
 
+  LastFrameAccessor last_frame(thread);
   Handle             h_exception(thread, exception);
-  methodHandle       h_method   (thread, method(thread));
+  methodHandle       h_method   (thread, last_frame.method());
   constantPoolHandle h_constants(thread, h_method->constants());
   bool               should_repeat;
   int                handler_bci;
-  int                current_bci = bci(thread);
+  int                current_bci = last_frame.bci();
 
   if (thread->frames_to_pop_failed_realloc() > 0) {
     // Allocation of scalar replaced object used in this frame
@@ -493,7 +500,7 @@
   // notify JVMTI of an exception throw; JVMTI will detect if this is a first
   // time throw or a stack unwinding throw and accordingly notify the debugger
   if (JvmtiExport::can_post_on_exceptions()) {
-    JvmtiExport::post_exception_throw(thread, h_method(), bcp(thread), h_exception());
+    JvmtiExport::post_exception_throw(thread, h_method(), last_frame.bcp(), h_exception());
   }
 
 #ifdef CC_INTERP
@@ -556,20 +563,21 @@
   Thread* THREAD = thread;
   // resolve field
   fieldDescriptor info;
-  constantPoolHandle pool(thread, method(thread)->constants());
-  methodHandle m(thread, method(thread));
+  LastFrameAccessor last_frame(thread);
+  constantPoolHandle pool(thread, last_frame.method()->constants());
+  methodHandle m(thread, last_frame.method());
   bool is_put    = (bytecode == Bytecodes::_putfield  || bytecode == Bytecodes::_nofast_putfield ||
                     bytecode == Bytecodes::_putstatic);
   bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
 
   {
     JvmtiHideSingleStepping jhss(thread);
-    LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
+    LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
                                        m, bytecode, CHECK);
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   if (cp_cache_entry->is_resolved(bytecode)) return;
 
   // compute auxiliary field attributes
@@ -718,16 +726,17 @@
 
 void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) {
   Thread* THREAD = thread;
+  LastFrameAccessor last_frame(thread);
   // extract receiver from the outgoing argument list if necessary
   Handle receiver(thread, NULL);
   if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface ||
       bytecode == Bytecodes::_invokespecial) {
     ResourceMark rm(thread);
-    methodHandle m (thread, method(thread));
-    Bytecode_invoke call(m, bci(thread));
+    methodHandle m (thread, last_frame.method());
+    Bytecode_invoke call(m, last_frame.bci());
     Symbol* signature = call.signature();
-    receiver = Handle(thread,
-                  thread->last_frame().interpreter_callee_receiver(signature));
+    receiver = Handle(thread, last_frame.callee_receiver(signature));
+
     assert(Universe::heap()->is_in_reserved_or_null(receiver()),
            "sanity check");
     assert(receiver.is_null() ||
@@ -737,12 +746,12 @@
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
+  constantPoolHandle pool(thread, last_frame.method()->constants());
 
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, receiver, pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                  CHECK);
     if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
       int retry_count = 0;
@@ -754,14 +763,14 @@
                   "Could not resolve to latest version of redefined method");
         // method is redefined in the middle of resolve so re-try.
         LinkResolver::resolve_invoke(info, receiver, pool,
-                                     get_index_u2_cpcache(thread, bytecode), bytecode,
+                                     last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                      CHECK);
       }
     }
   } // end JvmtiHideSingleStepping
 
   // check if link resolution caused cpCache to be updated
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   if (cp_cache_entry->is_resolved(bytecode)) return;
 
 #ifdef ASSERT
@@ -825,33 +834,35 @@
 void InterpreterRuntime::resolve_invokehandle(JavaThread* thread) {
   Thread* THREAD = thread;
   const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
+  LastFrameAccessor last_frame(thread);
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
+  constantPoolHandle pool(thread, last_frame.method()->constants());
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, Handle(), pool,
-                                 get_index_u2_cpcache(thread, bytecode), bytecode,
+                                 last_frame.get_index_u2_cpcache(bytecode), bytecode,
                                  CHECK);
   } // end JvmtiHideSingleStepping
 
-  ConstantPoolCacheEntry* cp_cache_entry = cache_entry(thread);
+  ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
   cp_cache_entry->set_method_handle(pool, info);
 }
 
 // First time execution:  Resolve symbols, create a permanent CallSite object.
 void InterpreterRuntime::resolve_invokedynamic(JavaThread* thread) {
   Thread* THREAD = thread;
+  LastFrameAccessor last_frame(thread);
   const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
 
   //TO DO: consider passing BCI to Java.
-  //  int caller_bci = method(thread)->bci_from(bcp(thread));
+  //  int caller_bci = last_frame.method()->bci_from(last_frame.bcp());
 
   // resolve method
   CallInfo info;
-  constantPoolHandle pool(thread, method(thread)->constants());
-  int index = get_index_u4(thread, bytecode);
+  constantPoolHandle pool(thread, last_frame.method()->constants());
+  int index = last_frame.get_index_u4(bytecode);
   {
     JvmtiHideSingleStepping jhss(thread);
     LinkResolver::resolve_invoke(info, Handle(), pool,
@@ -905,11 +916,19 @@
     // nm could have been unloaded so look it up again.  It's unsafe
     // to examine nm directly since it might have been freed and used
     // for something else.
-    frame fr = thread->last_frame();
-    Method* method =  fr.interpreter_frame_method();
-    int bci = method->bci_from(fr.interpreter_frame_bcp());
+    LastFrameAccessor last_frame(thread);
+    Method* method =  last_frame.method();
+    int bci = method->bci_from(last_frame.bcp());
     nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
   }
+  if (nm != NULL && thread->is_interp_only_mode()) {
+    // Normally we never get an nm if is_interp_only_mode() is true, because
+    // policy()->event has a check for this and won't compile the method when
+    // true. However, it's possible for is_interp_only_mode() to become true
+    // during the compilation. We don't want to return the nm in that case
+    // because we want to continue to execute interpreted.
+    nm = NULL;
+  }
 #ifndef PRODUCT
   if (TraceOnStackReplacement) {
     if (nm != NULL) {
@@ -927,11 +946,11 @@
   // flag, in case this method triggers classloading which will call into Java.
   UnlockFlagSaver fs(thread);
 
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  methodHandle method(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  methodHandle method(thread, last_frame.method());
   const int branch_bci = branch_bcp != NULL ? method->bci_from(branch_bcp) : InvocationEntryBci;
-  const int bci = branch_bcp != NULL ? method->bci_from(fr.interpreter_frame_bcp()) : InvocationEntryBci;
+  const int bci = branch_bcp != NULL ? method->bci_from(last_frame.bcp()) : InvocationEntryBci;
 
   assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending");
   nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
@@ -947,9 +966,9 @@
     if (UseBiasedLocking) {
       ResourceMark rm;
       GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-      for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end();
-           kptr < fr.interpreter_frame_monitor_begin();
-           kptr = fr.next_monitor_in_interpreter_frame(kptr) ) {
+      for( BasicObjectLock *kptr = last_frame.monitor_end();
+           kptr < last_frame.monitor_begin();
+           kptr = last_frame.next_monitor(kptr) ) {
         if( kptr->obj() != NULL ) {
           objects_to_revoke->append(Handle(THREAD, kptr->obj()));
         }
@@ -974,9 +993,9 @@
   UnlockFlagSaver fs(thread);
 
   assert(ProfileInterpreter, "must be profiling interpreter");
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  methodHandle method(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  methodHandle method(thread, last_frame.method());
   Method::build_interpreter_method_data(method, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
@@ -1021,9 +1040,9 @@
   assert(ProfileInterpreter, "must be profiling interpreter");
   ResourceMark rm(thread);
   HandleMark hm(thread);
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "must come from interpreter");
-  MethodData* h_mdo = fr.interpreter_frame_method()->method_data();
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must come from interpreter");
+  MethodData* h_mdo = last_frame.method()->method_data();
 
   // Grab a lock to ensure atomic access to setting the return bci and
   // the displacement.  This can block and GC, invalidating all naked oops.
@@ -1031,11 +1050,11 @@
 
   // ProfileData is essentially a wrapper around a derived oop, so we
   // need to take the lock before making any ProfileData structures.
-  ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(fr.interpreter_frame_mdp()));
+  ProfileData* data = h_mdo->data_at(h_mdo->dp_to_di(last_frame.mdp()));
   guarantee(data != NULL, "profile data must be valid");
   RetData* rdata = data->as_RetData();
   address new_mdp = rdata->fixup_ret(return_bci, h_mdo);
-  fr.interpreter_frame_set_mdp(new_mdp);
+  last_frame.set_mdp(new_mdp);
 IRT_END
 
 IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m))
@@ -1060,7 +1079,8 @@
     // We are called during regular safepoints and when the VM is
     // single stepping. If any thread is marked for single stepping,
     // then we may have JVMTI work to do.
-    JvmtiExport::at_single_stepping_point(thread, method(thread), bcp(thread));
+    LastFrameAccessor last_frame(thread);
+    JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
   }
 IRT_END
 
@@ -1083,7 +1103,8 @@
   }
   InstanceKlass* cp_entry_f1 = InstanceKlass::cast(cp_entry->f1_as_klass());
   jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static);
-  JvmtiExport::post_field_access(thread, method(thread), bcp(thread), cp_entry_f1, h_obj, fid);
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid);
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
@@ -1138,17 +1159,20 @@
     h_obj = Handle(thread, obj);
   }
 
-  JvmtiExport::post_raw_field_modification(thread, method(thread), bcp(thread), ik, h_obj,
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj,
                                            fid, sig_type, &fvalue);
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread))
-  JvmtiExport::post_method_entry(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame());
 IRT_END
 
 
 IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread))
-  JvmtiExport::post_method_exit(thread, InterpreterRuntime::method(thread), InterpreterRuntime::last_frame(thread));
+  LastFrameAccessor last_frame(thread);
+  JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame());
 IRT_END
 
 IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc))
@@ -1372,10 +1396,10 @@
   ResetNoHandleMark rnm; // In a LEAF entry.
   HandleMark hm;
   ResourceMark rm;
-  frame fr = thread->last_frame();
-  assert(fr.is_interpreted_frame(), "");
-  jint bci = fr.interpreter_frame_bci();
-  methodHandle mh(thread, fr.interpreter_frame_method());
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "");
+  jint bci = last_frame.bci();
+  methodHandle mh(thread, last_frame.method());
   Bytecode_invoke invoke(mh, bci);
   ArgumentSizeComputer asc(invoke.signature());
   int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver
@@ -1421,10 +1445,10 @@
 // The generated code still uses call_VM because that will set up the frame pointer for
 // bcp and method.
 IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
-  const frame f = thread->last_frame();
-  assert(f.is_interpreted_frame(), "must be an interpreted frame");
-  methodHandle mh(thread, f.interpreter_frame_method());
-  BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
+  LastFrameAccessor last_frame(thread);
+  assert(last_frame.is_interpreted_frame(), "must be an interpreted frame");
+  methodHandle mh(thread, last_frame.method());
+  BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2);
   return preserve_this_value;
 IRT_END
 #endif // !PRODUCT
--- a/src/hotspot/share/interpreter/interpreterRuntime.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -42,29 +42,54 @@
   friend class PrintingClosure; // for method and bcp
 
  private:
-  // Helper functions to access current interpreter state
-  static frame     last_frame(JavaThread *thread)    { return thread->last_frame(); }
-  static Method*   method(JavaThread *thread)        { return last_frame(thread).interpreter_frame_method(); }
-  static address   bcp(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bcp(); }
-  static int       bci(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bci(); }
-  static void      set_bcp_and_mdp(address bcp, JavaThread*thread);
-  static Bytecodes::Code code(JavaThread *thread)    {
+  // Helper class to access current interpreter state
+  class LastFrameAccessor : public StackObj {
+    frame _last_frame;
+  public:
+    LastFrameAccessor(JavaThread* thread) {
+      assert(thread == Thread::current(), "sanity");
+      _last_frame = thread->last_frame();
+    }
+    bool is_interpreted_frame() const              { return _last_frame.is_interpreted_frame(); }
+    Method*   method() const                       { return _last_frame.interpreter_frame_method(); }
+    address   bcp() const                          { return _last_frame.interpreter_frame_bcp(); }
+    int       bci() const                          { return _last_frame.interpreter_frame_bci(); }
+    address   mdp() const                          { return _last_frame.interpreter_frame_mdp(); }
+
+    void      set_bcp(address bcp)                 { _last_frame.interpreter_frame_set_bcp(bcp); }
+    void      set_mdp(address dp)                  { _last_frame.interpreter_frame_set_mdp(dp); }
+
     // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
-    return Bytecodes::code_at(method(thread), bcp(thread));
-  }
-  static Bytecode  bytecode(JavaThread *thread)      { return Bytecode(method(thread), bcp(thread)); }
-  static int       get_index_u1(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u1(bc); }
-  static int       get_index_u2(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u2(bc); }
-  static int       get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u2_cpcache(bc); }
-  static int       get_index_u4(JavaThread *thread, Bytecodes::Code bc)
-                                                        { return bytecode(thread).get_index_u4(bc); }
-  static int       number_of_dimensions(JavaThread *thread)  { return bcp(thread)[3]; }
+    Bytecodes::Code code() const                   { return Bytecodes::code_at(method(), bcp()); }
+
+    Bytecode  bytecode() const                     { return Bytecode(method(), bcp()); }
+    int get_index_u1(Bytecodes::Code bc) const     { return bytecode().get_index_u1(bc); }
+    int get_index_u2(Bytecodes::Code bc) const     { return bytecode().get_index_u2(bc); }
+    int get_index_u2_cpcache(Bytecodes::Code bc) const
+                                                   { return bytecode().get_index_u2_cpcache(bc); }
+    int get_index_u4(Bytecodes::Code bc) const     { return bytecode().get_index_u4(bc); }
+    int number_of_dimensions() const               { return bcp()[3]; }
+    ConstantPoolCacheEntry* cache_entry_at(int i) const
+                                                   { return method()->constants()->cache()->entry_at(i); }
+    ConstantPoolCacheEntry* cache_entry() const    { return cache_entry_at(Bytes::get_native_u2(bcp() + 1)); }
 
-  static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i)  { return method(thread)->constants()->cache()->entry_at(i); }
-  static ConstantPoolCacheEntry* cache_entry(JavaThread *thread)            { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
+    oop callee_receiver(Symbol* signature) {
+      return _last_frame.interpreter_callee_receiver(signature);
+    }
+    BasicObjectLock* monitor_begin() const {
+      return _last_frame.interpreter_frame_monitor_begin();
+    }
+    BasicObjectLock* monitor_end() const {
+      return _last_frame.interpreter_frame_monitor_end();
+    }
+    BasicObjectLock* next_monitor(BasicObjectLock* current) const {
+      return _last_frame.next_monitor_in_interpreter_frame(current);
+    }
+
+    frame& get_frame()                             { return _last_frame; }
+  };
+
+  static void      set_bcp_and_mdp(address bcp, JavaThread*thread);
   static void      note_trap_inner(JavaThread* thread, int reason,
                                    const methodHandle& trap_method, int trap_bci, TRAPS);
   static void      note_trap(JavaThread *thread, int reason, TRAPS);
@@ -139,7 +164,7 @@
   static void _breakpoint(JavaThread* thread, Method* method, address bcp);
   static Bytecodes::Code get_original_bytecode_at(JavaThread* thread, Method* method, address bcp);
   static void            set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code);
-  static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(bcp(thread)) == Bytecodes::_breakpoint; }
+  static bool is_breakpoint(JavaThread *thread) { return Bytecodes::code_or_bp_at(LastFrameAccessor(thread).bcp()) == Bytecodes::_breakpoint; }
 
   // Safepoints
   static void    at_safepoint(JavaThread* thread);
--- a/src/hotspot/share/interpreter/linkResolver.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/interpreter/linkResolver.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/defaultMethods.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/resolutionErrors.hpp"
@@ -42,7 +43,6 @@
 #include "oops/method.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/methodHandles.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/compilationPolicy.hpp"
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -45,7 +45,7 @@
 // use).
 ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL);
 ConstantIntValue*      CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1);
-ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0);
+ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue((jint)0);
 ConstantIntValue*      CodeInstaller::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1);
 ConstantIntValue*      CodeInstaller::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2);
 LocationValue*         CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location());
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,10 +22,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/javaCalls.hpp"
 #include "runtime/handles.hpp"
 #include "jvmci/jvmciJavaClasses.hpp"
--- a/src/hotspot/share/jvmci/jvmciCompiler.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -55,10 +55,13 @@
 public:
   JVMCICompiler();
 
-  static JVMCICompiler* instance(TRAPS) {
+  static JVMCICompiler* instance(bool require_non_null, TRAPS) {
     if (!EnableJVMCI) {
       THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
     }
+    if (_instance == NULL && require_non_null) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "The JVMCI compiler instance has not been created");
+    }
     return _instance;
   }
 
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1000,7 +1000,7 @@
   return -1;
 C2V_END
 
-C2V_VMENTRY(void, setNotInlineableOrCompileable,(JNIEnv *, jobject,  jobject jvmci_method))
+C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv *, jobject,  jobject jvmci_method))
   methodHandle method = CompilerToVM::asMethod(jvmci_method);
   method->set_not_c1_compilable();
   method->set_not_c2_compilable();
@@ -1018,7 +1018,7 @@
   Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code));
   Handle speculation_log_handle(THREAD, JNIHandles::resolve(speculation_log));
 
-  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR);
+  JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
 
   TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
   bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0;
@@ -1039,7 +1039,7 @@
   if (result != JVMCIEnv::ok) {
     assert(cb == NULL, "should be");
   } else {
-    if (!installed_code_handle.is_null()) {
+    if (installed_code_handle.not_null()) {
       assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type");
       nmethod::invalidate_installed_code(installed_code_handle, CHECK_0);
       {
@@ -1058,13 +1058,6 @@
           HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size());
         }
       }
-      nmethod* nm = cb->as_nmethod_or_null();
-      if (nm != NULL && installed_code_handle->is_scavengable()) {
-        assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable");
-        if (!UseG1GC) {
-          assert(nm->on_scavenge_root_list(), "nm should be on scavengable list");
-        }
-      }
     }
   }
   return result;
@@ -1143,7 +1136,7 @@
 C2V_END
 
 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
-  JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
+  JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
   CompilerStatistics* stats = compiler->stats();
   stats->_standard.reset();
   stats->_osr.reset();
@@ -1697,7 +1690,7 @@
   }
   while (length > 0) {
     jbyte* start = array->byte_at_addr(offset);
-    tty->write((char*) start, MIN2(length, O_BUFLEN));
+    tty->write((char*) start, MIN2(length, (jint)O_BUFLEN));
     length -= O_BUFLEN;
     offset += O_BUFLEN;
   }
@@ -1820,7 +1813,7 @@
   {CC "getImplementor",                               CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS,                                       FN_PTR(getImplementor)},
   {CC "getStackTraceElement",                         CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT,                                   FN_PTR(getStackTraceElement)},
   {CC "methodIsIgnoredBySecurityStackWalk",           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(methodIsIgnoredBySecurityStackWalk)},
-  {CC "setNotInlineableOrCompileable",                CC "(" HS_RESOLVED_METHOD ")V",                                                       FN_PTR(setNotInlineableOrCompileable)},
+  {CC "setNotInlinableOrCompilable",                  CC "(" HS_RESOLVED_METHOD ")V",                                                       FN_PTR(setNotInlinableOrCompilable)},
   {CC "isCompilable",                                 CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(isCompilable)},
   {CC "hasNeverInlineDirective",                      CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(hasNeverInlineDirective)},
   {CC "shouldInlineMethod",                           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(shouldInlineMethod)},
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -521,7 +521,9 @@
                                  debug_info, dependencies, code_buffer,
                                  frame_words, oop_map_set,
                                  handler_table, &implicit_tbl,
-                                 compiler, comp_level, installed_code, speculation_log);
+                                 compiler, comp_level,
+                                 JNIHandles::make_weak_global(installed_code),
+                                 JNIHandles::make_weak_global(speculation_log));
 
       // Free codeBlobs
       //code_buffer->free_blob();
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "asm/codeBuffer.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "code/codeCache.hpp"
@@ -37,7 +38,6 @@
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/reflection.hpp"
@@ -611,7 +611,7 @@
   }
 JRT_END
 
-JRT_ENTRY(jint, JVMCIRuntime::test_deoptimize_call_int(JavaThread* thread, int value))
+JRT_ENTRY(int, JVMCIRuntime::test_deoptimize_call_int(JavaThread* thread, int value))
   deopt_caller();
   return value;
 JRT_END
@@ -821,28 +821,37 @@
 }
 
 CompLevel JVMCIRuntime::adjust_comp_level_inner(const methodHandle& method, bool is_osr, CompLevel level, JavaThread* thread) {
-  JVMCICompiler* compiler = JVMCICompiler::instance(thread);
+  JVMCICompiler* compiler = JVMCICompiler::instance(false, thread);
   if (compiler != NULL && compiler->is_bootstrapping()) {
     return level;
   }
-  if (!is_HotSpotJVMCIRuntime_initialized() || !_comp_level_adjustment) {
+  if (!is_HotSpotJVMCIRuntime_initialized() || _comp_level_adjustment == JVMCIRuntime::none) {
     // JVMCI cannot participate in compilation scheduling until
     // JVMCI is initialized and indicates it wants to participate.
     return level;
   }
 
 #define CHECK_RETURN THREAD); \
-if (HAS_PENDING_EXCEPTION) { \
-  Handle exception(THREAD, PENDING_EXCEPTION); \
-  CLEAR_PENDING_EXCEPTION; \
-\
-  java_lang_Throwable::java_printStackTrace(exception, THREAD); \
   if (HAS_PENDING_EXCEPTION) { \
+    Handle exception(THREAD, PENDING_EXCEPTION); \
     CLEAR_PENDING_EXCEPTION; \
+  \
+    if (exception->is_a(SystemDictionary::ThreadDeath_klass())) { \
+      /* In the special case of ThreadDeath, we need to reset the */ \
+      /* pending async exception so that it is propagated.        */ \
+      thread->set_pending_async_exception(exception()); \
+      return level; \
+    } \
+    tty->print("Uncaught exception while adjusting compilation level: "); \
+    java_lang_Throwable::print(exception(), tty); \
+    tty->cr(); \
+    java_lang_Throwable::print_stack_trace(exception, tty); \
+    if (HAS_PENDING_EXCEPTION) { \
+      CLEAR_PENDING_EXCEPTION; \
+    } \
+    return level; \
   } \
-  return level; \
-} \
-(void)(0
+  (void)(0
 
 
   Thread* THREAD = thread;
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,8 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "jvmci/jvmci_globals.hpp"
-#include "prims/jvm.h"
 #include "utilities/defaultStream.hpp"
 #include "runtime/globals_extension.hpp"
 
--- a/src/hotspot/share/logging/logConfiguration.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logConfiguration.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/log.hpp"
 #include "logging/logConfiguration.hpp"
 #include "logging/logDecorations.hpp"
@@ -34,7 +35,6 @@
 #include "logging/logTagSet.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/os.inline.hpp"
 #include "runtime/semaphore.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/logging/logDecorations.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logDecorations.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,9 +22,9 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logConfiguration.hpp"
 #include "logging/logDecorations.hpp"
-#include "prims/jvm.h"
 #include "runtime/os.inline.hpp"
 #include "runtime/thread.inline.hpp"
 #include "services/management.hpp"
--- a/src/hotspot/share/logging/logFileOutput.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logFileOutput.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,11 +22,11 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/log.hpp"
 #include "logging/logConfiguration.hpp"
 #include "logging/logFileOutput.hpp"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/os.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/logging/logFileStreamOutput.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logFileStreamOutput.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,12 +22,12 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logDecorators.hpp"
 #include "logging/logDecorations.hpp"
 #include "logging/logFileStreamOutput.hpp"
 #include "logging/logMessageBuffer.hpp"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 
 static bool initialized;
 static union {
--- a/src/hotspot/share/logging/logOutput.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logOutput.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,11 +22,11 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logFileStreamOutput.hpp"
 #include "logging/logOutput.hpp"
 #include "logging/logTagSet.hpp"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.inline.hpp"
 
--- a/src/hotspot/share/logging/logTagSet.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/logging/logTagSet.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logDecorations.hpp"
 #include "logging/logFileStreamOutput.hpp"
 #include "logging/logLevel.hpp"
@@ -31,7 +32,6 @@
 #include "logging/logTagSet.hpp"
 #include "logging/logTagSetDescriptions.hpp"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 #include "utilities/ostream.hpp"
 
 LogTagSet*  LogTagSet::_list      = NULL;
--- a/src/hotspot/share/memory/filemap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/compactHashtable.inline.hpp"
 #include "classfile/sharedClassUtil.hpp"
@@ -42,7 +43,6 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/objArrayOop.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/java.hpp"
--- a/src/hotspot/share/memory/heap.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/heap.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -160,7 +160,18 @@
   char* high_boundary() const                    { return _memory.high_boundary(); }
 
   bool contains(const void* p) const             { return low_boundary() <= p && p < high(); }
-  bool contains_blob(const CodeBlob* blob) const { return contains(blob->code_begin()); }
+  bool contains_blob(const CodeBlob* blob) const {
+    // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap.
+    // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
+    // directly in their corresponding CodeHeap with their code appended to the actual C++ object.
+    // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while
+    // AOTCompiledMethod and their code/data is distributed in the C-Heap. This means we can use the
+    // address of a CodeBlob object in order to locate it in its heap while we have to use the address
+    // of the actual code an AOTCompiledMethod object is pointing to in order to locate it.
+    // Notice that for an ordinary CodeBlob with code size zero, code_begin() may point beyond the object!
+    const void* start = AOT_ONLY( (code_blob_type() == CodeBlobType::AOT) ? blob->code_begin() : ) (void*)blob;
+    return contains(start);
+  }
 
   virtual void* find_start(void* p)     const;   // returns the block containing p or NULL
   virtual CodeBlob* find_blob_unsafe(void* start) const;
--- a/src/hotspot/share/memory/metachunk.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/metachunk.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -55,8 +55,8 @@
     _container(container)
 {
   _top = initial_top();
+  set_is_tagged_free(false);
 #ifdef ASSERT
-  set_is_tagged_free(false);
   mangle(uninitMetaWordVal);
 #endif
 }
--- a/src/hotspot/share/memory/metachunk.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/metachunk.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -102,7 +102,7 @@
   // Current allocation top.
   MetaWord* _top;
 
-  DEBUG_ONLY(bool _is_tagged_free;)
+  bool _is_tagged_free;
 
   MetaWord* initial_top() const { return (MetaWord*)this + overhead(); }
   MetaWord* top() const         { return _top; }
@@ -138,10 +138,8 @@
   size_t used_word_size() const;
   size_t free_word_size() const;
 
-#ifdef ASSERT
   bool is_tagged_free() { return _is_tagged_free; }
   void set_is_tagged_free(bool v) { _is_tagged_free = v; }
-#endif
 
   bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; }
 
--- a/src/hotspot/share/memory/metaspace.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/metaspace.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -108,6 +108,18 @@
   return (ChunkIndex) (i+1);
 }
 
+static const char* scale_unit(size_t scale) {
+  switch(scale) {
+    case 1: return "BYTES";
+    case K: return "KB";
+    case M: return "MB";
+    case G: return "GB";
+    default:
+      ShouldNotReachHere();
+      return NULL;
+  }
+}
+
 volatile intptr_t MetaspaceGC::_capacity_until_GC = 0;
 uint MetaspaceGC::_shrink_factor = 0;
 bool MetaspaceGC::_should_concurrent_collect = false;
@@ -176,7 +188,7 @@
 
   void locked_get_statistics(ChunkManagerStatistics* stat) const;
   void get_statistics(ChunkManagerStatistics* stat) const;
-  static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out);
+  static void print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale);
 
  public:
 
@@ -283,7 +295,7 @@
 
   // Prints composition for both non-class and (if available)
   // class chunk manager.
-  static void print_all_chunkmanagers(outputStream* out);
+  static void print_all_chunkmanagers(outputStream* out, size_t scale = 1);
 };
 
 class SmallBlocks : public CHeapObj<mtClass> {
@@ -480,6 +492,7 @@
 #endif
 
   void print_on(outputStream* st) const;
+  void print_map(outputStream* st, bool is_class) const;
 };
 
 #define assert_is_aligned(value, alignment)                  \
@@ -531,6 +544,94 @@
   }
 }
 
+void VirtualSpaceNode::print_map(outputStream* st, bool is_class) const {
+
+  // Format:
+  // <ptr>
+  // <ptr>  . .. .               .  ..
+  //        SSxSSMMMMMMMMMMMMMMMMsssXX
+  //        112114444444444444444
+  // <ptr>  . .. .               .  ..
+  //        SSxSSMMMMMMMMMMMMMMMMsssXX
+  //        112114444444444444444
+
+  if (bottom() == top()) {
+    return;
+  }
+
+  // First line: dividers for every med-chunk-sized interval
+  // Second line: a dot for the start of a chunk
+  // Third line: a letter per chunk type (x,s,m,h), uppercase if in use.
+
+  const size_t spec_chunk_size = is_class ? ClassSpecializedChunk : SpecializedChunk;
+  const size_t small_chunk_size = is_class ? ClassSmallChunk : SmallChunk;
+  const size_t med_chunk_size = is_class ? ClassMediumChunk : MediumChunk;
+
+  int line_len = 100;
+  const size_t section_len = align_up(spec_chunk_size * line_len, med_chunk_size);
+  line_len = (int)(section_len / spec_chunk_size);
+
+  char* line1 = (char*)os::malloc(line_len, mtInternal);
+  char* line2 = (char*)os::malloc(line_len, mtInternal);
+  char* line3 = (char*)os::malloc(line_len, mtInternal);
+  int pos = 0;
+  const MetaWord* p = bottom();
+  const Metachunk* chunk = (const Metachunk*)p;
+  const MetaWord* chunk_end = p + chunk->word_size();
+  while (p < top()) {
+    if (pos == line_len) {
+      pos = 0;
+      st->fill_to(22);
+      st->print_raw(line1, line_len);
+      st->cr();
+      st->fill_to(22);
+      st->print_raw(line2, line_len);
+      st->cr();
+    }
+    if (pos == 0) {
+      st->print(PTR_FORMAT ":", p2i(p));
+    }
+    if (p == chunk_end) {
+      chunk = (Metachunk*)p;
+      chunk_end = p + chunk->word_size();
+    }
+    if (p == (const MetaWord*)chunk) {
+      // chunk starts.
+      line1[pos] = '.';
+    } else {
+      line1[pos] = ' ';
+    }
+    // Line 2: chunk type (x=spec, s=small, m=medium, h=humongous), uppercase if
+    // chunk is in use.
+    const bool chunk_is_free = ((Metachunk*)chunk)->is_tagged_free();
+    if (chunk->word_size() == spec_chunk_size) {
+      line2[pos] = chunk_is_free ? 'x' : 'X';
+    } else if (chunk->word_size() == small_chunk_size) {
+      line2[pos] = chunk_is_free ? 's' : 'S';
+    } else if (chunk->word_size() == med_chunk_size) {
+      line2[pos] = chunk_is_free ? 'm' : 'M';
+   } else if (chunk->word_size() > med_chunk_size) {
+      line2[pos] = chunk_is_free ? 'h' : 'H';
+    } else {
+      ShouldNotReachHere();
+    }
+    p += spec_chunk_size;
+    pos ++;
+  }
+  if (pos > 0) {
+    st->fill_to(22);
+    st->print_raw(line1, pos);
+    st->cr();
+    st->fill_to(22);
+    st->print_raw(line2, pos);
+    st->cr();
+  }
+  os::free(line1);
+  os::free(line2);
+  os::free(line3);
+}
+
+
 #ifdef ASSERT
 uintx VirtualSpaceNode::container_count_slow() {
   uintx count = 0;
@@ -637,6 +738,7 @@
   void purge(ChunkManager* chunk_manager);
 
   void print_on(outputStream* st) const;
+  void print_map(outputStream* st) const;
 
   class VirtualSpaceListIterator : public StackObj {
     VirtualSpaceNode* _virtual_spaces;
@@ -1449,6 +1551,18 @@
   }
 }
 
+void VirtualSpaceList::print_map(outputStream* st) const {
+  VirtualSpaceNode* list = virtual_space_list();
+  VirtualSpaceListIterator iter(list);
+  unsigned i = 0;
+  while (iter.repeat()) {
+    st->print_cr("Node %u:", i);
+    VirtualSpaceNode* node = iter.get_next();
+    node->print_map(st, this->is_class());
+    i ++;
+  }
+}
+
 // MetaspaceGC methods
 
 // VM_CollectForMetadataAllocation is the vm operation used to GC.
@@ -1724,7 +1838,6 @@
 #endif
 
 // ChunkManager methods
-
 size_t ChunkManager::free_chunks_total_words() {
   return _free_chunks_total;
 }
@@ -1923,11 +2036,10 @@
   // Remove it from the links to this freelist
   chunk->set_next(NULL);
   chunk->set_prev(NULL);
-#ifdef ASSERT
+
   // Chunk is no longer on any freelist. Setting to false make container_count_slow()
   // work.
   chunk->set_is_tagged_free(false);
-#endif
   chunk->container()->inc_container_count();
 
   slow_locked_verify();
@@ -1995,7 +2107,7 @@
         chunk_size_name(index), p2i(chunk), chunk->word_size());
   }
   chunk->container()->dec_container_count();
-  DEBUG_ONLY(chunk->set_is_tagged_free(true);)
+  chunk->set_is_tagged_free(true);
 
   // Chunk has been added; update counters.
   account_for_added_chunk(chunk);
@@ -2057,22 +2169,45 @@
   locked_get_statistics(stat);
 }
 
-void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out) {
+void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) {
   size_t total = 0;
+  assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
+  const char* unit = scale_unit(scale);
   for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
-    out->print_cr("  " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total " SIZE_FORMAT " bytes",
-                 stat->num_by_type[i], chunk_size_name(i),
-                 stat->single_size_by_type[i],
-                 stat->total_size_by_type[i]);
+    out->print("  " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ",
+                   stat->num_by_type[i], chunk_size_name(i),
+                   stat->single_size_by_type[i]);
+    if (scale == 1) {
+      out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]);
+    } else {
+      out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit);
+    }
+
     total += stat->total_size_by_type[i];
   }
-  out->print_cr("  " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
-               stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+
   total += stat->total_size_humongous_chunks;
-  out->print_cr("  total size: " SIZE_FORMAT ".", total);
+
+  if (scale == 1) {
+    out->print_cr("  " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes",
+    stat->num_humongous_chunks, stat->total_size_humongous_chunks);
+
+    out->print_cr("  total size: " SIZE_FORMAT " bytes.", total);
+  } else {
+    out->print_cr("  " SIZE_FORMAT " humongous chunks, total %.2f%s",
+    stat->num_humongous_chunks,
+    (float)stat->total_size_humongous_chunks / scale, unit);
+
+    out->print_cr("  total size: %.2f%s.", (float)total / scale, unit);
+  }
+
 }
 
-void ChunkManager::print_all_chunkmanagers(outputStream* out) {
+void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) {
+  assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale");
+
   // Note: keep lock protection only to retrieving statistics; keep printing
   // out of lock protection
   ChunkManagerStatistics stat;
@@ -2080,7 +2215,7 @@
   const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata();
   if (non_class_cm != NULL) {
     non_class_cm->get_statistics(&stat);
-    ChunkManager::print_statistics(&stat, out);
+    ChunkManager::print_statistics(&stat, out, scale);
   } else {
     out->print_cr("unavailable.");
   }
@@ -2088,7 +2223,7 @@
   const ChunkManager* const class_cm = Metaspace::chunk_manager_class();
   if (class_cm != NULL) {
     class_cm->get_statistics(&stat);
-    ChunkManager::print_statistics(&stat, out);
+    ChunkManager::print_statistics(&stat, out, scale);
   } else {
     out->print_cr("unavailable.");
   }
@@ -2911,9 +3046,9 @@
   size_t free_bytes = free_bytes_slow(mdtype);
   size_t used_and_free = used_bytes + free_bytes +
                            free_chunks_capacity_bytes;
-  out->print_cr("  Chunk accounting: used in chunks " SIZE_FORMAT
+  out->print_cr("  Chunk accounting: (used in chunks " SIZE_FORMAT
              "K + unused in chunks " SIZE_FORMAT "K  + "
-             " capacity in free chunks " SIZE_FORMAT "K = " SIZE_FORMAT
+             " capacity in free chunks " SIZE_FORMAT "K) = " SIZE_FORMAT
              "K  capacity in allocated chunks " SIZE_FORMAT "K",
              used_bytes / K,
              free_bytes / K,
@@ -2981,6 +3116,194 @@
   }
 }
 
+class MetadataStats VALUE_OBJ_CLASS_SPEC {
+private:
+  size_t _capacity;
+  size_t _used;
+  size_t _free;
+  size_t _waste;
+
+public:
+  MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { }
+  MetadataStats(size_t capacity, size_t used, size_t free, size_t waste)
+  : _capacity(capacity), _used(used), _free(free), _waste(waste) { }
+
+  void add(const MetadataStats& stats) {
+    _capacity += stats.capacity();
+    _used += stats.used();
+    _free += stats.free();
+    _waste += stats.waste();
+  }
+
+  size_t capacity() const { return _capacity; }
+  size_t used() const     { return _used; }
+  size_t free() const     { return _free; }
+  size_t waste() const    { return _waste; }
+
+  void print_on(outputStream* out, size_t scale) const;
+};
+
+
+void MetadataStats::print_on(outputStream* out, size_t scale) const {
+  const char* unit = scale_unit(scale);
+  out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s",
+    (float)capacity() / scale, unit,
+    (float)used() / scale, unit,
+    (float)free() / scale, unit,
+    (float)waste() / scale, unit);
+}
+
+class PrintCLDMetaspaceInfoClosure : public CLDClosure {
+private:
+  outputStream*  _out;
+  size_t         _scale;
+
+  size_t         _total_count;
+  MetadataStats  _total_metadata;
+  MetadataStats  _total_class;
+
+  size_t         _total_anon_count;
+  MetadataStats  _total_anon_metadata;
+  MetadataStats  _total_anon_class;
+
+public:
+  PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K)
+  : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { }
+
+  ~PrintCLDMetaspaceInfoClosure() {
+    print_summary();
+  }
+
+  void do_cld(ClassLoaderData* cld) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
+
+    if (cld->is_unloading()) return;
+    Metaspace* msp = cld->metaspace_or_null();
+    if (msp == NULL) {
+      return;
+    }
+
+    bool anonymous = false;
+    if (cld->is_anonymous()) {
+      _out->print_cr("ClassLoader: for anonymous class");
+      anonymous = true;
+    } else {
+      ResourceMark rm;
+      _out->print_cr("ClassLoader: %s", cld->loader_name());
+    }
+
+    print_metaspace(msp, anonymous);
+    _out->cr();
+  }
+
+private:
+  void print_metaspace(Metaspace* msp, bool anonymous);
+  void print_summary() const;
+};
+
+void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){
+  assert(msp != NULL, "Sanity");
+  SpaceManager* vsm = msp->vsm();
+  const char* unit = scale_unit(_scale);
+
+  size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+  size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+  size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+  size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+  _total_count ++;
+  MetadataStats metadata_stats(capacity, used, free, waste);
+  _total_metadata.add(metadata_stats);
+
+  if (anonymous) {
+    _total_anon_count ++;
+    _total_anon_metadata.add(metadata_stats);
+  }
+
+  _out->print("  Metadata   ");
+  metadata_stats.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    vsm = msp->class_vsm();
+
+    capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord;
+    used = vsm->sum_used_in_chunks_in_use() * BytesPerWord;
+    free = vsm->sum_free_in_chunks_in_use() * BytesPerWord;
+    waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord;
+
+    MetadataStats class_stats(capacity, used, free, waste);
+    _total_class.add(class_stats);
+
+    if (anonymous) {
+      _total_anon_class.add(class_stats);
+    }
+
+    _out->print("  Class data ");
+    class_stats.print_on(_out, _scale);
+  }
+}
+
+void PrintCLDMetaspaceInfoClosure::print_summary() const {
+  const char* unit = scale_unit(_scale);
+  _out->cr();
+  _out->print_cr("Summary:");
+
+  MetadataStats total;
+  total.add(_total_metadata);
+  total.add(_total_class);
+
+  _out->print("  Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count);
+  total.print_on(_out, _scale);
+
+  _out->print("                    Metadata ");
+  _total_metadata.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    _out->print("                  Class data ");
+    _total_class.print_on(_out, _scale);
+  }
+  _out->cr();
+
+  MetadataStats total_anon;
+  total_anon.add(_total_anon_metadata);
+  total_anon.add(_total_anon_class);
+
+  _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count);
+  total_anon.print_on(_out, _scale);
+
+  _out->print("                    Metadata ");
+  _total_anon_metadata.print_on(_out, _scale);
+
+  if (Metaspace::using_class_space()) {
+    _out->print("                  Class data ");
+    _total_anon_class.print_on(_out, _scale);
+  }
+}
+
+void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) {
+  const char* unit = scale_unit(scale);
+  out->print_cr("Metaspaces:");
+  out->print_cr("  Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+    reserved_bytes(Metaspace::NonClassType) / scale, unit,
+    committed_bytes(Metaspace::NonClassType) / scale, unit);
+  if (Metaspace::using_class_space()) {
+    out->print_cr("  Class    space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s",
+    reserved_bytes(Metaspace::ClassType) / scale, unit,
+    committed_bytes(Metaspace::ClassType) / scale, unit);
+  }
+
+  out->cr();
+  ChunkManager::print_all_chunkmanagers(out, scale);
+
+  out->cr();
+  out->print_cr("Per-classloader metadata:");
+  out->cr();
+
+  PrintCLDMetaspaceInfoClosure cl(out, scale);
+  ClassLoaderDataGraph::cld_do(&cl);
+}
+
+
 // Dump global metaspace things from the end of ClassLoaderDataGraph
 void MetaspaceAux::dump(outputStream* out) {
   out->print_cr("All Metaspace:");
@@ -2989,6 +3312,31 @@
   print_waste(out);
 }
 
+// Prints an ASCII representation of the given space.
+void MetaspaceAux::print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype) {
+  MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
+  const bool for_class = mdtype == Metaspace::ClassType ? true : false;
+  VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+  if (vsl != NULL) {
+    if (for_class) {
+      if (!Metaspace::using_class_space()) {
+        out->print_cr("No Class Space.");
+        return;
+      }
+      out->print_raw("---- Metaspace Map (Class Space) ----");
+    } else {
+      out->print_raw("---- Metaspace Map (Non-Class Space) ----");
+    }
+    // Print legend:
+    out->cr();
+    out->print_cr("Chunk Types (uppercase chunks are in use): x-specialized, s-small, m-medium, h-humongous.");
+    out->cr();
+    VirtualSpaceList* const vsl = for_class ? Metaspace::class_space_list() : Metaspace::space_list();
+    vsl->print_map(out);
+    out->cr();
+  }
+}
+
 void MetaspaceAux::verify_free_chunks() {
   Metaspace::chunk_manager_metadata()->verify();
   if (Metaspace::using_class_space()) {
@@ -3627,6 +3975,7 @@
     }
     LogStream ls(log.info());
     MetaspaceAux::dump(&ls);
+    MetaspaceAux::print_metaspace_map(&ls, mdtype);
     ChunkManager::print_all_chunkmanagers(&ls);
   }
 
--- a/src/hotspot/share/memory/metaspace.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/metaspace.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -63,6 +63,7 @@
 class MetaWord;
 class Mutex;
 class outputStream;
+class PrintCLDMetaspaceInfoClosure;
 class SpaceManager;
 class VirtualSpaceList;
 
@@ -87,6 +88,7 @@
   friend class MetaspaceAux;
   friend class MetaspaceShared;
   friend class CollectorPolicy;
+  friend class PrintCLDMetaspaceInfoClosure;
 
  public:
   enum MetadataType {
@@ -347,6 +349,8 @@
     return min_chunk_size_words() * BytesPerWord;
   }
 
+  static void print_metadata_for_nmt(outputStream* out, size_t scale = K);
+
   static bool has_chunk_free_list(Metaspace::MetadataType mdtype);
   static MetaspaceChunkFreeListSummary chunk_free_list_summary(Metaspace::MetadataType mdtype);
 
@@ -357,6 +361,10 @@
 
   static void print_class_waste(outputStream* out);
   static void print_waste(outputStream* out);
+
+  // Prints an ASCII representation of the given space.
+  static void print_metaspace_map(outputStream* out, Metaspace::MetadataType mdtype);
+
   static void dump(outputStream* out);
   static void verify_free_chunks();
   // Checks that the values returned by allocated_capacity_bytes() and
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classListParser.hpp"
 #include "classfile/classLoaderExt.hpp"
 #include "classfile/dictionary.hpp"
@@ -55,7 +56,6 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayKlass.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiRedefineClasses.hpp"
 #include "runtime/timerTrace.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/memory/universe.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/memory/universe.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -32,10 +32,10 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/dependencies.hpp"
+#include "gc/serial/serialHeap.hpp"
 #include "gc/shared/cardTableModRefBS.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
-#include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/generation.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/space.hpp"
@@ -762,7 +762,7 @@
     return Universe::create_heap_with_policy<CMSHeap, ConcurrentMarkSweepPolicy>();
 #endif
   } else if (UseSerialGC) {
-    return Universe::create_heap_with_policy<GenCollectedHeap, MarkSweepPolicy>();
+    return Universe::create_heap_with_policy<SerialHeap, MarkSweepPolicy>();
   }
 
   ShouldNotReachHere();
--- a/src/hotspot/share/oops/constantPool.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/constantPool.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoaderData.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/metadataOnStackMark.hpp"
@@ -41,7 +42,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/fieldType.hpp"
 #include "runtime/init.hpp"
 #include "runtime/javaCalls.hpp"
@@ -305,14 +305,9 @@
 
   constantPoolHandle cp(THREAD, this);
   for (int index = 1; index < length(); index++) { // Index 0 is unused
-    if (tag_at(index).is_string()) {
-      Symbol* sym = cp->unresolved_string_at(index);
-      // Look up only. Only resolve references to already interned strings.
-      oop str = StringTable::lookup(sym);
-      if (str != NULL) {
-        int cache_index = cp->cp_to_object_index(index);
-        cp->string_at_put(index, cache_index, str);
-      }
+    if (tag_at(index).is_string() && !cp->is_pseudo_string_at(index)) {
+      int cache_index = cp->cp_to_object_index(index);
+      string_at_impl(cp, index, cache_index, CHECK);
     }
   }
 }
--- a/src/hotspot/share/oops/generateOopMap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/generateOopMap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,13 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "interpreter/bytecodeStream.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "oops/generateOopMap.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/relocator.hpp"
@@ -2146,8 +2146,14 @@
   // Append method name
   char msg_buffer2[512];
   jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg_buffer, method()->name()->as_C_string());
-  _exception = Exceptions::new_exception(Thread::current(),
-                vmSymbols::java_lang_LinkageError(), msg_buffer2);
+  if (Thread::current()->can_call_java()) {
+    _exception = Exceptions::new_exception(Thread::current(),
+                  vmSymbols::java_lang_LinkageError(), msg_buffer2);
+  } else {
+    // We cannot instantiate an exception object from a compiler thread.
+    // Exit the VM with a useful error message.
+    fatal("%s", msg_buffer2);
+  }
 }
 
 void GenerateOopMap::report_error(const char *format, ...) {
@@ -2159,14 +2165,7 @@
 void GenerateOopMap::verify_error(const char *format, ...) {
   // We do not distinguish between different types of errors for verification
   // errors.  Let the verifier give a better message.
-  const char *msg = "Illegal class file encountered. Try running with -Xverify:all";
-  _got_error = true;
-  // Append method name
-  char msg_buffer2[512];
-  jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg,
-               method()->name()->as_C_string());
-  _exception = Exceptions::new_exception(Thread::current(),
-                vmSymbols::java_lang_LinkageError(), msg_buffer2);
+  report_error("Illegal class file encountered. Try running with -Xverify:all");
 }
 
 //
--- a/src/hotspot/share/oops/instanceKlass.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "aot/aotLoader.hpp"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
@@ -59,7 +60,6 @@
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiRedefineClasses.hpp"
 #include "prims/jvmtiThreadState.hpp"
--- a/src/hotspot/share/oops/klassVtable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/klassVtable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc/shared/gcLocker.hpp"
@@ -36,7 +37,6 @@
 #include "oops/method.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
 #include "utilities/copy.hpp"
--- a/src/hotspot/share/oops/method.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/method.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -271,7 +271,7 @@
   int highest_osr_comp_level() const;
   void set_highest_osr_comp_level(int level);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Count of times method was exited via exception while interpreting
   void interpreter_throwout_increment(TRAPS) {
     MethodCounters* mcs = get_method_counters(CHECK);
@@ -426,7 +426,7 @@
       return (mcs == NULL) ? 0 : mcs->interpreter_invocation_count();
     }
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int increment_interpreter_invocation_count(TRAPS) {
     if (TieredCompilation) ShouldNotReachHere();
     MethodCounters* mcs = get_method_counters(CHECK_0);
--- a/src/hotspot/share/oops/methodCounters.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/oops/methodCounters.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -40,7 +40,7 @@
 #if INCLUDE_AOT
   Method*           _method;                     // Back link to Method
 #endif
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int               _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
 #endif
@@ -130,7 +130,7 @@
   MetaspaceObj::Type type() const { return MethodCountersType; }
   void clear_counters();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
   int interpreter_invocation_count() {
     return _interpreter_invocation_count;
@@ -154,7 +154,7 @@
     _interpreter_throwout_count = count;
   }
 
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
   int interpreter_invocation_count() {
     return 0;
@@ -170,7 +170,7 @@
     assert(count == 0, "count must be 0");
   }
 
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #if INCLUDE_JVMTI
   u2   number_of_breakpoints() const   { return _number_of_breakpoints; }
@@ -213,7 +213,7 @@
     return byte_offset_of(MethodCounters, _nmethod_age);
   }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 
   static ByteSize interpreter_invocation_counter_offset() {
     return byte_offset_of(MethodCounters, _interpreter_invocation_count);
@@ -223,14 +223,14 @@
     return offset_of(MethodCounters, _interpreter_invocation_count);
   }
 
-#else // defined(COMPILER2) || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
   static ByteSize interpreter_invocation_counter_offset() {
     ShouldNotReachHere();
     return in_ByteSize(0);
   }
 
-#endif // defined(COMPILER2) || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   static ByteSize invocation_counter_offset()    {
     return byte_offset_of(MethodCounters, _invocation_counter);
--- a/src/hotspot/share/opto/castnode.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/castnode.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -237,8 +237,8 @@
     if (in_type != NULL && this_type != NULL &&
         (in_type->_lo != this_type->_lo ||
          in_type->_hi != this_type->_hi)) {
-      int lo1 = this_type->_lo;
-      int hi1 = this_type->_hi;
+      jint lo1 = this_type->_lo;
+      jint hi1 = this_type->_hi;
       int w1  = this_type->_widen;
 
       if (lo1 >= 0) {
--- a/src/hotspot/share/opto/loopTransform.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/loopTransform.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2129,7 +2129,7 @@
       // Look for trip_counter + offset vs limit
       Node *rc_exp = cmp->in(1);
       Node *limit  = cmp->in(2);
-      jint scale_con= 1;        // Assume trip counter not scaled
+      int scale_con= 1;        // Assume trip counter not scaled
 
       Node *limit_c = get_ctrl(limit);
       if( loop->is_member(get_loop(limit_c) ) ) {
--- a/src/hotspot/share/opto/mulnode.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/mulnode.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -235,13 +235,13 @@
   const TypeInt *r1 = t1->is_int();
 
   // Fetch endpoints of all ranges
-  int32_t lo0 = r0->_lo;
+  jint lo0 = r0->_lo;
   double a = (double)lo0;
-  int32_t hi0 = r0->_hi;
+  jint hi0 = r0->_hi;
   double b = (double)hi0;
-  int32_t lo1 = r1->_lo;
+  jint lo1 = r1->_lo;
   double c = (double)lo1;
-  int32_t hi1 = r1->_hi;
+  jint hi1 = r1->_hi;
   double d = (double)hi1;
 
   // Compute all endpoints & check for overflow
--- a/src/hotspot/share/opto/output.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/output.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -577,10 +577,10 @@
     // arbitrary, and are not tied to any machine-level encodings.)
 #ifdef _LP64
     if( t->base() == Type::DoubleBot || t->base() == Type::DoubleCon ) {
-      array->append(new ConstantIntValue(0));
+      array->append(new ConstantIntValue((jint)0));
       array->append(new_loc_value( _regalloc, regnum, Location::dbl ));
     } else if ( t->base() == Type::Long ) {
-      array->append(new ConstantIntValue(0));
+      array->append(new ConstantIntValue((jint)0));
       array->append(new_loc_value( _regalloc, regnum, Location::lng ));
     } else if ( t->base() == Type::RawPtr ) {
       // jsr/ret return address which must be restored into a the full
@@ -663,7 +663,7 @@
   case Type::DoubleCon: {
     jdouble d = t->is_double_constant()->getd();
 #ifdef _LP64
-    array->append(new ConstantIntValue(0));
+    array->append(new ConstantIntValue((jint)0));
     array->append(new ConstantDoubleValue(d));
 #else
     // Repack the double as two jints.
@@ -683,7 +683,7 @@
   case Type::Long: {
     jlong d = t->is_long()->get_con();
 #ifdef _LP64
-    array->append(new ConstantIntValue(0));
+    array->append(new ConstantIntValue((jint)0));
     array->append(new ConstantLongValue(d));
 #else
     // Repack the long as two jints.
--- a/src/hotspot/share/opto/parse3.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/parse3.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -412,11 +412,11 @@
   // The original expression was of this form: new T[length0][length1]...
   // It is often the case that the lengths are small (except the last).
   // If that happens, use the fast 1-d creator a constant number of times.
-  const jint expand_limit = MIN2((jint)MultiArrayExpandLimit, 100);
-  jint expand_count = 1;        // count of allocations in the expansion
-  jint expand_fanout = 1;       // running total fanout
+  const int expand_limit = MIN2((int)MultiArrayExpandLimit, 100);
+  int expand_count = 1;        // count of allocations in the expansion
+  int expand_fanout = 1;       // running total fanout
   for (j = 0; j < ndimensions-1; j++) {
-    jint dim_con = find_int_con(length[j], -1);
+    int dim_con = find_int_con(length[j], -1);
     expand_fanout *= dim_con;
     expand_count  += expand_fanout; // count the level-J sub-arrays
     if (dim_con <= 0
--- a/src/hotspot/share/opto/phaseX.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/phaseX.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -723,7 +723,7 @@
 
 //------------------------------intcon-----------------------------------------
 // Fast integer constant.  Same as "transform(new ConINode(TypeInt::make(i)))"
-ConINode* PhaseTransform::intcon(int i) {
+ConINode* PhaseTransform::intcon(jint i) {
   // Small integer?  Check cache! Check that cached node is not dead
   if (i >= _icon_min && i <= _icon_max) {
     ConINode* icon = _icons[i-_icon_min];
--- a/src/hotspot/share/opto/split_if.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/split_if.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -116,9 +116,23 @@
         assert( bol->is_Bool(), "" );
         if (bol->outcnt() == 1) {
           Node* use = bol->unique_out();
-          Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use);
-          if (use_c == blk1 || use_c == blk2) {
-            continue;
+          if (use->Opcode() == Op_Opaque4) {
+            if (use->outcnt() == 1) {
+              Node* iff = use->unique_out();
+              assert(iff->is_If(), "unexpected node type");
+              Node *use_c = iff->in(0);
+              if (use_c == blk1 || use_c == blk2) {
+                continue;
+              }
+            }
+          } else {
+            // We might see an Opaque1 from a loop limit check here
+            assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type");
+            Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use);
+            if (use_c == blk1 || use_c == blk2) {
+              assert(use->is_CMove(), "unexpected node type");
+              continue;
+            }
           }
         }
         if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) {
@@ -129,17 +143,40 @@
             bol->dump();
           }
 #endif
-          for (DUIterator_Last jmin, j = bol->last_outs(jmin); j >= jmin; --j) {
-            // Uses are either IfNodes or CMoves
-            Node* iff = bol->last_out(j);
-            assert( iff->in(1) == bol, "" );
-            // Get control block of either the CMove or the If input
-            Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
-            Node *x = bol->clone();
-            register_new_node(x, iff_ctrl);
-            _igvn.replace_input_of(iff, 1, x);
+          for (DUIterator j = bol->outs(); bol->has_out(j); j++) {
+            Node* u = bol->out(j);
+            // Uses are either IfNodes, CMoves or Opaque4
+            if (u->Opcode() == Op_Opaque4) {
+              assert(u->in(1) == bol, "bad input");
+              for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) {
+                Node* iff = u->last_out(k);
+                assert(iff->is_If() || iff->is_CMove(), "unexpected node type");
+                assert( iff->in(1) == u, "" );
+                // Get control block of either the CMove or the If input
+                Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
+                Node *x1 = bol->clone();
+                Node *x2 = u->clone();
+                register_new_node(x1, iff_ctrl);
+                register_new_node(x2, iff_ctrl);
+                _igvn.replace_input_of(x2, 1, x1);
+                _igvn.replace_input_of(iff, 1, x2);
+              }
+              _igvn.remove_dead_node(u);
+              --j;
+            } else {
+              // We might see an Opaque1 from a loop limit check here
+              assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type");
+              assert(u->in(1) == bol, "");
+              // Get control block of either the CMove or the If input
+              Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u);
+              assert(u_ctrl != blk1 && u_ctrl != blk2, "won't converge");
+              Node *x = bol->clone();
+              register_new_node(x, u_ctrl);
+              _igvn.replace_input_of(u, 1, x);
+              --j;
+            }
           }
-          _igvn.remove_dead_node( bol );
+          _igvn.remove_dead_node(bol);
           --i;
         }
       }
--- a/src/hotspot/share/opto/superword.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/superword.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2168,10 +2168,12 @@
   CountedLoopNode *cl = lpt()->_head->as_CountedLoop();
   Compile* C = _phase->C;
   if (_packset.length() == 0) {
-    // Instigate more unrolling for optimization when vectorization fails.
-    C->set_major_progress();
-    cl->set_notpassed_slp();
-    cl->mark_do_unroll_only();
+    if (cl->is_main_loop()) {
+      // Instigate more unrolling for optimization when vectorization fails.
+      C->set_major_progress();
+      cl->set_notpassed_slp();
+      cl->mark_do_unroll_only();
+    }
     return;
   }
 
@@ -2417,6 +2419,9 @@
   }//for (int i = 0; i < _block.length(); i++)
 
   C->set_max_vector_size(max_vlen_in_bytes);
+  if (max_vlen_in_bytes > 0) {
+    cl->mark_loop_vectorized();
+  }
 
   if (SuperWordLoopUnrollAnalysis) {
     if (cl->has_passed_slp()) {
@@ -2439,7 +2444,6 @@
         }
 
         if (do_reserve_copy()) {
-          cl->mark_loop_vectorized();
           if (can_process_post_loop) {
             // Now create the difference of trip and limit and use it as our mask index.
             // Note: We limited the unroll of the vectorized loop so that
--- a/src/hotspot/share/opto/type.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/opto/type.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1503,7 +1503,7 @@
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypeInt::hash(void) const {
-  return java_add(java_add(_lo, _hi), java_add(_widen, (int)Type::Int));
+  return java_add(java_add(_lo, _hi), java_add((jint)_widen, (jint)Type::Int));
 }
 
 //------------------------------is_finite--------------------------------------
@@ -2505,7 +2505,7 @@
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypePtr::hash(void) const {
-  return java_add(java_add(_ptr, _offset), java_add( hash_speculative(), _inline_depth));
+  return java_add(java_add((jint)_ptr, (jint)_offset), java_add((jint)hash_speculative(), (jint)_inline_depth));
 ;
 }
 
@@ -3338,8 +3338,8 @@
 // Type-specific hashing function.
 int TypeOopPtr::hash(void) const {
   return
-    java_add(java_add(const_oop() ? const_oop()->hash() : 0, _klass_is_exact),
-             java_add(_instance_id, TypePtr::hash()));
+    java_add(java_add((jint)(const_oop() ? const_oop()->hash() : 0), (jint)_klass_is_exact),
+             java_add((jint)_instance_id, (jint)TypePtr::hash()));
 }
 
 //------------------------------dump2------------------------------------------
@@ -3946,7 +3946,7 @@
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypeInstPtr::hash(void) const {
-  int hash = java_add(klass()->hash(), TypeOopPtr::hash());
+  int hash = java_add((jint)klass()->hash(), (jint)TypeOopPtr::hash());
   return hash;
 }
 
@@ -4871,7 +4871,7 @@
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypeKlassPtr::hash(void) const {
-  return java_add(klass()->hash(), TypePtr::hash());
+  return java_add((jint)klass()->hash(), (jint)TypePtr::hash());
 }
 
 //------------------------------singleton--------------------------------------
--- a/src/hotspot/share/precompiled/precompiled.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/precompiled/precompiled.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -27,6 +27,7 @@
 
 #ifndef DONT_USE_PRECOMPILED_HEADER
 # include "jni.h"
+# include "jvm.h"
 # include "asm/assembler.hpp"
 # include "asm/assembler.inline.hpp"
 # include "asm/codeBuffer.hpp"
@@ -160,7 +161,6 @@
 # include "oops/symbol.hpp"
 # include "oops/typeArrayKlass.hpp"
 # include "oops/typeArrayOop.hpp"
-# include "prims/jvm.h"
 # include "prims/jvmtiExport.hpp"
 # include "prims/methodHandles.hpp"
 # include "runtime/arguments.hpp"
--- a/src/hotspot/share/prims/jni.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jni.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,6 +25,7 @@
 
 #include "precompiled.hpp"
 #include "jni.h"
+#include "jvm.h"
 #include "ci/ciReplay.hpp"
 #include "classfile/altHashing.hpp"
 #include "classfile/classFileStream.hpp"
@@ -55,7 +56,6 @@
 #include "prims/jniCheck.hpp"
 #include "prims/jniExport.hpp"
 #include "prims/jniFastGetField.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
@@ -263,7 +263,7 @@
 
 #ifdef ASSERT
   Histogram* JNIHistogram;
-  static volatile jint JNIHistogram_lock = 0;
+  static volatile int JNIHistogram_lock = 0;
 
   class JNIHistogramElement : public HistogramElement {
     public:
@@ -3277,9 +3277,9 @@
 
 // Initialization state for three routines below relating to
 // java.nio.DirectBuffers
-static          jint directBufferSupportInitializeStarted = 0;
-static volatile jint directBufferSupportInitializeEnded   = 0;
-static volatile jint directBufferSupportInitializeFailed  = 0;
+static          int directBufferSupportInitializeStarted = 0;
+static volatile int directBufferSupportInitializeEnded   = 0;
+static volatile int directBufferSupportInitializeFailed  = 0;
 static jclass    bufferClass                 = NULL;
 static jclass    directBufferClass           = NULL;
 static jclass    directByteBufferClass       = NULL;
@@ -3844,9 +3844,9 @@
 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
 
 // Global invocation API vars
-volatile jint vm_created = 0;
+volatile int vm_created = 0;
 // Indicate whether it is safe to recreate VM
-volatile jint safe_to_recreate_vm = 1;
+volatile int safe_to_recreate_vm = 1;
 struct JavaVM_ main_vm = {&jni_InvokeInterface};
 
 
@@ -3949,7 +3949,7 @@
         // JVMCI is initialized on a CompilerThread
         if (BootstrapJVMCI) {
           JavaThread* THREAD = thread;
-          JVMCICompiler* compiler = JVMCICompiler::instance(CATCH);
+          JVMCICompiler* compiler = JVMCICompiler::instance(true, CATCH);
           compiler->bootstrap(THREAD);
           if (HAS_PENDING_EXCEPTION) {
             HandleMark hm;
@@ -4045,7 +4045,7 @@
 
   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
 
-  if (vm_created) {
+  if (vm_created == 1) {
     if (numVMs != NULL) *numVMs = 1;
     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
   } else {
@@ -4065,7 +4065,7 @@
   jint res = JNI_ERR;
   DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
 
-  if (!vm_created) {
+  if (vm_created == 0) {
     res = JNI_ERR;
     return res;
   }
@@ -4086,7 +4086,7 @@
   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
   if (Threads::destroy_vm()) {
     // Should not change thread state, VM is gone
-    vm_created = false;
+    vm_created = 0;
     res = JNI_OK;
     return res;
   } else {
@@ -4226,7 +4226,7 @@
 
 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
   HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(vm, penv, _args);
-  if (!vm_created) {
+  if (vm_created == 0) {
   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
     return JNI_ERR;
   }
@@ -4285,7 +4285,7 @@
   jint ret = JNI_ERR;
   DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
 
-  if (!vm_created) {
+  if (vm_created == 0) {
     *penv = NULL;
     ret = JNI_EDETACHED;
     return ret;
@@ -4336,7 +4336,7 @@
 
 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(vm, penv, _args);
-  if (!vm_created) {
+  if (vm_created == 0) {
   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN((uint32_t) JNI_ERR);
     return JNI_ERR;
   }
--- a/src/hotspot/share/prims/jniCheck.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jniCheck.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "jni.h"
+#include "jvm.h"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -32,7 +33,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "prims/jniCheck.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.hpp"
--- a/src/hotspot/share/prims/jni_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "utilities/macros.hpp"
-
-/* Switch to the correct jni_md.h file without reliance on -I options. */
-#include CPU_HEADER_H(jni)
-
-/*
-  The local copies of JNI header files may be refreshed
-  from a JDK distribution by means of these commands:
-
-  cp ${JDK_DIST}/solaris/include/solaris/jni_md.h  ./jni_sparc.h
-  cp ${JDK_DIST}/win32/include/win32/jni_md.h      ./jni_i486.h
-  cp ${JDK_DIST}/win32/include/jni.h               ./jni.h
-
-*/
--- a/src/hotspot/share/prims/jvm.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jvm.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
@@ -46,7 +47,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
@@ -215,7 +215,7 @@
 
 #ifdef ASSERT
   Histogram* JVMHistogram;
-  volatile jint JVMHistogram_lock = 0;
+  volatile int JVMHistogram_lock = 0;
 
   class JVMHistogramElement : public HistogramElement {
     public:
@@ -3766,7 +3766,7 @@
   // when we add a new capability in the jvm_version_info struct, we should also
   // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat
   // counter defined in runtimeService.cpp.
-  info->is_attachable = AttachListener::is_attach_supported();
+  info->is_attach_supported = AttachListener::is_attach_supported();
 }
 JVM_END
 
--- a/src/hotspot/share/prims/jvm.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1373 +0,0 @@
-/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_PRIMS_JVM_H
-#define SHARE_VM_PRIMS_JVM_H
-
-#include "jni.h"
-#include "utilities/macros.hpp"
-
-#include OS_HEADER_H(jvm)
-
-#ifndef _JAVASOFT_JVM_H_
-#define _JAVASOFT_JVM_H_
-
-// HotSpot integration note:
-//
-// This file and jvm.h used with the JDK are identical,
-// except for the three includes removed below
-
-// #include <sys/stat.h>
-// #include "jni.h"
-// #include "jvm_md.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This file contains additional functions exported from the VM.
- * These functions are complementary to the standard JNI support.
- * There are three parts to this file:
- *
- * First, this file contains the VM-related functions needed by native
- * libraries in the standard Java API. For example, the java.lang.Object
- * class needs VM-level functions that wait for and notify monitors.
- *
- * Second, this file contains the functions and constant definitions
- * needed by the byte code verifier and class file format checker.
- * These functions allow the verifier and format checker to be written
- * in a VM-independent way.
- *
- * Third, this file contains various I/O and nerwork operations needed
- * by the standard Java I/O and network APIs.
- */
-
-/*
- * Bump the version number when either of the following happens:
- *
- * 1. There is a change in JVM_* functions.
- *
- * 2. There is a change in the contract between VM and Java classes.
- *    For example, if the VM relies on a new private field in Thread
- *    class.
- */
-
-#define JVM_INTERFACE_VERSION 5
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetMethodParameters(JNIEnv *env, jobject method);
-
-JNIEXPORT jint JNICALL
-JVM_GetInterfaceVersion(void);
-
-/*************************************************************************
- PART 1: Functions for Native Libraries
- ************************************************************************/
-/*
- * java.lang.Object
- */
-JNIEXPORT jint JNICALL
-JVM_IHashCode(JNIEnv *env, jobject obj);
-
-JNIEXPORT void JNICALL
-JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms);
-
-JNIEXPORT void JNICALL
-JVM_MonitorNotify(JNIEnv *env, jobject obj);
-
-JNIEXPORT void JNICALL
-JVM_MonitorNotifyAll(JNIEnv *env, jobject obj);
-
-JNIEXPORT jobject JNICALL
-JVM_Clone(JNIEnv *env, jobject obj);
-
-/*
- * java.lang.String
- */
-JNIEXPORT jstring JNICALL
-JVM_InternString(JNIEnv *env, jstring str);
-
-/*
- * java.lang.System
- */
-JNIEXPORT jlong JNICALL
-JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored);
-
-JNIEXPORT jlong JNICALL
-JVM_NanoTime(JNIEnv *env, jclass ignored);
-
-JNIEXPORT jlong JNICALL
-JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs);
-
-JNIEXPORT void JNICALL
-JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos,
-              jobject dst, jint dst_pos, jint length);
-
-JNIEXPORT jobject JNICALL
-JVM_InitProperties(JNIEnv *env, jobject p);
-
-/*
- * java.lang.Runtime
- */
-
-JNIEXPORT void JNICALL
-JVM_Halt(jint code);
-
-JNIEXPORT void JNICALL
-JVM_GC(void);
-
-/* Returns the number of real-time milliseconds that have elapsed since the
- * least-recently-inspected heap object was last inspected by the garbage
- * collector.
- *
- * For simple stop-the-world collectors this value is just the time
- * since the most recent collection.  For generational collectors it is the
- * time since the oldest generation was most recently collected.  Other
- * collectors are free to return a pessimistic estimate of the elapsed time, or
- * simply the time since the last full collection was performed.
- *
- * Note that in the presence of reference objects, a given object that is no
- * longer strongly reachable may have to be inspected multiple times before it
- * can be reclaimed.
- */
-JNIEXPORT jlong JNICALL
-JVM_MaxObjectInspectionAge(void);
-
-JNIEXPORT jlong JNICALL
-JVM_TotalMemory(void);
-
-JNIEXPORT jlong JNICALL
-JVM_FreeMemory(void);
-
-JNIEXPORT jlong JNICALL
-JVM_MaxMemory(void);
-
-JNIEXPORT jint JNICALL
-JVM_ActiveProcessorCount(void);
-
-JNIEXPORT void * JNICALL
-JVM_LoadLibrary(const char *name);
-
-JNIEXPORT void JNICALL
-JVM_UnloadLibrary(void * handle);
-
-JNIEXPORT void * JNICALL
-JVM_FindLibraryEntry(void *handle, const char *name);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsSupportedJNIVersion(jint version);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetVmArguments(JNIEnv *env);
-
-/*
- * java.lang.Throwable
- */
-JNIEXPORT void JNICALL
-JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
-
-/*
- * java.lang.StackTraceElement
- */
-JNIEXPORT void JNICALL
-JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable);
-
-JNIEXPORT void JNICALL
-JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo);
-
-/*
- * java.lang.StackWalker
- */
-enum {
-  JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x02,
-  JVM_STACKWALK_GET_CALLER_CLASS           = 0x04,
-  JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
-  JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
-};
-
-JNIEXPORT jobject JNICALL
-JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
-                  jint skip_frames, jint frame_count, jint start_index,
-                  jobjectArray frames);
-
-JNIEXPORT jint JNICALL
-JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
-                  jint frame_count, jint start_index,
-                  jobjectArray frames);
-
-/*
- * java.lang.Thread
- */
-JNIEXPORT void JNICALL
-JVM_StartThread(JNIEnv *env, jobject thread);
-
-JNIEXPORT void JNICALL
-JVM_StopThread(JNIEnv *env, jobject thread, jobject exception);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsThreadAlive(JNIEnv *env, jobject thread);
-
-JNIEXPORT void JNICALL
-JVM_SuspendThread(JNIEnv *env, jobject thread);
-
-JNIEXPORT void JNICALL
-JVM_ResumeThread(JNIEnv *env, jobject thread);
-
-JNIEXPORT void JNICALL
-JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio);
-
-JNIEXPORT void JNICALL
-JVM_Yield(JNIEnv *env, jclass threadClass);
-
-JNIEXPORT void JNICALL
-JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis);
-
-JNIEXPORT jobject JNICALL
-JVM_CurrentThread(JNIEnv *env, jclass threadClass);
-
-JNIEXPORT jint JNICALL
-JVM_CountStackFrames(JNIEnv *env, jobject thread);
-
-JNIEXPORT void JNICALL
-JVM_Interrupt(JNIEnv *env, jobject thread);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted);
-
-JNIEXPORT jboolean JNICALL
-JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj);
-
-JNIEXPORT void JNICALL
-JVM_DumpAllStacks(JNIEnv *env, jclass unused);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetAllThreads(JNIEnv *env, jclass dummy);
-
-JNIEXPORT void JNICALL
-JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name);
-
-/* getStackTrace() and getAllStackTraces() method */
-JNIEXPORT jobjectArray JNICALL
-JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads);
-
-/*
- * java.lang.SecurityManager
- */
-JNIEXPORT jclass JNICALL
-JVM_CurrentLoadedClass(JNIEnv *env);
-
-JNIEXPORT jobject JNICALL
-JVM_CurrentClassLoader(JNIEnv *env);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassContext(JNIEnv *env);
-
-JNIEXPORT jint JNICALL
-JVM_ClassDepth(JNIEnv *env, jstring name);
-
-JNIEXPORT jint JNICALL
-JVM_ClassLoaderDepth(JNIEnv *env);
-
-/*
- * java.lang.Package
- */
-JNIEXPORT jstring JNICALL
-JVM_GetSystemPackage(JNIEnv *env, jstring name);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetSystemPackages(JNIEnv *env);
-
-/*
- * java.lang.ref.Reference
- */
-JNIEXPORT jobject JNICALL
-JVM_GetAndClearReferencePendingList(JNIEnv *env);
-
-JNIEXPORT jboolean JNICALL
-JVM_HasReferencePendingList(JNIEnv *env);
-
-JNIEXPORT void JNICALL
-JVM_WaitForReferencePendingList(JNIEnv *env);
-
-/*
- * java.io.ObjectInputStream
- */
-JNIEXPORT jobject JNICALL
-JVM_LatestUserDefinedLoader(JNIEnv *env);
-
-/*
- * java.lang.reflect.Array
- */
-JNIEXPORT jint JNICALL
-JVM_GetArrayLength(JNIEnv *env, jobject arr);
-
-JNIEXPORT jobject JNICALL
-JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index);
-
-JNIEXPORT jvalue JNICALL
-JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode);
-
-JNIEXPORT void JNICALL
-JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val);
-
-JNIEXPORT void JNICALL
-JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v,
-                             unsigned char vCode);
-
-JNIEXPORT jobject JNICALL
-JVM_NewArray(JNIEnv *env, jclass eltClass, jint length);
-
-JNIEXPORT jobject JNICALL
-JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim);
-
-/*
- * java.lang.Class and java.lang.ClassLoader
- */
-
-#define JVM_CALLER_DEPTH -1
-
-/*
- * Returns the class in which the code invoking the native method
- * belongs.
- *
- * Note that in JDK 1.1, native methods did not create a frame.
- * In 1.2, they do. Therefore native methods like Class.forName
- * can no longer look at the current frame for the caller class.
- */
-JNIEXPORT jclass JNICALL
-JVM_GetCallerClass(JNIEnv *env, int n);
-
-/*
- * Find primitive classes
- * utf: class name
- */
-JNIEXPORT jclass JNICALL
-JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
-
-/*
- * Find a class from a boot class loader. Returns NULL if class not found.
- */
-JNIEXPORT jclass JNICALL
-JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
-
-/*
- * Find a class from a given class loader.  Throws ClassNotFoundException.
- *  name:   name of class
- *  init:   whether initialization is done
- *  loader: class loader to look up the class. This may not be the same as the caller's
- *          class loader.
- *  caller: initiating class. The initiating class may be null when a security
- *          manager is not installed.
- */
-JNIEXPORT jclass JNICALL
-JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
-                        jobject loader, jclass caller);
-
-/*
- * Find a class from a given class.
- */
-JNIEXPORT jclass JNICALL
-JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init,
-                             jclass from);
-
-/* Find a loaded class cached by the VM */
-JNIEXPORT jclass JNICALL
-JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name);
-
-/* Define a class */
-JNIEXPORT jclass JNICALL
-JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
-                jsize len, jobject pd);
-
-/* Define a class with a source (added in JDK1.5) */
-JNIEXPORT jclass JNICALL
-JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
-                          const jbyte *buf, jsize len, jobject pd,
-                          const char *source);
-
-/*
- * Module support funcions
- */
-
-/*
- * Define a module with the specified packages and bind the module to the
- * given class loader.
- *  module:       module to define
- *  is_open:      specifies if module is open (currently ignored)
- *  version:      the module version
- *  location:     the module location
- *  packages:     list of packages in the module
- *  num_packages: number of packages in the module
- */
-JNIEXPORT void JNICALL
-JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version,
-                 jstring location, const char* const* packages, jsize num_packages);
-
-/*
- * Set the boot loader's unnamed module.
- *  module: boot loader's unnamed module
- */
-JNIEXPORT void JNICALL
-JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module);
-
-/*
- * Do a qualified export of a package.
- *  from_module: module containing the package to export
- *  package:     name of the package to export
- *  to_module:   module to export the package to
- */
-JNIEXPORT void JNICALL
-JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module);
-
-/*
- * Do an export of a package to all unnamed modules.
- *  from_module: module containing the package to export
- *  package:     name of the package to export to all unnamed modules
- */
-JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package);
-
-/*
- * Do an unqualified export of a package.
- *  from_module: module containing the package to export
- *  package:     name of the package to export
- */
-JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package);
-
-/*
- * Add a module to the list of modules that a given module can read.
- *  from_module:   module requesting read access
- *  source_module: module that from_module wants to read
- */
-JNIEXPORT void JNICALL
-JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
-
-/*
- * Reflection support functions
- */
-
-JNIEXPORT jstring JNICALL
-JVM_GetClassName(JNIEnv *env, jclass cls);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsInterface(JNIEnv *env, jclass cls);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassSigners(JNIEnv *env, jclass cls);
-
-JNIEXPORT void JNICALL
-JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers);
-
-JNIEXPORT jobject JNICALL
-JVM_GetProtectionDomain(JNIEnv *env, jclass cls);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsArrayClass(JNIEnv *env, jclass cls);
-
-JNIEXPORT jboolean JNICALL
-JVM_IsPrimitiveClass(JNIEnv *env, jclass cls);
-
-JNIEXPORT jint JNICALL
-JVM_GetClassModifiers(JNIEnv *env, jclass cls);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass);
-
-JNIEXPORT jclass JNICALL
-JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass);
-
-JNIEXPORT jstring JNICALL
-JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass);
-
-/* Generics support (JDK 1.5) */
-JNIEXPORT jstring JNICALL
-JVM_GetClassSignature(JNIEnv *env, jclass cls);
-
-/* Annotations support (JDK 1.5) */
-JNIEXPORT jbyteArray JNICALL
-JVM_GetClassAnnotations(JNIEnv *env, jclass cls);
-
-/* Annotations support (JDK 1.6) */
-
-/* Type use annotations support (JDK 1.8) */
-
-JNIEXPORT jbyteArray JNICALL
-JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
-
-// field is a handle to a java.lang.reflect.Field object
-JNIEXPORT jbyteArray JNICALL
-JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field);
-
-// method is a handle to a java.lang.reflect.Method object
-JNIEXPORT jbyteArray JNICALL
-JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method);
-
-/*
- * New (JDK 1.4) reflection implementation
- */
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
-
-/* Differs from JVM_GetClassModifiers in treatment of inner classes.
-   This returns the access flags for the class as specified in the
-   class file rather than searching the InnerClasses attribute (if
-   present) to find the source-level access flags. Only the values of
-   the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
-   valid. */
-JNIEXPORT jint JNICALL
-JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
-
-/*
- * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5)
- */
-
-JNIEXPORT jobject JNICALL
-JVM_GetClassConstantPool(JNIEnv *env, jclass cls);
-
-JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize
-(JNIEnv *env, jobject obj, jobject unused);
-
-JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetNameAndTypeRefInfoAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jint JNICALL JVM_ConstantPoolGetNameAndTypeRefIndexAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jint JNICALL JVM_ConstantPoolGetClassRefIndexAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At
-(JNIEnv *env, jobject obj, jobject unused, jint index);
-
-JNIEXPORT jbyte JNICALL JVM_ConstantPoolGetTagAt
-(JNIEnv *env, jobject unused, jobject jcpool, jint index);
-
-/*
- * java.security.*
- */
-
-JNIEXPORT jobject JNICALL
-JVM_DoPrivileged(JNIEnv *env, jclass cls,
-                 jobject action, jobject context, jboolean wrapException);
-
-JNIEXPORT jobject JNICALL
-JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls);
-
-JNIEXPORT jobject JNICALL
-JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls);
-
-/*
- * Signal support, used to implement the shutdown sequence.  Every VM must
- * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts
- * (^C) and the latter for external termination (kill, system shutdown, etc.).
- * Other platform-dependent signal values may also be supported.
- */
-
-JNIEXPORT void * JNICALL
-JVM_RegisterSignal(jint sig, void *handler);
-
-JNIEXPORT jboolean JNICALL
-JVM_RaiseSignal(jint sig);
-
-JNIEXPORT jint JNICALL
-JVM_FindSignal(const char *name);
-
-/*
- * Retrieve the assertion directives for the specified class.
- */
-JNIEXPORT jboolean JNICALL
-JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls);
-
-/*
- * Retrieve the assertion directives from the VM.
- */
-JNIEXPORT jobject JNICALL
-JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused);
-
-/*
- * java.util.concurrent.atomic.AtomicLong
- */
-JNIEXPORT jboolean JNICALL
-JVM_SupportsCX8(void);
-
-/*************************************************************************
- PART 2: Support for the Verifier and Class File Format Checker
- ************************************************************************/
-/*
- * Return the class name in UTF format. The result is valid
- * until JVM_ReleaseUTf is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetClassNameUTF(JNIEnv *env, jclass cb);
-
-/*
- * Returns the constant pool types in the buffer provided by "types."
- */
-JNIEXPORT void JNICALL
-JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types);
-
-/*
- * Returns the number of Constant Pool entries.
- */
-JNIEXPORT jint JNICALL
-JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb);
-
-/*
- * Returns the number of *declared* fields or methods.
- */
-JNIEXPORT jint JNICALL
-JVM_GetClassFieldsCount(JNIEnv *env, jclass cb);
-
-JNIEXPORT jint JNICALL
-JVM_GetClassMethodsCount(JNIEnv *env, jclass cb);
-
-/*
- * Returns the CP indexes of exceptions raised by a given method.
- * Places the result in the given buffer.
- *
- * The method is identified by method_index.
- */
-JNIEXPORT void JNICALL
-JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index,
-                                unsigned short *exceptions);
-/*
- * Returns the number of exceptions raised by a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index);
-
-/*
- * Returns the byte code sequence of a given method.
- * Places the result in the given buffer.
- *
- * The method is identified by method_index.
- */
-JNIEXPORT void JNICALL
-JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index,
-                        unsigned char *code);
-
-/*
- * Returns the length of the byte code sequence of a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index);
-
-/*
- * A structure used to a capture exception table entry in a Java method.
- */
-typedef struct {
-    jint start_pc;
-    jint end_pc;
-    jint handler_pc;
-    jint catchType;
-} JVM_ExceptionTableEntryType;
-
-/*
- * Returns the exception table entry at entry_index of a given method.
- * Places the result in the given buffer.
- *
- * The method is identified by method_index.
- */
-JNIEXPORT void JNICALL
-JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index,
-                                   jint entry_index,
-                                   JVM_ExceptionTableEntryType *entry);
-
-/*
- * Returns the length of the exception table of a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the modifiers of a given field.
- * The field is identified by field_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the modifiers of a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the number of local variables of a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the number of arguments (including this pointer) of a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the maximum amount of stack (in words) used by a given method.
- * The method is identified by method_index.
- */
-JNIEXPORT jint JNICALL
-JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index);
-
-/*
- * Is a given method a constructor.
- * The method is identified by method_index.
- */
-JNIEXPORT jboolean JNICALL
-JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index);
-
-/*
- * Is the given method generated by the VM.
- * The method is identified by method_index.
- */
-JNIEXPORT jboolean JNICALL
-JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index);
-
-/*
- * Returns the name of a given method in UTF format.
- * The result remains valid until JVM_ReleaseUTF is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the signature of a given method in UTF format.
- * The result remains valid until JVM_ReleaseUTF is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the name of the field refered to at a given constant pool
- * index.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the name of the method refered to at a given constant pool
- * index.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the signature of the method refered to at a given constant pool
- * index.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the signature of the field refered to at a given constant pool
- * index.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the class name refered to at a given constant pool index.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the class name refered to at a given constant pool index.
- *
- * The constant pool entry must refer to a CONSTANT_Fieldref.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the class name refered to at a given constant pool index.
- *
- * The constant pool entry must refer to CONSTANT_Methodref or
- * CONSTANT_InterfaceMethodref.
- *
- * The result is in UTF format and remains valid until JVM_ReleaseUTF
- * is called.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- */
-JNIEXPORT const char * JNICALL
-JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index);
-
-/*
- * Returns the modifiers of a field in calledClass. The field is
- * referred to in class cb at constant pool entry index.
- *
- * The caller must treat the string as a constant and not modify it
- * in any way.
- *
- * Returns -1 if the field does not exist in calledClass.
- */
-JNIEXPORT jint JNICALL
-JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
-
-/*
- * Returns the modifiers of a method in calledClass. The method is
- * referred to in class cb at constant pool entry index.
- *
- * Returns -1 if the method does not exist in calledClass.
- */
-JNIEXPORT jint JNICALL
-JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass);
-
-/*
- * Releases the UTF string obtained from the VM.
- */
-JNIEXPORT void JNICALL
-JVM_ReleaseUTF(const char *utf);
-
-/*
- * Compare if two classes are in the same package.
- */
-JNIEXPORT jboolean JNICALL
-JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2);
-
-/* Constants in class files */
-
-#define JVM_ACC_PUBLIC        0x0001  /* visible to everyone */
-#define JVM_ACC_PRIVATE       0x0002  /* visible only to the defining class */
-#define JVM_ACC_PROTECTED     0x0004  /* visible to subclasses */
-#define JVM_ACC_STATIC        0x0008  /* instance variable is static */
-#define JVM_ACC_FINAL         0x0010  /* no further subclassing, overriding */
-#define JVM_ACC_SYNCHRONIZED  0x0020  /* wrap method call in monitor lock */
-#define JVM_ACC_SUPER         0x0020  /* funky handling of invokespecial */
-#define JVM_ACC_VOLATILE      0x0040  /* can not cache in registers */
-#define JVM_ACC_BRIDGE        0x0040  /* bridge method generated by compiler */
-#define JVM_ACC_TRANSIENT     0x0080  /* not persistent */
-#define JVM_ACC_VARARGS       0x0080  /* method declared with variable number of args */
-#define JVM_ACC_NATIVE        0x0100  /* implemented in C */
-#define JVM_ACC_INTERFACE     0x0200  /* class is an interface */
-#define JVM_ACC_ABSTRACT      0x0400  /* no definition provided */
-#define JVM_ACC_STRICT        0x0800  /* strict floating point */
-#define JVM_ACC_SYNTHETIC     0x1000  /* compiler-generated class, method or field */
-#define JVM_ACC_ANNOTATION    0x2000  /* annotation type */
-#define JVM_ACC_ENUM          0x4000  /* field is declared as element of enum */
-#define JVM_ACC_MODULE        0x8000  /* module-info class file */
-
-#define JVM_ACC_PUBLIC_BIT        0
-#define JVM_ACC_PRIVATE_BIT       1
-#define JVM_ACC_PROTECTED_BIT     2
-#define JVM_ACC_STATIC_BIT        3
-#define JVM_ACC_FINAL_BIT         4
-#define JVM_ACC_SYNCHRONIZED_BIT  5
-#define JVM_ACC_SUPER_BIT         5
-#define JVM_ACC_VOLATILE_BIT      6
-#define JVM_ACC_BRIDGE_BIT        6
-#define JVM_ACC_TRANSIENT_BIT     7
-#define JVM_ACC_VARARGS_BIT       7
-#define JVM_ACC_NATIVE_BIT        8
-#define JVM_ACC_INTERFACE_BIT     9
-#define JVM_ACC_ABSTRACT_BIT      10
-#define JVM_ACC_STRICT_BIT        11
-#define JVM_ACC_SYNTHETIC_BIT     12
-#define JVM_ACC_ANNOTATION_BIT    13
-#define JVM_ACC_ENUM_BIT          14
-
-// NOTE: replicated in SA in vm/agent/sun/jvm/hotspot/utilities/ConstantTag.java
-enum {
-    JVM_CONSTANT_Utf8 = 1,
-    JVM_CONSTANT_Unicode,               /* unused */
-    JVM_CONSTANT_Integer,
-    JVM_CONSTANT_Float,
-    JVM_CONSTANT_Long,
-    JVM_CONSTANT_Double,
-    JVM_CONSTANT_Class,
-    JVM_CONSTANT_String,
-    JVM_CONSTANT_Fieldref,
-    JVM_CONSTANT_Methodref,
-    JVM_CONSTANT_InterfaceMethodref,
-    JVM_CONSTANT_NameAndType,
-    JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
-    JVM_CONSTANT_MethodType             = 16,  // JSR 292
-    //JVM_CONSTANT_(unused)             = 17,  // JSR 292 early drafts only
-    JVM_CONSTANT_InvokeDynamic          = 18,  // JSR 292
-    JVM_CONSTANT_ExternalMax            = 18   // Last tag found in classfiles
-};
-
-/* JVM_CONSTANT_MethodHandle subtypes */
-enum {
-    JVM_REF_getField                = 1,
-    JVM_REF_getStatic               = 2,
-    JVM_REF_putField                = 3,
-    JVM_REF_putStatic               = 4,
-    JVM_REF_invokeVirtual           = 5,
-    JVM_REF_invokeStatic            = 6,
-    JVM_REF_invokeSpecial           = 7,
-    JVM_REF_newInvokeSpecial        = 8,
-    JVM_REF_invokeInterface         = 9
-};
-
-/* Used in the newarray instruction. */
-
-#define JVM_T_BOOLEAN 4
-#define JVM_T_CHAR    5
-#define JVM_T_FLOAT   6
-#define JVM_T_DOUBLE  7
-#define JVM_T_BYTE    8
-#define JVM_T_SHORT   9
-#define JVM_T_INT    10
-#define JVM_T_LONG   11
-
-/* JVM method signatures */
-
-#define JVM_SIGNATURE_ARRAY             '['
-#define JVM_SIGNATURE_BYTE              'B'
-#define JVM_SIGNATURE_CHAR              'C'
-#define JVM_SIGNATURE_CLASS             'L'
-#define JVM_SIGNATURE_ENDCLASS          ';'
-#define JVM_SIGNATURE_ENUM              'E'
-#define JVM_SIGNATURE_FLOAT             'F'
-#define JVM_SIGNATURE_DOUBLE            'D'
-#define JVM_SIGNATURE_FUNC              '('
-#define JVM_SIGNATURE_ENDFUNC           ')'
-#define JVM_SIGNATURE_INT               'I'
-#define JVM_SIGNATURE_LONG              'J'
-#define JVM_SIGNATURE_SHORT             'S'
-#define JVM_SIGNATURE_VOID              'V'
-#define JVM_SIGNATURE_BOOLEAN           'Z'
-
-/*
- * A function defined by the byte-code verifier and called by the VM.
- * This is not a function implemented in the VM.
- *
- * Returns JNI_FALSE if verification fails. A detailed error message
- * will be places in msg_buf, whose length is specified by buf_len.
- */
-typedef jboolean (*verifier_fn_t)(JNIEnv *env,
-                                  jclass cb,
-                                  char * msg_buf,
-                                  jint buf_len);
-
-
-/*
- * Support for a VM-independent class format checker.
- */
-typedef struct {
-    unsigned long code;    /* byte code */
-    unsigned long excs;    /* exceptions */
-    unsigned long etab;    /* catch table */
-    unsigned long lnum;    /* line number */
-    unsigned long lvar;    /* local vars */
-} method_size_info;
-
-typedef struct {
-    unsigned int constants;    /* constant pool */
-    unsigned int fields;
-    unsigned int methods;
-    unsigned int interfaces;
-    unsigned int fields2;      /* number of static 2-word fields */
-    unsigned int innerclasses; /* # of records in InnerClasses attr */
-
-    method_size_info clinit;   /* memory used in clinit */
-    method_size_info main;     /* used everywhere else */
-} class_size_info;
-
-/*
- * Functions defined in libjava.so to perform string conversions.
- *
- */
-
-typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
-
-typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
-
-/* This is the function defined in libjava.so that performs class
- * format checks. This functions fills in size information about
- * the class file and returns:
- *
- *   0: good
- *  -1: out of memory
- *  -2: bad format
- *  -3: unsupported version
- *  -4: bad class name
- */
-
-typedef jint (*check_format_fn_t)(char *class_name,
-                                  unsigned char *data,
-                                  unsigned int data_size,
-                                  class_size_info *class_size,
-                                  char *message_buffer,
-                                  jint buffer_length,
-                                  jboolean measure_only,
-                                  jboolean check_relaxed);
-
-#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
-                                        JVM_ACC_FINAL | \
-                                        JVM_ACC_SUPER | \
-                                        JVM_ACC_INTERFACE | \
-                                        JVM_ACC_ABSTRACT | \
-                                        JVM_ACC_ANNOTATION | \
-                                        JVM_ACC_ENUM | \
-                                        JVM_ACC_SYNTHETIC)
-
-#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \
-                                        JVM_ACC_PRIVATE | \
-                                        JVM_ACC_PROTECTED | \
-                                        JVM_ACC_STATIC | \
-                                        JVM_ACC_FINAL | \
-                                        JVM_ACC_VOLATILE | \
-                                        JVM_ACC_TRANSIENT | \
-                                        JVM_ACC_ENUM | \
-                                        JVM_ACC_SYNTHETIC)
-
-#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \
-                                         JVM_ACC_PRIVATE | \
-                                         JVM_ACC_PROTECTED | \
-                                         JVM_ACC_STATIC | \
-                                         JVM_ACC_FINAL | \
-                                         JVM_ACC_SYNCHRONIZED | \
-                                         JVM_ACC_BRIDGE | \
-                                         JVM_ACC_VARARGS | \
-                                         JVM_ACC_NATIVE | \
-                                         JVM_ACC_ABSTRACT | \
-                                         JVM_ACC_STRICT | \
-                                         JVM_ACC_SYNTHETIC)
-
-/*
- * This is the function defined in libjava.so to perform path
- * canonicalization. VM call this function before opening jar files
- * to load system classes.
- *
- */
-
-typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len);
-
-/*************************************************************************
- PART 3: I/O and Network Support
- ************************************************************************/
-
-/*
- * Convert a pathname into native format.  This function does syntactic
- * cleanup, such as removing redundant separator characters.  It modifies
- * the given pathname string in place.
- */
-JNIEXPORT char * JNICALL
-JVM_NativePath(char *);
-
-/*
- * The standard printing functions supported by the Java VM. (Should they
- * be renamed to JVM_* in the future?
- */
-
-/* jio_snprintf() and jio_vsnprintf() behave like snprintf(3) and vsnprintf(3),
- *  respectively, with the following differences:
- * - The string written to str is always zero-terminated, also in case of
- *   truncation (count is too small to hold the result string), unless count
- *   is 0. In case of truncation count-1 characters are written and '\0'
- *   appendend.
- * - If count is too small to hold the whole string, -1 is returned across
- *   all platforms. */
-JNIEXPORT int
-jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
-
-JNIEXPORT int
-jio_snprintf(char *str, size_t count, const char *fmt, ...);
-
-JNIEXPORT int
-jio_fprintf(FILE *, const char *fmt, ...);
-
-JNIEXPORT int
-jio_vfprintf(FILE *, const char *fmt, va_list args);
-
-
-JNIEXPORT void * JNICALL
-JVM_RawMonitorCreate(void);
-
-JNIEXPORT void JNICALL
-JVM_RawMonitorDestroy(void *mon);
-
-JNIEXPORT jint JNICALL
-JVM_RawMonitorEnter(void *mon);
-
-JNIEXPORT void JNICALL
-JVM_RawMonitorExit(void *mon);
-
-/*
- * java.lang.reflect.Method
- */
-JNIEXPORT jobject JNICALL
-JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0);
-
-/*
- * java.lang.reflect.Constructor
- */
-JNIEXPORT jobject JNICALL
-JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
-
-/*
- * java.lang.management support
- */
-JNIEXPORT void* JNICALL
-JVM_GetManagement(jint version);
-
-/*
- * com.sun.tools.attach.VirtualMachine support
- *
- * Initialize the agent properties with the properties maintained in the VM.
- */
-JNIEXPORT jobject JNICALL
-JVM_InitAgentProperties(JNIEnv *env, jobject agent_props);
-
-JNIEXPORT jstring JNICALL
-JVM_GetTemporaryDirectory(JNIEnv *env);
-
-/* Generics reflection support.
- *
- * Returns information about the given class's EnclosingMethod
- * attribute, if present, or null if the class had no enclosing
- * method.
- *
- * If non-null, the returned array contains three elements. Element 0
- * is the java.lang.Class of which the enclosing method is a member,
- * and elements 1 and 2 are the java.lang.Strings for the enclosing
- * method's name and descriptor, respectively.
- */
-JNIEXPORT jobjectArray JNICALL
-JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass);
-
-/* =========================================================================
- * The following defines a private JVM interface that the JDK can query
- * for the JVM version and capabilities.  sun.misc.Version defines
- * the methods for getting the VM version and its capabilities.
- *
- * When a new bit is added, the following should be updated to provide
- * access to the new capability:
- *    HS:   JVM_GetVersionInfo and Abstract_VM_Version class
- *    SDK:  Version class
- *
- * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for
- * JVM to query for the JDK version and capabilities.
- *
- * When a new bit is added, the following should be updated to provide
- * access to the new capability:
- *    HS:   JDK_Version class
- *    SDK:  JDK_GetVersionInfo0
- *
- * ==========================================================================
- */
-typedef struct {
-    unsigned int jvm_version; /* Encoded $VNUM as defined by JEP-223 */
-    unsigned int patch_version : 8; /* JEP-223 patch version */
-    unsigned int reserved3 : 8;
-    unsigned int reserved1 : 16;
-    unsigned int reserved2;
-
-    /* The following bits represents JVM supports that JDK has dependency on.
-     * JDK can use these bits to determine which JVM version
-     * and support it has to maintain runtime compatibility.
-     *
-     * When a new bit is added in a minor or update release, make sure
-     * the new bit is also added in the main/baseline.
-     */
-    unsigned int is_attachable : 1;
-    unsigned int : 31;
-    unsigned int : 32;
-    unsigned int : 32;
-} jvm_version_info;
-
-#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
-#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
-#define JVM_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8)
-#define JVM_VERSION_BUILD(version) ((version & 0x000000FF))
-
-JNIEXPORT void JNICALL
-JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size);
-
-typedef struct {
-    unsigned int jdk_version; /* Encoded $VNUM as defined by JEP-223 */
-    unsigned int patch_version : 8; /* JEP-223 patch version */
-    unsigned int reserved3 : 8;
-    unsigned int reserved1 : 16;
-    unsigned int reserved2;
-
-    /* The following bits represents new JDK supports that VM has dependency on.
-     * VM implementation can use these bits to determine which JDK version
-     * and support it has to maintain runtime compatibility.
-     *
-     * When a new bit is added in a minor or update release, make sure
-     * the new bit is also added in the main/baseline.
-     */
-    unsigned int thread_park_blocker : 1;
-    unsigned int post_vm_init_hook_enabled : 1;
-    unsigned int pending_list_uses_discovered_field : 1;
-    unsigned int : 29;
-    unsigned int : 32;
-    unsigned int : 32;
-} jdk_version_info;
-
-#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
-#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
-#define JDK_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8)
-#define JDK_VERSION_BUILD(version) ((version & 0x000000FF))
-
-/*
- * This is the function JDK_GetVersionInfo0 defined in libjava.so
- * that is dynamically looked up by JVM.
- */
-typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size);
-
-/*
- * This structure is used by the launcher to get the default thread
- * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a
- * version of 1.1.  As it is not supported otherwise, it has been removed
- * from jni.h
- */
-typedef struct JDK1_1InitArgs {
-    jint version;
-
-    char **properties;
-    jint checkSource;
-    jint nativeStackSize;
-    jint javaStackSize;
-    jint minHeapSize;
-    jint maxHeapSize;
-    jint verifyMode;
-    char *classpath;
-
-    jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args);
-    void (JNICALL *exit)(jint code);
-    void (JNICALL *abort)(void);
-
-    jint enableClassGC;
-    jint enableVerboseGC;
-    jint disableAsyncGC;
-    jint verbose;
-    jboolean debugging;
-    jint debugPort;
-} JDK1_1InitArgs;
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* !_JAVASOFT_JVM_H_ */
-
-#endif // SHARE_VM_PRIMS_JVM_H
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -741,7 +741,7 @@
 // Save JNI local handles for any objects that this frame owns.
 jvmtiError
 JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
-                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) {
+                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {
   jvmtiError err = JVMTI_ERROR_NONE;
   ResourceMark rm;
 
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -523,7 +523,7 @@
 //
 
 // Constructor for non-object getter
-VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)
+VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type)
   : _thread(thread)
   , _calling_thread(NULL)
   , _depth(depth)
@@ -536,7 +536,7 @@
 }
 
 // Constructor for object or non-object setter
-VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)
+VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value)
   : _thread(thread)
   , _calling_thread(NULL)
   , _depth(depth)
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -2006,7 +2006,7 @@
                                                              jlong thread_tag,
                                                              jint depth,
                                                              jmethodID method,
-                                                             jint slot,
+                                                             int slot,
                                                              oop obj) {
   assert(ServiceUtil::visible_oop(obj), "checking");
 
--- a/src/hotspot/share/prims/methodHandles.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/methodHandles.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -27,7 +27,6 @@
 
 #include "classfile/javaClasses.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "prims/jvm.h"
 #include "runtime/frame.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/interfaceSupport.hpp"
--- a/src/hotspot/share/prims/nativeLookup.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/nativeLookup.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -293,10 +293,12 @@
   char* critical_name = critical_jni_name(method);
 
   // Compute argument size
-  int args_size = 1                             // JNIEnv
-                + (method->is_static() ? 1 : 0) // class for static methods
-                + method->size_of_parameters(); // actual parameters
-
+  int args_size = method->size_of_parameters();
+  for (SignatureStream ss(signature); !ss.at_return_type(); ss.next()) {
+    if (ss.is_array()) {
+      args_size += T_INT_size; // array length parameter
+    }
+  }
 
   // 1) Try JNI short style
   entry = lookup_critical_style(method, critical_name, "",        args_size, true);
--- a/src/hotspot/share/prims/perf.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/perf.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,11 +24,11 @@
 
 #include "precompiled.hpp"
 #include "jni.h"
+#include "jvm.h"
 #include "classfile/vmSymbols.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/perfData.hpp"
 #include "runtime/perfMemory.hpp"
--- a/src/hotspot/share/prims/stackwalk.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/stackwalk.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -272,9 +272,8 @@
   return array_h;
 }
 
-// Fill StackFrameInfo with declaringClass and bci and initialize memberName
+// Fill StackFrameInfo with bci and initialize memberName
 void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) {
-  java_lang_StackFrameInfo::set_declaringClass(stackFrame(), method->method_holder()->java_mirror());
   java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), THREAD);
 }
 
--- a/src/hotspot/share/prims/unsafe.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/unsafe.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "jni.h"
+#include "jvm.h"
 #include "classfile/classFileStream.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "memory/allocation.inline.hpp"
@@ -31,7 +32,6 @@
 #include "oops/fieldStreams.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/unsafe.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
--- a/src/hotspot/share/prims/whitebox.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/prims/whitebox.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1715,6 +1715,10 @@
   }
 WB_END
 
+WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
+  return MetaspaceShared::open_archive_heap_region_mapped();
+WB_END
+
 WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
 #if INCLUDE_CDS
   return true;
@@ -2031,6 +2035,7 @@
   {CC"isSharedClass",      CC"(Ljava/lang/Class;)Z",  (void*)&WB_IsSharedClass },
   {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
   {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
+  {CC"areOpenArchiveHeapObjectsMapped",   CC"()Z",    (void*)&WB_AreOpenArchiveHeapObjectsMapped},
   {CC"isCDSIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsCDSIncludedInVmBuild },
   {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
   {CC"addCompilerDirective",    CC"(Ljava/lang/String;)I",
--- a/src/hotspot/share/runtime/arguments.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/moduleEntry.hpp"
@@ -39,7 +40,6 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/arguments_ext.hpp"
@@ -382,6 +382,8 @@
   { "MaxRAMFraction",               JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
   { "MinRAMFraction",               JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
   { "InitialRAMFraction",           JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
+  { "UseMembar",                    JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+  { "IgnoreUnverifiableClassesDuringDump", JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
 
   // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
   { "DefaultMaxRAMFraction",        JDK_Version::jdk(8),  JDK_Version::undefined(), JDK_Version::undefined() },
@@ -395,6 +397,10 @@
   { "MinSleepInterval",              JDK_Version::jdk(9),      JDK_Version::jdk(10), JDK_Version::jdk(11) },
   { "PermSize",                      JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
   { "MaxPermSize",                   JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
+  { "SharedReadWriteSize",           JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedReadOnlySize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedMiscDataSize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+  { "SharedMiscCodeSize",            JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -1859,7 +1865,7 @@
 #endif
   select_gc();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Shared spaces work fine with other GCs but causes bytecode rewriting
   // to be disabled, which hurts interpreter performance and decreases
   // server performance.  When -server is specified, keep the default off
@@ -2088,9 +2094,10 @@
   // respecting the maximum and minimum sizes of the heap.
   if (FLAG_IS_DEFAULT(MaxHeapSize)) {
     julong reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
-    if (phys_mem <= (julong)((MaxHeapSize * MinRAMPercentage) / 100)) {
+    const julong reasonable_min = (julong)((phys_mem * MinRAMPercentage) / 100);
+    if (reasonable_min < MaxHeapSize) {
       // Small physical memory, so use a minimum fraction of it for the heap
-      reasonable_max = (julong)((phys_mem * MinRAMPercentage) / 100);
+      reasonable_max = reasonable_min;
     } else {
       // Not-small physical memory, so require a heap at least
       // as large as MaxHeapSize
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -145,7 +145,9 @@
   return info;
 }
 
-static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
+// After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL,
+// AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization).
+static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
   markOop mark = obj->mark();
   if (!mark->has_bias_pattern()) {
     if (log_is_enabled(Info, biasedlocking)) {
@@ -298,6 +300,11 @@
     }
   }
 
+  // If requested, return information on which thread held the bias
+  if (biased_locker != NULL) {
+    *biased_locker = biased_thread;
+  }
+
   return BiasedLocking::BIAS_REVOKED;
 }
 
@@ -418,7 +425,7 @@
 
     // At this point we're done. All we have to do is potentially
     // adjust the header of the given object to revoke its bias.
-    revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);
+    revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread, NULL);
   } else {
     if (log_is_enabled(Info, biasedlocking)) {
       ResourceMark rm;
@@ -440,14 +447,14 @@
         oop owner = mon_info->owner();
         markOop mark = owner->mark();
         if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
-          revoke_bias(owner, false, true, requesting_thread);
+          revoke_bias(owner, false, true, requesting_thread, NULL);
         }
       }
     }
 
     // Must force the bias of the passed object to be forcibly revoked
     // as well to ensure guarantees to callers
-    revoke_bias(o, false, true, requesting_thread);
+    revoke_bias(o, false, true, requesting_thread, NULL);
   }
 
   log_info(biasedlocking)("* Ending bulk revocation");
@@ -486,19 +493,22 @@
   GrowableArray<Handle>* _objs;
   JavaThread* _requesting_thread;
   BiasedLocking::Condition _status_code;
+  traceid _biased_locker_id;
 
 public:
   VM_RevokeBias(Handle* obj, JavaThread* requesting_thread)
     : _obj(obj)
     , _objs(NULL)
     , _requesting_thread(requesting_thread)
-    , _status_code(BiasedLocking::NOT_BIASED) {}
+    , _status_code(BiasedLocking::NOT_BIASED)
+    , _biased_locker_id(0) {}
 
   VM_RevokeBias(GrowableArray<Handle>* objs, JavaThread* requesting_thread)
     : _obj(NULL)
     , _objs(objs)
     , _requesting_thread(requesting_thread)
-    , _status_code(BiasedLocking::NOT_BIASED) {}
+    , _status_code(BiasedLocking::NOT_BIASED)
+    , _biased_locker_id(0) {}
 
   virtual VMOp_Type type() const { return VMOp_RevokeBias; }
 
@@ -525,7 +535,11 @@
   virtual void doit() {
     if (_obj != NULL) {
       log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
-      _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
+      JavaThread* biased_locker = NULL;
+      _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread, &biased_locker);
+      if (biased_locker != NULL) {
+        _biased_locker_id = THREAD_TRACE_ID(biased_locker);
+      }
       clean_up_cached_monitor_info();
       return;
     } else {
@@ -537,6 +551,10 @@
   BiasedLocking::Condition status_code() const {
     return _status_code;
   }
+
+  traceid biased_locker() const {
+    return _biased_locker_id;
+  }
 };
 
 
@@ -645,7 +663,7 @@
       ResourceMark rm;
       log_info(biasedlocking)("Revoking bias by walking my own stack:");
       EventBiasedLockSelfRevocation event;
-      BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
+      BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
       ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
       assert(cond == BIAS_REVOKED, "why not?");
       if (event.should_commit()) {
@@ -661,6 +679,7 @@
         event.set_lockClass(k);
         // Subtract 1 to match the id of events committed inside the safepoint
         event.set_safepointId(SafepointSynchronize::safepoint_counter() - 1);
+        event.set_previousOwner(revoke.biased_locker());
         event.commit();
       }
       return revoke.status_code();
@@ -700,7 +719,7 @@
   oop obj = h_obj();
   HeuristicsResult heuristics = update_heuristics(obj, false);
   if (heuristics == HR_SINGLE_REVOKE) {
-    revoke_bias(obj, false, false, NULL);
+    revoke_bias(obj, false, false, NULL, NULL);
   } else if ((heuristics == HR_BULK_REBIAS) ||
              (heuristics == HR_BULK_REVOKE)) {
     bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
@@ -716,7 +735,7 @@
     oop obj = (objs->at(i))();
     HeuristicsResult heuristics = update_heuristics(obj, false);
     if (heuristics == HR_SINGLE_REVOKE) {
-      revoke_bias(obj, false, false, NULL);
+      revoke_bias(obj, false, false, NULL, NULL);
     } else if ((heuristics == HR_BULK_REBIAS) ||
                (heuristics == HR_BULK_REVOKE)) {
       bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
--- a/src/hotspot/share/runtime/commandLineFlagRangeList.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/commandLineFlagRangeList.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,10 +23,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "gc/shared/referenceProcessor.hpp"
-#include "prims/jvm.h"
 #include "oops/markOop.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/commandLineFlagConstraintList.hpp"
--- a/src/hotspot/share/runtime/deoptimization.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
 #include "code/debugInfoRec.hpp"
@@ -40,7 +41,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "oops/verifyOopClosure.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/compilationPolicy.hpp"
@@ -192,7 +192,7 @@
 
   bool realloc_failures = false;
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Reallocate the non-escaping objects and restore their fields. Then
   // relock objects if synchronization on them was eliminated.
 #ifndef INCLUDE_JVMCI
@@ -282,7 +282,7 @@
     }
   }
 #endif // INCLUDE_JVMCI
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   ScopeDesc* trap_scope = chunk->at(0)->scope();
   Handle exceptionObject;
@@ -303,7 +303,7 @@
   NoSafepointVerifier no_safepoint;
 
   vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures);
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   if (realloc_failures) {
     pop_frames_failed_reallocs(thread, array);
   }
@@ -792,7 +792,7 @@
 Deoptimization::DeoptAction Deoptimization::_unloaded_action
   = Deoptimization::Action_reinterpret;
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) {
   Handle pending_exception(THREAD, thread->pending_exception());
   const char* exception_file = thread->exception_file();
@@ -1151,7 +1151,7 @@
   }
 }
 #endif
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
   Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, p2i(fr.pc()), p2i(fr.sp()));
@@ -1211,7 +1211,7 @@
   return array;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) {
   // Reallocation of some scalar replaced objects failed. Record
   // that we need to pop all the interpreter frames for the
@@ -1443,7 +1443,7 @@
   return mdo;
 }
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) {
   // in case of an unresolved klass entry, load the class.
   if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -1674,19 +1674,9 @@
         tty->print(" compiler=%s compile_id=%d", nm->compiler_name(), nm->compile_id());
 #if INCLUDE_JVMCI
         if (nm->is_nmethod()) {
-          oop installedCode = nm->as_nmethod()->jvmci_installed_code();
-          if (installedCode != NULL) {
-            oop installedCodeName = NULL;
-            if (installedCode->is_a(InstalledCode::klass())) {
-              installedCodeName = InstalledCode::name(installedCode);
-            }
-            if (installedCodeName != NULL) {
-              tty->print(" (JVMCI: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName));
-            } else {
-              tty->print(" (JVMCI: installed code has no name) ");
-            }
-          } else if (nm->is_compiled_by_jvmci()) {
-            tty->print(" (JVMCI: no installed code) ");
+          char* installed_code_name = nm->as_nmethod()->jvmci_installed_code_name(buf, sizeof(buf));
+          if (installed_code_name != NULL) {
+            tty->print(" (JVMCI: installed code name=%s) ", installed_code_name);
           }
         }
 #endif
@@ -2360,7 +2350,7 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2 || INCLUDE_JVMCI
+#else // COMPILER2_OR_JVMCI
 
 
 // Stubs for C1 only system.
@@ -2396,4 +2386,4 @@
   return buf;
 }
 
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
--- a/src/hotspot/share/runtime/deoptimization.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/deoptimization.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -151,7 +151,7 @@
   // executing in a particular CodeBlob if UseBiasedLocking is enabled
   static void revoke_biases_of_monitors(CodeBlob* cb);
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 JVMCI_ONLY(public:)
 
   // Support for restoring non-escaping objects
@@ -162,7 +162,7 @@
   static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures);
   static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array);
   NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures);)
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
   public:
   static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures);
--- a/src/hotspot/share/runtime/frame.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/frame.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1148,7 +1148,7 @@
       // make sure we have the right receiver type
     }
   }
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "must be empty before verify");
 #endif
   oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
--- a/src/hotspot/share/runtime/globals.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/globals.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
--- a/src/hotspot/share/runtime/globals.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/globals.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -99,11 +99,11 @@
 #define CI_COMPILER_COUNT 0
 #else
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
 #define CI_COMPILER_COUNT 2
 #else
 #define CI_COMPILER_COUNT 1
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
 
 #endif // no compilers
 
@@ -1144,8 +1144,8 @@
   notproduct(bool, PrintSystemDictionaryAtExit, false,                      \
           "Print the system dictionary at exit")                            \
                                                                             \
-  experimental(intx, PredictedLoadedClassCount, 0,                          \
-          "Experimental: Tune loaded class cache starting size")            \
+  diagnostic(bool, DynamicallyResizeSystemDictionaries, true,               \
+          "Dynamically resize system dictionaries as needed")               \
                                                                             \
   diagnostic(bool, UnsyncloadClass, false,                                  \
           "Unstable: VM calls loadClass unsynchronized. Custom "            \
@@ -3901,18 +3901,6 @@
           "If PrintSharedArchiveAndExit is true, also print the shared "    \
           "dictionary")                                                     \
                                                                             \
-  product(size_t, SharedReadWriteSize, 0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedReadOnlySize, 0,                                    \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedMiscDataSize,  0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
-  product(size_t, SharedMiscCodeSize,  0,                                   \
-          "Deprecated")                                                     \
-                                                                            \
   product(size_t, SharedBaseAddress, LP64_ONLY(32*G)                        \
           NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)),                           \
           "Address to allocate shared memory region for class data")        \
@@ -3922,7 +3910,7 @@
           "Average number of symbols per bucket in shared table")           \
           range(2, 246)                                                     \
                                                                             \
-  diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false,              \
+  diagnostic(bool, IgnoreUnverifiableClassesDuringDump, true,              \
           "Do not quit -Xshare:dump even if we encounter unverifiable "     \
           "classes. Just exclude them from the shared dictionary.")         \
                                                                             \
--- a/src/hotspot/share/runtime/handles.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/handles.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -99,7 +99,7 @@
   while (bottom < top) {
     // This test can be moved up but for now check every oop.
 
-    assert(oopDesc::is_oop(*bottom), "handle should point to oop");
+    assert(oopDesc::is_oop(*bottom, true), "handle should point to oop");
 
     f->do_oop(bottom++);
   }
--- a/src/hotspot/share/runtime/init.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/init.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -60,7 +60,11 @@
 jint universe_init();          // depends on codeCache_init and stubRoutines_init
 #if INCLUDE_ALL_GCS
 // depends on universe_init, must be before interpreter_init (currently only on SPARC)
+#ifndef ZERO
 void g1_barrier_stubs_init() NOT_SPARC({});
+#else
+void g1_barrier_stubs_init() {};
+#endif
 #endif
 void interpreter_init();       // before any methods loaded
 void invocationCounter_init(); // before any methods loaded
--- a/src/hotspot/share/runtime/interfaceSupport.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/interfaceSupport.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -47,7 +47,7 @@
 Histogram* RuntimeHistogram;
 
 RuntimeHistogramElement::RuntimeHistogramElement(const char* elementName) {
-  static volatile jint RuntimeHistogram_lock = 0;
+  static volatile int RuntimeHistogram_lock = 0;
   _name = elementName;
   uintx count = 0;
 
--- a/src/hotspot/share/runtime/java.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/java.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "aot/aotLoader.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/stringTable.hpp"
@@ -49,7 +50,6 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/biasedLocking.hpp"
--- a/src/hotspot/share/runtime/jniHandles.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/jniHandles.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -30,6 +30,7 @@
 #include "runtime/jniHandles.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/thread.inline.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/align.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
@@ -126,6 +127,11 @@
 template oop JNIHandles::resolve_jweak<true>(jweak);
 template oop JNIHandles::resolve_jweak<false>(jweak);
 
+bool JNIHandles::is_global_weak_cleared(jweak handle) {
+  assert(is_jweak(handle), "not a weak handle");
+  return guard_value<false>(jweak_ref(handle)) == NULL;
+}
+
 void JNIHandles::destroy_global(jobject handle) {
   if (handle != NULL) {
     assert(is_global_handle(handle), "Invalid delete of global JNI handle");
--- a/src/hotspot/share/runtime/jniHandles.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/jniHandles.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -82,6 +82,7 @@
   // Weak global handles
   static jobject make_weak_global(Handle obj);
   static void destroy_weak_global(jobject handle);
+  static bool is_global_weak_cleared(jweak handle); // Test jweak without resolution
 
   // Sentinel marking deleted handles in block. Note that we cannot store NULL as
   // the sentinel, since clearing weak global JNI refs are done by storing NULL in
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -116,7 +116,6 @@
 Monitor* SecondaryFreeList_lock       = NULL;
 Mutex*   OldSets_lock                 = NULL;
 Monitor* RootRegionScan_lock          = NULL;
-Mutex*   MMUTracker_lock              = NULL;
 
 Monitor* GCTaskManager_lock           = NULL;
 
@@ -130,7 +129,6 @@
 Monitor* JfrMsg_lock                  = NULL;
 Mutex*   JfrBuffer_lock               = NULL;
 Mutex*   JfrStream_lock               = NULL;
-Mutex*   JfrThreadGroups_lock         = NULL;
 #endif
 
 #ifndef SUPPORTS_NATIVE_CX8
@@ -193,7 +191,6 @@
     def(SecondaryFreeList_lock     , PaddedMonitor, leaf     ,   true,  Monitor::_safepoint_check_never);
     def(OldSets_lock               , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
     def(RootRegionScan_lock        , PaddedMonitor, leaf     ,   true,  Monitor::_safepoint_check_never);
-    def(MMUTracker_lock            , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
 
     def(StringDedupQueue_lock      , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
     def(StringDedupTable_lock      , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
@@ -282,7 +279,6 @@
 #if INCLUDE_TRACE
   def(JfrMsg_lock                  , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_always);
   def(JfrBuffer_lock               , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
-  def(JfrThreadGroups_lock         , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);
   def(JfrStream_lock               , PaddedMutex  , leaf+1,      true,  Monitor::_safepoint_check_never);      // ensure to rank lower than 'safepoint'
   def(JfrStacktrace_lock           , PaddedMutex  , special,     true,  Monitor::_safepoint_check_sometimes);
 #endif
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -117,8 +117,6 @@
 extern Monitor* SecondaryFreeList_lock;          // protects the secondary free region list
 extern Mutex*   OldSets_lock;                    // protects the old region sets
 extern Monitor* RootRegionScan_lock;             // used to notify that the CM threads have finished scanning the IM snapshot regions
-extern Mutex*   MMUTracker_lock;                 // protects the MMU
-                                                 // tracker data structures
 
 extern Mutex*   Management_lock;                 // a lock used to serialize JVM management
 extern Monitor* Service_lock;                    // a lock used for service thread operation
@@ -130,7 +128,6 @@
 extern Monitor* JfrMsg_lock;                     // protects JFR messaging
 extern Mutex*   JfrBuffer_lock;                  // protects JFR buffer operations
 extern Mutex*   JfrStream_lock;                  // protects JFR stream access
-extern Mutex*   JfrThreadGroups_lock;            // protects JFR access to Thread Groups
 #endif
 
 #ifndef SUPPORTS_NATIVE_CX8
--- a/src/hotspot/share/runtime/os.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/os.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
@@ -41,7 +42,6 @@
 #endif
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "prims/privilegedStack.hpp"
 #include "runtime/arguments.hpp"
--- a/src/hotspot/share/runtime/os.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/os.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_RUNTIME_OS_HPP
 #define SHARE_VM_RUNTIME_OS_HPP
 
+#include "jvm.h"
 #include "jvmtifiles/jvmti.h"
-#include "prims/jvm.h"
 #include "runtime/extendedPC.hpp"
 #include "runtime/handles.hpp"
 #include "utilities/macros.hpp"
--- a/src/hotspot/share/runtime/perfData.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/perfData.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,10 +23,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutex.hpp"
@@ -420,11 +420,11 @@
 
 PerfStringVariable* PerfDataManager::create_string_variable(CounterNS ns,
                                                             const char* name,
-                                                            jint max_length,
+                                                            int max_length,
                                                             const char* s,
                                                             TRAPS) {
 
-  if (max_length == 0 && s != NULL) max_length = (jint)strlen(s);
+  if (max_length == 0 && s != NULL) max_length = (int)strlen(s);
 
   assert(max_length != 0, "PerfStringVariable with length 0");
 
--- a/src/hotspot/share/runtime/perfMemory.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/perfMemory.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutex.hpp"
@@ -51,7 +51,7 @@
 char*                    PerfMemory::_end = NULL;
 char*                    PerfMemory::_top = NULL;
 size_t                   PerfMemory::_capacity = 0;
-jint                     PerfMemory::_initialized = false;
+int                      PerfMemory::_initialized = false;
 PerfDataPrologue*        PerfMemory::_prologue = NULL;
 bool                     PerfMemory::_destroyed = false;
 
--- a/src/hotspot/share/runtime/perfMemory.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/perfMemory.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -120,7 +120,7 @@
     static char*  _top;
     static size_t _capacity;
     static PerfDataPrologue*  _prologue;
-    static jint   _initialized;
+    static int    _initialized;
     static bool   _destroyed;
 
     static void create_memory_region(size_t sizep);
--- a/src/hotspot/share/runtime/reflection.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/reflection.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
@@ -38,7 +39,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/rframe.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/rframe.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -155,7 +155,7 @@
 
 void RFrame::print(const char* kind) {
 #ifndef PRODUCT
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   int cnt = top_method()->interpreter_invocation_count();
 #else
   int cnt = top_method()->invocation_count();
--- a/src/hotspot/share/runtime/safepoint.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/safepoint.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -618,6 +619,14 @@
       ClassLoaderDataGraph::purge_if_needed();
       event_safepoint_cleanup_task_commit(event, name);
     }
+
+    if (!_subtasks.is_task_claimed(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) {
+      const char* name = "resizing system dictionaries";
+      EventSafepointCleanupTask event;
+      TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
+      ClassLoaderDataGraph::resize_if_needed();
+      event_safepoint_cleanup_task_commit(event, name);
+    }
     _subtasks.all_tasks_completed(_num_workers);
   }
 };
--- a/src/hotspot/share/runtime/safepoint.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/safepoint.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -83,6 +83,7 @@
     SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH,
     SAFEPOINT_CLEANUP_STRING_TABLE_REHASH,
     SAFEPOINT_CLEANUP_CLD_PURGE,
+    SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE,
     // Leave this one last.
     SAFEPOINT_CLEANUP_NUM_TASKS
   };
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "aot/aotLoader.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -45,7 +46,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"
-#include "prims/jvm.h"
 #include "prims/jvmtiExport.hpp"
 #include "prims/methodHandles.hpp"
 #include "prims/nativeLookup.hpp"
@@ -102,13 +102,13 @@
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),        "resolve_static_call");
   _resolve_static_call_entry           = _resolve_static_call_blob->entry_point();
 
-#if defined(COMPILER2) || INCLUDE_JVMCI
+#if COMPILER2_OR_JVMCI
   // Vectors are generated only by C2 and JVMCI.
   bool support_wide = is_wide_vector(MaxVectorSize);
   if (support_wide) {
     _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
   }
-#endif // COMPILER2 || INCLUDE_JVMCI
+#endif // COMPILER2_OR_JVMCI
   _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
   _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
 
--- a/src/hotspot/share/runtime/stackValue.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/stackValue.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -191,12 +191,12 @@
 void StackValue::print_on(outputStream* st) const {
   switch(_type) {
     case T_INT:
-      st->print("%d (int) %f (float) %x (hex)",  *(int *)&_i, *(float *)&_i,  *(int *)&_i);
+      st->print("%d (int) %f (float) %x (hex)",  *(int *)&_integer_value, *(float *)&_integer_value,  *(int *)&_integer_value);
       break;
 
     case T_OBJECT:
-     _o()->print_value_on(st);
-      st->print(" <" INTPTR_FORMAT ">", p2i((address)_o()));
+      _handle_value()->print_value_on(st);
+      st->print(" <" INTPTR_FORMAT ">", p2i((address)_handle_value()));
      break;
 
     case T_CONFLICT:
--- a/src/hotspot/share/runtime/stackValue.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/stackValue.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,63 +31,63 @@
 class StackValue : public ResourceObj {
  private:
   BasicType _type;
-  intptr_t  _i; // Blank java stack slot value
-  Handle    _o; // Java stack slot value interpreted as a Handle
+  intptr_t  _integer_value; // Blank java stack slot value
+  Handle    _handle_value;  // Java stack slot value interpreted as a Handle
  public:
 
   StackValue(intptr_t value) {
-    _type  = T_INT;
-    _i     = value;
+    _type              = T_INT;
+    _integer_value     = value;
   }
 
   StackValue(Handle value, intptr_t scalar_replaced = 0) {
-    _type    = T_OBJECT;
-    _i       = scalar_replaced;
-    _o       = value;
-    assert(_i == 0 || _o.is_null(), "not null object should not be marked as scalar replaced");
+    _type                = T_OBJECT;
+    _integer_value       = scalar_replaced;
+    _handle_value        = value;
+    assert(_integer_value == 0 ||  _handle_value.is_null(), "not null object should not be marked as scalar replaced");
   }
 
   StackValue() {
-    _type   = T_CONFLICT;
-    _i      = 0;
+    _type           = T_CONFLICT;
+    _integer_value  = 0;
   }
 
   // Only used during deopt- preserve object type.
   StackValue(intptr_t o, BasicType t) {
     assert(t == T_OBJECT, "should not be used");
-    _type   = t;
-    _i      = o;
+    _type          = t;
+    _integer_value = o;
   }
 
   Handle get_obj() const {
     assert(type() == T_OBJECT, "type check");
-    return _o;
+    return _handle_value;
   }
 
   bool obj_is_scalar_replaced() const {
     assert(type() == T_OBJECT, "type check");
-    return _i != 0;
+    return _integer_value != 0;
   }
 
   void set_obj(Handle value) {
     assert(type() == T_OBJECT, "type check");
-    _o = value;
+    _handle_value = value;
   }
 
   intptr_t get_int() const {
     assert(type() == T_INT, "type check");
-    return _i;
+    return _integer_value;
   }
 
   // For special case in deopt.
   intptr_t get_int(BasicType t) const {
     assert(t == T_OBJECT && type() == T_OBJECT, "type check");
-    return _i;
+    return _integer_value;
   }
 
   void set_int(intptr_t value) {
     assert(type() == T_INT, "type check");
-    _i = value;
+    _integer_value = value;
   }
 
   BasicType type() const { return  _type; }
@@ -95,11 +95,11 @@
   bool equal(StackValue *value) {
     if (_type != value->_type) return false;
     if (_type == T_OBJECT)
-      return (_o == value->_o);
+      return (_handle_value == value->_handle_value);
     else {
       assert(_type == T_INT, "sanity check");
       // [phh] compare only low addressed portions of intptr_t slots
-      return (*(int *)&_i == *(int *)&value->_i);
+      return (*(int *)&_integer_value == *(int *)&value->_integer_value);
     }
   }
 
--- a/src/hotspot/share/runtime/thread.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/thread.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoader.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
@@ -51,7 +52,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/verifyOopClosure.hpp"
-#include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
@@ -762,7 +762,7 @@
 
 // GC Support
 bool Thread::claim_oops_do_par_case(int strong_roots_parity) {
-  jint thread_parity = _oops_do_parity;
+  int thread_parity = _oops_do_parity;
   if (thread_parity != strong_roots_parity) {
     jint res = Atomic::cmpxchg(strong_roots_parity, &_oops_do_parity, thread_parity);
     if (res == thread_parity) {
@@ -3724,7 +3724,7 @@
   }
 
   // initialize compiler(s)
-#if defined(COMPILER1) || defined(COMPILER2) || INCLUDE_JVMCI
+#if defined(COMPILER1) || COMPILER2_OR_JVMCI
   CompileBroker::compilation_init(CHECK_JNI_ERR);
 #endif
 
--- a/src/hotspot/share/runtime/thread.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/thread.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -244,7 +244,7 @@
 
   // The parity of the last strong_roots iteration in which this thread was
   // claimed as a task.
-  jint _oops_do_parity;
+  int _oops_do_parity;
 
  public:
   void set_last_handle_mark(HandleMark* mark)   { _last_handle_mark = mark; }
--- a/src/hotspot/share/runtime/vmStructs.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -47,6 +47,7 @@
 #include "gc/parallel/immutableSpace.hpp"
 #include "gc/parallel/mutableSpace.hpp"
 #include "gc/serial/defNewGeneration.hpp"
+#include "gc/serial/serialHeap.hpp"
 #include "gc/serial/tenuredGeneration.hpp"
 #include "gc/cms/cmsHeap.hpp"
 #include "gc/shared/cardTableRS.hpp"
@@ -356,7 +357,7 @@
   nonstatic_field(Symbol,                      _length,                                       unsigned short)                        \
   unchecked_nonstatic_field(Symbol,            _body,                                         sizeof(jbyte)) /* NOTE: no type */     \
   nonstatic_field(Symbol,                      _body[0],                                      jbyte)                                 \
-  nonstatic_field(TypeArrayKlass,              _max_length,                                   int)                                   \
+  nonstatic_field(TypeArrayKlass,              _max_length,                                   jint)                                  \
                                                                                                                                      \
   /***********************/                                                                                                          \
   /* Constant Pool Cache */                                                                                                          \
@@ -579,7 +580,7 @@
      static_field(PerfMemory,                  _top,                                          char*)                                 \
      static_field(PerfMemory,                  _capacity,                                     size_t)                                \
      static_field(PerfMemory,                  _prologue,                                     PerfDataPrologue*)                     \
-     static_field(PerfMemory,                  _initialized,                                  jint)                                  \
+     static_field(PerfMemory,                  _initialized,                                  int)                                   \
                                                                                                                                      \
   /***************/                                                                                                                  \
   /* SymbolTable */                                                                                                                  \
@@ -1465,6 +1466,7 @@
   declare_toplevel_type(CollectedHeap)                                    \
            declare_type(GenCollectedHeap,             CollectedHeap)      \
            declare_type(CMSHeap,                      GenCollectedHeap)   \
+           declare_type(SerialHeap,                   GenCollectedHeap)   \
   declare_toplevel_type(Generation)                                       \
            declare_type(DefNewGeneration,             Generation)         \
            declare_type(CardGeneration,               Generation)         \
@@ -2175,6 +2177,7 @@
   declare_toplevel_type(vframeArray)                                      \
   declare_toplevel_type(vframeArrayElement)                               \
   declare_toplevel_type(Annotations*)                                     \
+  declare_type(OopMapValue, StackObj)                                     \
                                                                           \
   /***************/                                                       \
   /* Miscellaneous types */                                               \
@@ -2257,7 +2260,8 @@
                                                                           \
   declare_constant(G1SATBCardTableModRefBS::g1_young_gen)                 \
                                                                           \
-  declare_constant(CollectedHeap::GenCollectedHeap)                       \
+  declare_constant(CollectedHeap::SerialHeap)                             \
+  declare_constant(CollectedHeap::CMSHeap)                                \
   declare_constant(CollectedHeap::ParallelScavengeHeap)                   \
   declare_constant(CollectedHeap::G1CollectedHeap)                        \
                                                                           \
--- a/src/hotspot/share/runtime/vm_operations.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/vm_operations.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -230,6 +230,10 @@
   JNIHandles::print_on(_out);
 }
 
+void VM_PrintMetadata::doit() {
+  MetaspaceAux::print_metadata_for_nmt(_out, _scale);
+}
+
 VM_FindDeadlocks::~VM_FindDeadlocks() {
   if (_deadlocks != NULL) {
     DeadlockCycle* cycle = _deadlocks;
--- a/src/hotspot/share/runtime/vm_operations.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/runtime/vm_operations.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -111,6 +111,7 @@
   template(ThreadsSuspendJVMTI)                   \
   template(ICBufferFull)                          \
   template(ScavengeMonitors)                      \
+  template(PrintMetadata)                         \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
@@ -374,6 +375,17 @@
   void doit();
 };
 
+class VM_PrintMetadata : public VM_Operation {
+ private:
+  outputStream* _out;
+  size_t        _scale;
+ public:
+  VM_PrintMetadata(outputStream* out, size_t scale) : _out(out), _scale(scale) {};
+
+  VMOp_Type type() const  { return VMOp_PrintMetadata; }
+  void doit();
+};
+
 class DeadlockCycle;
 class VM_FindDeadlocks: public VM_Operation {
  private:
--- a/src/hotspot/share/services/diagnosticArgument.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/diagnosticArgument.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/thread.hpp"
 #include "services/diagnosticArgument.hpp"
 
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/classLoaderStats.hpp"
 #include "classfile/compactHashtable.hpp"
 #include "compiler/compileBroker.hpp"
@@ -30,7 +31,6 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/globals.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/services/diagnosticFramework.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/diagnosticFramework.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,10 +23,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "services/diagnosticArgument.hpp"
--- a/src/hotspot/share/services/heapDumper.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/heapDumper.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -34,7 +35,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/services/mallocSiteTable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/mallocSiteTable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -235,8 +235,8 @@
 
 
 void MallocSiteTable::AccessLock::exclusiveLock() {
-  jint target;
-  jint val;
+  int target;
+  int val;
 
   assert(_lock_state != ExclusiveLock, "Can only call once");
   assert(*_lock >= 0, "Can not content exclusive lock");
--- a/src/hotspot/share/services/memTracker.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/memTracker.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,8 +22,8 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 
-#include "prims/jvm.h"
 #include "runtime/mutex.hpp"
 #include "services/memBaseline.hpp"
 #include "services/memReporter.hpp"
--- a/src/hotspot/share/services/memoryService.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/memoryService.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -86,7 +86,7 @@
 void MemoryService::set_universe_heap(CollectedHeap* heap) {
   CollectedHeap::Name kind = heap->kind();
   switch (kind) {
-    case CollectedHeap::GenCollectedHeap :
+    case CollectedHeap::SerialHeap :
     case CollectedHeap::CMSHeap : {
       add_gen_collected_heap_info(GenCollectedHeap::heap());
       break;
--- a/src/hotspot/share/services/nmtDCmd.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/nmtDCmd.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -24,6 +24,8 @@
 #include "precompiled.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/vmThread.hpp"
+#include "runtime/vm_operations.hpp"
 #include "services/nmtDCmd.hpp"
 #include "services/memReporter.hpp"
 #include "services/memTracker.hpp"
@@ -38,6 +40,8 @@
   _detail("detail", "request runtime to report memory allocation >= "
            "1K by each callsite.",
            "BOOLEAN", false, "false"),
+  _metadata("metadata", "request runtime to report metadata information",
+           "BOOLEAN", false, "false"),
   _baseline("baseline", "request runtime to baseline current memory usage, " \
             "so it can be compared against in later time.",
             "BOOLEAN", false, "false"),
@@ -57,6 +61,7 @@
        "STRING", false, "KB") {
   _dcmdparser.add_dcmd_option(&_summary);
   _dcmdparser.add_dcmd_option(&_detail);
+  _dcmdparser.add_dcmd_option(&_metadata);
   _dcmdparser.add_dcmd_option(&_baseline);
   _dcmdparser.add_dcmd_option(&_summary_diff);
   _dcmdparser.add_dcmd_option(&_detail_diff);
@@ -92,6 +97,7 @@
   int nopt = 0;
   if (_summary.is_set() && _summary.value()) { ++nopt; }
   if (_detail.is_set() && _detail.value()) { ++nopt; }
+  if (_metadata.is_set() && _metadata.value()) { ++nopt; }
   if (_baseline.is_set() && _baseline.value()) { ++nopt; }
   if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
   if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
@@ -100,7 +106,7 @@
 
   if (nopt > 1) {
       output()->print_cr("At most one of the following option can be specified: " \
-        "summary, detail, baseline, summary.diff, detail.diff, shutdown");
+        "summary, detail, metadata, baseline, summary.diff, detail.diff, shutdown");
       return;
   } else if (nopt == 0) {
     if (_summary.is_set()) {
@@ -118,9 +124,13 @@
     report(true, scale_unit);
   } else if (_detail.value()) {
     if (!check_detail_tracking_level(output())) {
-    return;
-  }
+      return;
+    }
     report(false, scale_unit);
+  } else if (_metadata.value()) {
+      size_t scale = get_scale(_scale.value());
+      VM_PrintMetadata op(output(), scale);
+      VMThread::execute(&op);
   } else if (_baseline.value()) {
     MemBaseline& baseline = MemTracker::get_baseline();
     if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
--- a/src/hotspot/share/services/nmtDCmd.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/services/nmtDCmd.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -39,6 +39,7 @@
  protected:
   DCmdArgument<bool>  _summary;
   DCmdArgument<bool>  _detail;
+  DCmdArgument<bool>  _metadata;
   DCmdArgument<bool>  _baseline;
   DCmdArgument<bool>  _summary_diff;
   DCmdArgument<bool>  _detail_diff;
--- a/src/hotspot/share/trace/traceMacros.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/trace/traceMacros.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -41,6 +41,8 @@
 #define TRACE_REGISTER_NATIVES ((void*)((address_word)(&trace_register_natives)))
 #define TRACE_START() JNI_OK
 #define TRACE_INITIALIZE() JNI_OK
+#define TRACE_ALLOCATION(obj, size, thread)
+#define TRACE_WEAK_OOPS_DO(is_alive, f)
 #define TRACE_VM_EXIT()
 #define TRACE_VM_ERROR()
 #define TRACE_SUSPEND_THREAD(t)
--- a/src/hotspot/share/trace/traceevents.xml	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/trace/traceevents.xml	Thu Nov 16 12:15:55 2017 +0000
@@ -108,6 +108,7 @@
          description="Revoked bias of object" has_thread="true" has_stacktrace="true" is_instant="false">
     <value type="CLASS" field="lockClass" label="Lock Class" description="Class of object whose biased lock was revoked"/>
     <value type="INTEGER" field="safepointId" label="Safepoint Identifier" relation="SafepointId"/>
+    <value type="THREAD" field="previousOwner" label="Previous Owner" description="Thread owning the bias before revocation"/>
   </event>
 
   <event id="BiasedLockSelfRevocation" path="java/biased_lock_self_revocation" label="Biased Lock Self Revocation"
--- a/src/hotspot/share/utilities/accessFlags.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/accessFlags.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
 #define SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
 
+#include "jvm.h"
 #include "memory/allocation.hpp"
-#include "prims/jvm.h"
 #include "utilities/macros.hpp"
 
 // AccessFlags is an abstraction over Java access flags.
--- a/src/hotspot/share/utilities/constantTag.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/constantTag.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_UTILITIES_CONSTANTTAG_HPP
 #define SHARE_VM_UTILITIES_CONSTANTTAG_HPP
 
+#include "jvm.h"
 #include "memory/allocation.hpp"
-#include "prims/jvm.h"
 
 // constant tags in Java .class files
 
--- a/src/hotspot/share/utilities/debug.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/debug.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
@@ -36,7 +37,6 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "prims/privilegedStack.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
@@ -276,7 +276,7 @@
 }
 
 void report_java_out_of_memory(const char* message) {
-  static jint out_of_memory_reported = 0;
+  static int out_of_memory_reported = 0;
 
   // A number of threads may attempt to report OutOfMemoryError at around the
   // same time. To avoid dumping the heap or executing the data collection
--- a/src/hotspot/share/utilities/decoder.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/decoder.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
 #include "runtime/os.hpp"
 #include "utilities/decoder.hpp"
 #include "utilities/vmError.hpp"
--- a/src/hotspot/share/utilities/elfStringTable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/elfStringTable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -26,8 +26,8 @@
 
 #if !defined(_WINDOWS) && !defined(__APPLE__)
 
+#include "jvm.h"
 #include "memory/allocation.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/os.hpp"
 #include "utilities/elfStringTable.hpp"
 
--- a/src/hotspot/share/utilities/formatBuffer.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/formatBuffer.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,8 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/allocation.hpp"
-#include "prims/jvm.h"
 #include "utilities/formatBuffer.hpp"
 
 #include <stdarg.h>
--- a/src/hotspot/share/utilities/formatBuffer.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/formatBuffer.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -25,8 +25,8 @@
 #ifndef SHARE_VM_UTILITIES_FORMATBUFFER_HPP
 #define SHARE_VM_UTILITIES_FORMATBUFFER_HPP
 
+#include "jvm.h"
 #include "utilities/globalDefinitions.hpp"
-#include "prims/jvm.h"
 #include <stdarg.h>
 
 // Simple class to format the ctor arguments into a fixed-sized buffer.
--- a/src/hotspot/share/utilities/globalDefinitions_xlc.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/globalDefinitions_xlc.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -86,6 +86,7 @@
 // In this case you need to copy the following defines to a position after #include <dirent.h>
 // (see jmv_aix.h).
 #ifdef AIX
+  #include <dirent.h>
   #ifdef _LP64
     #undef NULL
     #define NULL 0L
--- a/src/hotspot/share/utilities/growableArray.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/growableArray.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -402,7 +402,7 @@
   // matching key according to the static compare function.  Insert
   // that element is not already in the list.  Assumes the list is
   // already sorted according to compare function.
-  template <int compare(const E&, const E&)> E insert_sorted(E& key) {
+  template <int compare(const E&, const E&)> E insert_sorted(const E& key) {
     bool found;
     int location = find_sorted<E, compare>(key, found);
     if (!found) {
--- a/src/hotspot/share/utilities/hashtable.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/hashtable.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -264,6 +264,49 @@
   }
 }
 
+template <MEMFLAGS F> bool BasicHashtable<F>::resize(int new_size) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+
+  // Allocate new buckets
+  HashtableBucket<F>* buckets_new = NEW_C_HEAP_ARRAY2_RETURN_NULL(HashtableBucket<F>, new_size, F, CURRENT_PC);
+  if (buckets_new == NULL) {
+    return false;
+  }
+
+  // Clear the new buckets
+  for (int i = 0; i < new_size; i++) {
+    buckets_new[i].clear();
+  }
+
+  int table_size_old = _table_size;
+  // hash_to_index() uses _table_size, so switch the sizes now
+  _table_size = new_size;
+
+  // Move entries from the old table to a new table
+  for (int index_old = 0; index_old < table_size_old; index_old++) {
+    for (BasicHashtableEntry<F>* p = _buckets[index_old].get_entry(); p != NULL; ) {
+      BasicHashtableEntry<F>* next = p->next();
+      bool keep_shared = p->is_shared();
+      int index_new = hash_to_index(p->hash());
+
+      p->set_next(buckets_new[index_new].get_entry());
+      buckets_new[index_new].set_entry(p);
+
+      if (keep_shared) {
+        p->set_shared();
+      }
+      p = next;
+    }
+  }
+
+  // The old backets now can be released
+  BasicHashtable<F>::free_buckets();
+
+  // Switch to the new storage
+  _buckets = buckets_new;
+
+  return true;
+}
 
 // Dump footprint and bucket length statistics
 //
--- a/src/hotspot/share/utilities/hashtable.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/hashtable.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -237,6 +237,8 @@
 
   int number_of_entries() const { return _number_of_entries; }
 
+  bool resize(int new_size);
+
   template <class T> void verify_table(const char* table_name) PRODUCT_RETURN;
 };
 
@@ -281,7 +283,6 @@
   HashtableEntry<T, F>** bucket_addr(int i) {
     return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
   }
-
 };
 
 template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
--- a/src/hotspot/share/utilities/macros.hpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/macros.hpp	Thu Nov 16 12:15:55 2017 +0000
@@ -322,7 +322,9 @@
 #endif
 
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+#ifndef BSD
 #define BSD
+#endif // BSD defined in <sys/param.h>
 #define BSD_ONLY(code) code
 #define NOT_BSD(code)
 #else
--- a/src/hotspot/share/utilities/ostream.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/ostream.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,9 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "compiler/compileLog.hpp"
 #include "oops/oop.inline.hpp"
-#include "prims/jvm.h"
 #include "runtime/arguments.hpp"
 #include "runtime/os.hpp"
 #include "runtime/vm_version.hpp"
--- a/src/hotspot/share/utilities/vmError.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/hotspot/share/utilities/vmError.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,12 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "code/codeCache.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "logging/logConfiguration.hpp"
-#include "prims/jvm.h"
 #include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
--- a/src/java.base/macosx/native/include/jni_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef _JAVASOFT_JNI_MD_H_
-#define _JAVASOFT_JNI_MD_H_
-
-#define JNIEXPORT     __attribute__((visibility("default")))
-#define JNIIMPORT     __attribute__((visibility("default")))
-#define JNICALL
-
-typedef int jint;
-#ifdef _LP64 /* 64-bit */
-typedef long jlong;
-#else
-typedef long long jlong;
-#endif
-
-typedef signed char jbyte;
-
-#endif /* !_JAVASOFT_JNI_MD_H_ */
--- a/src/java.base/macosx/native/include/jvm_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef _JAVASOFT_JVM_MD_H_
-#define _JAVASOFT_JVM_MD_H_
-
-/*
- * This file is currently collecting system-specific dregs for the
- * JNI conversion, which should be sorted out later.
- */
-
-#include <dirent.h>             /* For DIR */
-#include <sys/param.h>          /* For MAXPATHLEN */
-#include <unistd.h>             /* For F_OK, R_OK, W_OK */
-#include <stddef.h>             /* For ptrdiff_t */
-#include <stdint.h>             /* For uintptr_t */
-
-#define JNI_ONLOAD_SYMBOLS   {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
-
-#define JNI_LIB_PREFIX "lib"
-#define JNI_LIB_SUFFIX ".dylib"
-#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME "." VERSION JNI_LIB_SUFFIX
-#define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX
-
-#define JVM_MAXPATHLEN MAXPATHLEN
-
-#define JVM_R_OK    R_OK
-#define JVM_W_OK    W_OK
-#define JVM_X_OK    X_OK
-#define JVM_F_OK    F_OK
-
-/*
- * File I/O
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signals */
-
-#define JVM_SIGINT     SIGINT
-#define JVM_SIGTERM    SIGTERM
-
-
-#endif /* !_JAVASOFT_JVM_MD_H_ */
--- a/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,14 +32,12 @@
 import java.lang.invoke.MethodType;
 
 class StackFrameInfo implements StackFrame {
+    private final byte RETAIN_CLASS_REF = 0x01;
+
     private final static JavaLangInvokeAccess JLIA =
         SharedSecrets.getJavaLangInvokeAccess();
 
-    // Footprint improvement: MemberName::clazz can replace
-    // StackFrameInfo::declaringClass.
-
-    private final StackWalker walker;
-    private final Class<?> declaringClass;
+    private final byte flags;
     private final Object memberName;
     private final short bci;
     private volatile StackTraceElement ste;
@@ -49,8 +47,7 @@
      * to use
      */
     StackFrameInfo(StackWalker walker) {
-        this.walker = walker;
-        this.declaringClass = null;
+        this.flags = walker.retainClassRef ? RETAIN_CLASS_REF : 0;
         this.bci = -1;
         this.memberName = JLIA.newMemberName();
     }
@@ -58,20 +55,20 @@
     // package-private called by StackStreamFactory to skip
     // the capability check
     Class<?> declaringClass() {
-        return declaringClass;
+        return JLIA.getDeclaringClass(memberName);
     }
 
     // ----- implementation of StackFrame methods
 
     @Override
     public String getClassName() {
-        return declaringClass.getName();
+        return declaringClass().getName();
     }
 
     @Override
     public Class<?> getDeclaringClass() {
-        walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
-        return declaringClass;
+        ensureRetainClassRefEnabled();
+        return declaringClass();
     }
 
     @Override
@@ -81,7 +78,7 @@
 
     @Override
     public MethodType getMethodType() {
-        walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
+        ensureRetainClassRefEnabled();
         return JLIA.getMethodType(memberName);
     }
 
@@ -137,4 +134,10 @@
         }
         return s;
     }
+
+    private void ensureRetainClassRefEnabled() {
+        if ((flags & RETAIN_CLASS_REF) == 0) {
+            throw new UnsupportedOperationException("No access to RETAIN_CLASS_REFERENCE");
+        }
+    }
 }
--- a/src/java.base/share/classes/java/lang/StackWalker.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/StackWalker.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -296,6 +296,7 @@
     private final Set<Option> options;
     private final ExtendedOption extendedOption;
     private final int estimateDepth;
+    final boolean retainClassRef; // cached for performance
 
     /**
      * Returns a {@code StackWalker} instance.
@@ -412,6 +413,7 @@
         this.options = options;
         this.estimateDepth = estimateDepth;
         this.extendedOption = extendedOption;
+        this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);
     }
 
     private static void checkPermission(Set<Option> options) {
@@ -590,7 +592,7 @@
      */
     @CallerSensitive
     public Class<?> getCallerClass() {
-        if (!options.contains(Option.RETAIN_CLASS_REFERENCE)) {
+        if (!retainClassRef) {
             throw new UnsupportedOperationException("This stack walker " +
                     "does not have RETAIN_CLASS_REFERENCE access");
         }
@@ -617,11 +619,4 @@
     boolean hasLocalsOperandsOption() {
         return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
     }
-
-    void ensureAccessEnabled(Option access) {
-        if (!hasOption(access)) {
-            throw new UnsupportedOperationException("No access to " + access +
-                    ": " + options.toString());
-        }
-    }
 }
--- a/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,25 +25,21 @@
 
 package java.lang.invoke;
 
-import jdk.internal.loader.BootLoader;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.FieldVisitor;
-import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.vm.annotation.Stable;
 import sun.invoke.util.ValueConversions;
-import sun.invoke.util.Wrapper;
 
-import java.lang.invoke.LambdaForm.NamedFunction;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.Field;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Function;
+import java.util.ArrayList;
+import java.util.List;
 
 import static java.lang.invoke.LambdaForm.BasicType;
 import static java.lang.invoke.LambdaForm.BasicType.*;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import static java.lang.invoke.LambdaForm.BasicType.V_TYPE_NUM;
+import static java.lang.invoke.LambdaForm.BasicType.V_TYPE_NUM;
+import static java.lang.invoke.LambdaForm.BasicType.V_TYPE_NUM;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.newInternalError;
+import static java.lang.invoke.MethodHandleStatics.uncaughtException;
 
 /**
  * The flavor of method handle which emulates an invoke instruction
@@ -56,7 +52,7 @@
 
     /*non-public*/ BoundMethodHandle(MethodType type, LambdaForm form) {
         super(type, form);
-        assert(speciesData() == speciesData(form));
+        assert(speciesData() == speciesDataFor(form));
     }
 
     //
@@ -70,13 +66,13 @@
             case L_TYPE:
                 return bindSingle(type, form, x);  // Use known fast path.
             case I_TYPE:
-                return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor().invokeBasic(type, form, ValueConversions.widenSubword(x));
+                return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
             case J_TYPE:
-                return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor().invokeBasic(type, form, (long) x);
+                return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
             case F_TYPE:
-                return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor().invokeBasic(type, form, (float) x);
+                return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
             case D_TYPE:
-                return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor().invokeBasic(type, form, (double) x);
+                return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
             default : throw newInternalError("unexpected xtype: " + xtype);
             }
         } catch (Throwable t) {
@@ -98,6 +94,7 @@
     BoundMethodHandle bindArgumentL(int pos, Object value) {
         return editor().bindArgumentL(this, pos, value);
     }
+
     /*non-public*/
     BoundMethodHandle bindArgumentI(int pos, int value) {
         return editor().bindArgumentI(this, pos, value);
@@ -114,7 +111,6 @@
     BoundMethodHandle bindArgumentD(int pos, double value) {
         return editor().bindArgumentD(this, pos, value);
     }
-
     @Override
     BoundMethodHandle rebind() {
         if (!tooComplex()) {
@@ -137,28 +133,29 @@
     static BoundMethodHandle makeReinvoker(MethodHandle target) {
         LambdaForm form = DelegatingMethodHandle.makeReinvokerForm(
                 target, MethodTypeForm.LF_REBIND,
-                Species_L.SPECIES_DATA, Species_L.SPECIES_DATA.getterFunction(0));
+                Species_L.BMH_SPECIES, Species_L.BMH_SPECIES.getterFunction(0));
         return Species_L.make(target.type(), form, target);
     }
 
     /**
-     * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
+     * Return the {@link BoundMethodHandle.SpeciesData} instance representing this BMH species. All subclasses must provide a
      * static field containing this value, and they must accordingly implement this method.
      */
-    /*non-public*/ abstract SpeciesData speciesData();
+    /*non-public*/ abstract BoundMethodHandle.SpeciesData speciesData();
 
-    /*non-public*/ static SpeciesData speciesData(LambdaForm form) {
+    /*non-public*/ static BoundMethodHandle.SpeciesData speciesDataFor(LambdaForm form) {
         Object c = form.names[0].constraint;
-        if (c instanceof SpeciesData)
+        if (c instanceof SpeciesData) {
             return (SpeciesData) c;
+        }
         // if there is no BMH constraint, then use the null constraint
-        return SpeciesData.EMPTY;
+        return SPECIALIZER.topSpecies();
     }
 
     /**
      * Return the number of fields in this BMH.  Equivalent to speciesData().fieldCount().
      */
-    /*non-public*/ abstract int fieldCount();
+    /*non-public*/ final int fieldCount() { return speciesData().fieldCount(); }
 
     @Override
     Object internalProperties() {
@@ -167,7 +164,7 @@
 
     @Override
     final String internalValues() {
-        int count = speciesData().fieldCount();
+        int count = fieldCount();
         if (count == 1) {
             return "[" + arg(0) + "]";
         }
@@ -180,17 +177,18 @@
 
     /*non-public*/ final Object arg(int i) {
         try {
-            switch (speciesData().fieldType(i)) {
-            case L_TYPE: return          speciesData().getters[i].invokeBasic(this);
-            case I_TYPE: return (int)    speciesData().getters[i].invokeBasic(this);
-            case J_TYPE: return (long)   speciesData().getters[i].invokeBasic(this);
-            case F_TYPE: return (float)  speciesData().getters[i].invokeBasic(this);
-            case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
+            Class<?> fieldType = speciesData().fieldTypes().get(i);
+            switch (BasicType.basicType(fieldType)) {
+                case L_TYPE: return          speciesData().getter(i).invokeBasic(this);
+                case I_TYPE: return (int)    speciesData().getter(i).invokeBasic(this);
+                case J_TYPE: return (long)   speciesData().getter(i).invokeBasic(this);
+                case F_TYPE: return (float)  speciesData().getter(i).invokeBasic(this);
+                case D_TYPE: return (double) speciesData().getter(i).invokeBasic(this);
             }
         } catch (Throwable ex) {
             throw uncaughtException(ex);
         }
-        throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
+        throw new InternalError("unexpected type: " + speciesData().key()+"."+i);
     }
 
     //
@@ -210,20 +208,21 @@
 
     private  // make it private to force users to access the enclosing class first
     static final class Species_L extends BoundMethodHandle {
+
         final Object argL0;
+
         private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
             super(mt, lf);
             this.argL0 = argL0;
         }
+
         @Override
         /*non-public*/ SpeciesData speciesData() {
-            return SPECIES_DATA;
+            return BMH_SPECIES;
         }
-        @Override
-        /*non-public*/ int fieldCount() {
-            return 1;
-        }
-        /*non-public*/ static final SpeciesData SPECIES_DATA = new SpeciesData("L", Species_L.class);
+
+        /*non-public*/ static @Stable SpeciesData BMH_SPECIES;
+
         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
             return new Species_L(mt, lf, argL0);
         }
@@ -234,7 +233,7 @@
         @Override
         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
             try {
-                return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
+                return (BoundMethodHandle) BMH_SPECIES.extendWith(L_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
@@ -242,7 +241,7 @@
         @Override
         /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
             try {
-                return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
+                return (BoundMethodHandle) BMH_SPECIES.extendWith(I_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
@@ -250,7 +249,7 @@
         @Override
         /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
             try {
-                return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
+                return (BoundMethodHandle) BMH_SPECIES.extendWith(J_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
@@ -258,7 +257,7 @@
         @Override
         /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
             try {
-                return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
+                return (BoundMethodHandle) BMH_SPECIES.extendWith(F_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
@@ -266,7 +265,7 @@
         @Override
         /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
             try {
-                return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
+                return (BoundMethodHandle) BMH_SPECIES.extendWith(D_TYPE_NUM).factory().invokeBasic(mt, lf, argL0, narg);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
@@ -277,601 +276,177 @@
     // BMH species meta-data
     //
 
-    /**
-     * Meta-data wrapper for concrete BMH types.
-     * Each BMH type corresponds to a given sequence of basic field types (LIJFD).
-     * The fields are immutable; their values are fully specified at object construction.
-     * Each BMH type supplies an array of getter functions which may be used in lambda forms.
-     * A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
-     * The shortest possible BMH has zero fields; its class is SimpleMethodHandle.
-     * BMH species are not interrelated by subtyping, even though it would appear that
-     * a shorter BMH could serve as a supertype of a longer one which extends it.
-     */
-    static class SpeciesData {
-        private final String                             typeChars;
-        private final BasicType[]                        typeCodes;
-        private final Class<? extends BoundMethodHandle> clazz;
-        // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
-        // Therefore, we need a non-final link in the chain.  Use array elements.
-        @Stable private final MethodHandle[]             constructor;
-        @Stable private final MethodHandle[]             getters;
-        @Stable private final NamedFunction[]            nominalGetters;
-        @Stable private final SpeciesData[]              extensions;
+    /*non-public*/
+    static final class SpeciesData extends ClassSpecializer<BoundMethodHandle, String, SpeciesData>.SpeciesData {
+        // This array is filled in lazily, as new species come into being over time.
+        @Stable final private SpeciesData[] extensions = new SpeciesData[ARG_TYPE_LIMIT];
 
-        /*non-public*/ int fieldCount() {
-            return typeCodes.length;
-        }
-        /*non-public*/ BasicType fieldType(int i) {
-            return typeCodes[i];
-        }
-        /*non-public*/ char fieldTypeChar(int i) {
-            return typeChars.charAt(i);
+        public SpeciesData(Specializer outer, String key) {
+            outer.super(key);
         }
-        String fieldSignature() {
-            return typeChars;
-        }
-        public Class<? extends BoundMethodHandle> fieldHolder() {
-            return clazz;
-        }
-        public String toString() {
-            return "SpeciesData<"+fieldSignature()+">";
+
+        @Override
+        protected String deriveClassName() {
+            String typeString = deriveTypeString();
+            if (typeString.isEmpty()) {
+                return SimpleMethodHandle.class.getName();
+            }
+            return BoundMethodHandle.class.getName() + "$Species_" + typeString;
         }
 
-        /**
-         * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
-         * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
-         * getter.
-         */
-        NamedFunction getterFunction(int i) {
-            NamedFunction nf = nominalGetters[i];
-            assert(nf.memberDeclaringClassOrNull() == fieldHolder());
-            assert(nf.returnType() == fieldType(i));
-            return nf;
-        }
-
-        NamedFunction[] getterFunctions() {
-            return nominalGetters;
-        }
-
-        MethodHandle[] getterHandles() { return getters; }
-
-        MethodHandle constructor() {
-            return constructor[0];
+        @Override
+        protected List<Class<?>> deriveFieldTypes(String key) {
+            ArrayList<Class<?>> types = new ArrayList<>(key.length());
+            for (int i = 0; i < key.length(); i++) {
+                types.add(basicType(key.charAt(i)).basicTypeClass());
+            }
+            return types;
         }
 
-        static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
-
-        SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
-            this.typeChars = types;
-            this.typeCodes = basicTypes(types);
-            this.clazz = clazz;
-            if (!INIT_DONE) {
-                this.constructor = new MethodHandle[1];  // only one ctor
-                this.getters = new MethodHandle[types.length()];
-                this.nominalGetters = new NamedFunction[types.length()];
-            } else {
-                this.constructor = Factory.makeCtors(clazz, types, null);
-                this.getters = Factory.makeGetters(clazz, types, null);
-                this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters);
-            }
-            this.extensions = new SpeciesData[ARG_TYPE_LIMIT];
+        @Override
+        protected String deriveTypeString() {
+            // (If/when we have to add nominal types, just inherit the more complex default.)
+            return key();
         }
 
-        private void initForBootstrap() {
-            assert(!INIT_DONE);
-            if (constructor() == null) {
-                String types = typeChars;
-                CACHE.put(types, this);
-                Factory.makeCtors(clazz, types, this.constructor);
-                Factory.makeGetters(clazz, types, this.getters);
-                Factory.makeNominalGetters(types, this.nominalGetters, this.getters);
+        @Override
+        protected MethodHandle deriveTransformHelper(MemberName transform, int whichtm) {
+            if (whichtm == Specializer.TN_COPY_NO_EXTEND) {
+                return factory();
+            } else if (whichtm < ARG_TYPE_LIMIT) {
+                return extendWith((byte) whichtm).factory();
+            } else {
+                throw newInternalError("bad transform");
             }
         }
 
-        private static final ConcurrentMap<String, SpeciesData> CACHE = new ConcurrentHashMap<>();
-        private static final boolean INIT_DONE;  // set after <clinit> finishes...
-
-        SpeciesData extendWith(byte type) {
-            return extendWith(BasicType.basicType(type));
-        }
-
-        SpeciesData extendWith(BasicType type) {
-            int ord = type.ordinal();
-            SpeciesData d = extensions[ord];
-            if (d != null)  return d;
-            extensions[ord] = d = get(typeChars+type.basicTypeChar());
-            return d;
+        @Override
+        protected <X> List<X> deriveTransformHelperArguments(MemberName transform, int whichtm, List<X> args, List<X> fields) {
+            assert(verifyTHAargs(transform, whichtm, args, fields));
+            // The rule is really simple:  Keep the first two arguments
+            // the same, then put in the fields, then put any other argument.
+            args.addAll(2, fields);
+            return args;
         }
 
-        private static SpeciesData get(String types) {
-            return CACHE.computeIfAbsent(types, new Function<String, SpeciesData>() {
-                @Override
-                public SpeciesData apply(String types) {
-                    Class<? extends BoundMethodHandle> bmhcl = Factory.getConcreteBMHClass(types);
-                    // SpeciesData instantiation may throw VirtualMachineError because of
-                    // code cache overflow...
-                    SpeciesData speciesData = new SpeciesData(types, bmhcl);
-                    // CHM.computeIfAbsent ensures only one SpeciesData will be set
-                    // successfully on the concrete BMH class if ever
-                    Factory.setSpeciesDataToConcreteBMHClass(bmhcl, speciesData);
-                    // the concrete BMH class is published via SpeciesData instance
-                    // returned here only after it's SPECIES_DATA field is set
-                    return speciesData;
-                }
-            });
-        }
-
-        /**
-         * This is to be called when assertions are enabled. It checks whether SpeciesData for all of the statically
-         * defined species subclasses of BoundMethodHandle has been added to the SpeciesData cache. See below in the
-         * static initializer for
-         */
-        static boolean speciesDataCachePopulated() {
-            Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
-            for (Class<?> c : rootCls.getDeclaredClasses()) {
-                if (rootCls.isAssignableFrom(c)) {
-                    final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
-                    SpeciesData d = Factory.getSpeciesDataFromConcreteBMHClass(cbmh);
-                    assert(d != null) : cbmh.getName();
-                    assert(d.clazz == cbmh);
-                    assert(CACHE.get(d.typeChars) == d);
-                }
+        private boolean verifyTHAargs(MemberName transform, int whichtm, List<?> args, List<?> fields) {
+            assert(transform == Specializer.BMH_TRANSFORMS.get(whichtm));
+            assert(args.size() == transform.getMethodType().parameterCount());
+            assert(fields.size() == this.fieldCount());
+            final int MH_AND_LF = 2;
+            if (whichtm == Specializer.TN_COPY_NO_EXTEND) {
+                assert(transform.getMethodType().parameterCount() == MH_AND_LF);
+            } else if (whichtm < ARG_TYPE_LIMIT) {
+                assert(transform.getMethodType().parameterCount() == MH_AND_LF+1);
+                final BasicType type = basicType((byte) whichtm);
+                assert(transform.getParameterTypes()[MH_AND_LF] == type.basicTypeClass());
+            } else {
+                return false;
             }
             return true;
         }
 
-        static {
-            // Pre-fill the BMH species-data cache with EMPTY and all BMH's inner subclasses.
-            EMPTY.initForBootstrap();
-            Species_L.SPECIES_DATA.initForBootstrap();
-            // check that all static SpeciesData instances have been initialized
-            assert speciesDataCachePopulated();
-            // Note:  Do not simplify this, because INIT_DONE must not be
-            // a compile-time constant during bootstrapping.
-            INIT_DONE = Boolean.TRUE;
+        /*non-public*/ SpeciesData extendWith(byte typeNum) {
+            SpeciesData sd = extensions[typeNum];
+            if (sd != null)  return sd;
+            sd = SPECIALIZER.findSpecies(key() + BasicType.basicType(typeNum).basicTypeChar());
+            extensions[typeNum] = sd;
+            return sd;
         }
     }
 
-    static SpeciesData getSpeciesData(String types) {
-        return SpeciesData.get(types);
+    /*non-public*/
+    static final Specializer SPECIALIZER = new Specializer();
+    static {
+        SimpleMethodHandle.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("");
+        Species_L.BMH_SPECIES = BoundMethodHandle.SPECIALIZER.findSpecies("L");
     }
 
-    /**
-     * Generation of concrete BMH classes.
-     *
-     * A concrete BMH species is fit for binding a number of values adhering to a
-     * given type pattern. Reference types are erased.
-     *
-     * BMH species are cached by type pattern.
-     *
-     * A BMH species has a number of fields with the concrete (possibly erased) types of
-     * bound values. Setters are provided as an API in BMH. Getters are exposed as MHs,
-     * which can be included as names in lambda forms.
-     */
-    static class Factory {
+    /*non-public*/
+    static final class Specializer extends ClassSpecializer<BoundMethodHandle, String, SpeciesData> {
+
+        private static final MemberName SPECIES_DATA_ACCESSOR;
 
-        private static final String JLO_SIG  = "Ljava/lang/Object;";
-        private static final String MH       = "java/lang/invoke/MethodHandle";
-        private static final String MH_SIG   = "L"+MH+";";
-        private static final String BMH      = "java/lang/invoke/BoundMethodHandle";
-        private static final String BMH_NAME = "java.lang.invoke.BoundMethodHandle";
-        private static final String BMH_SIG  = "L"+BMH+";";
-        private static final String SPECIES_DATA     = "java/lang/invoke/BoundMethodHandle$SpeciesData";
-        private static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
-        private static final String STABLE_SIG       = "Ljdk/internal/vm/annotation/Stable;";
+        static {
+            try {
+                SPECIES_DATA_ACCESSOR = IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BoundMethodHandle.class,
+                        "speciesData", MethodType.methodType(BoundMethodHandle.SpeciesData.class));
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError("Bootstrap link error", ex);
+            }
+        }
 
-        private static final String SPECIES_PREFIX_NAME = "Species_";
-        private static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
-        private static final String SPECIES_CLASS_PREFIX = BMH_NAME + "$" + SPECIES_PREFIX_NAME;
-
-        private static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
-        private static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
-        private static final String INT_SIG    = "()I";
+        private Specializer() {
+            super(  // Reified type parameters:
+                    BoundMethodHandle.class, String.class, BoundMethodHandle.SpeciesData.class,
+                    // Principal constructor type:
+                    MethodType.methodType(void.class, MethodType.class, LambdaForm.class),
+                    // Required linkage between class and species:
+                    SPECIES_DATA_ACCESSOR,
+                    "BMH_SPECIES",
+                    BMH_TRANSFORMS);
+        }
 
-        private static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
+        @Override
+        protected String topSpeciesKey() {
+            return "";
+        }
 
-        private static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
-
-        private static final ConcurrentMap<String, Class<? extends BoundMethodHandle>> CLASS_CACHE = new ConcurrentHashMap<>();
+        @Override
+        protected BoundMethodHandle.SpeciesData newSpeciesData(String key) {
+            return new BoundMethodHandle.SpeciesData(this, key);
+        }
 
-        /**
-         * Get a concrete subclass of BMH for a given combination of bound types.
-         *
-         * @param types the type signature, wherein reference types are erased to 'L'
-         * @return the concrete BMH class
-         */
-        static Class<? extends BoundMethodHandle> getConcreteBMHClass(String types) {
-            // CHM.computeIfAbsent ensures generateConcreteBMHClass is called
-            // only once per key.
-            return CLASS_CACHE.computeIfAbsent(
-                types, new Function<String, Class<? extends BoundMethodHandle>>() {
-                    @Override
-                    public Class<? extends BoundMethodHandle> apply(String types) {
-                        String shortTypes = LambdaForm.shortenSignature(types);
-                        String className = SPECIES_CLASS_PREFIX + shortTypes;
-                        Class<?> c = BootLoader.loadClassOrNull(className);
-                        if (TRACE_RESOLVE) {
-                            System.out.println("[BMH_RESOLVE] " + shortTypes +
-                                    (c != null ? " (success)" : " (fail)") );
-                        }
-                        if (c != null) {
-                            return c.asSubclass(BoundMethodHandle.class);
-                        } else {
-                            // Not pregenerated, generate the class
-                            return generateConcreteBMHClass(shortTypes, types);
-                        }
-                    }
-                });
+        static final List<MemberName> BMH_TRANSFORMS;
+        static final int TN_COPY_NO_EXTEND = V_TYPE_NUM;
+        static {
+            final Class<BoundMethodHandle> BMH = BoundMethodHandle.class;
+            // copyWithExtendLIJFD + copyWith
+            try {
+                BMH_TRANSFORMS = List.of(
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWithExtendL", MethodType.methodType(BMH, MethodType.class, LambdaForm.class, Object.class)),
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWithExtendI", MethodType.methodType(BMH, MethodType.class, LambdaForm.class, int.class)),
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWithExtendJ", MethodType.methodType(BMH, MethodType.class, LambdaForm.class, long.class)),
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWithExtendF", MethodType.methodType(BMH, MethodType.class, LambdaForm.class, float.class)),
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWithExtendD", MethodType.methodType(BMH, MethodType.class, LambdaForm.class, double.class)),
+                        IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, BMH, "copyWith", MethodType.methodType(BMH, MethodType.class, LambdaForm.class))
+                );
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError("Failed resolving copyWith methods", ex);
+            }
+
+            // as it happens, there is one transform per BasicType including V_TYPE
+            assert(BMH_TRANSFORMS.size() == TYPE_LIMIT);
         }
 
         /**
-         * Generate a concrete subclass of BMH for a given combination of bound types.
-         *
-         * A concrete BMH species adheres to the following schema:
+         * Generation of concrete BMH classes.
          *
-         * <pre>
-         * class Species_[[types]] extends BoundMethodHandle {
-         *     [[fields]]
-         *     final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); }
-         * }
-         * </pre>
-         *
-         * The {@code [[types]]} signature is precisely the string that is passed to this
-         * method.
-         *
-         * The {@code [[fields]]} section consists of one field definition per character in
-         * the type signature, adhering to the naming schema described in the definition of
-         * {@link #makeFieldName}.
-         *
-         * For example, a concrete BMH species for two reference and one integral bound values
-         * would have the following shape:
+         * A concrete BMH species is fit for binding a number of values adhering to a
+         * given type pattern. Reference types are erased.
          *
-         * <pre>
-         * class BoundMethodHandle { ... private static
-         * final class Species_LLI extends BoundMethodHandle {
-         *     final Object argL0;
-         *     final Object argL1;
-         *     final int argI2;
-         *     private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
-         *         super(mt, lf);
-         *         this.argL0 = argL0;
-         *         this.argL1 = argL1;
-         *         this.argI2 = argI2;
-         *     }
-         *     final SpeciesData speciesData() { return SPECIES_DATA; }
-         *     final int fieldCount() { return 3; }
-         *     &#64;Stable static SpeciesData SPECIES_DATA; // injected afterwards
-         *     static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
-         *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
-         *     }
-         *     final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
-         *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
-         *     }
-         *     final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
-         *         return SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
-         *     }
-         *     final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
-         *         return SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
-         *     }
-         *     final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
-         *         return SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
-         *     }
-         *     final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
-         *         return SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
-         *     }
-         *     public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
-         *         return SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
-         *     }
-         * }
-         * </pre>
+         * BMH species are cached by type pattern.
          *
-         * @param types the type signature, wherein reference types are erased to 'L'
-         * @return the generated concrete BMH class
+         * A BMH species has a number of fields with the concrete (possibly erased) types of
+         * bound values. Setters are provided as an API in BMH. Getters are exposed as MHs,
+         * which can be included as names in lambda forms.
          */
-        static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String shortTypes,
-                String types) {
-            final String className  = speciesInternalClassName(shortTypes);
-            byte[] classFile = generateConcreteBMHClassBytes(shortTypes, types, className);
-
-            // load class
-            InvokerBytecodeGenerator.maybeDump(className, classFile);
-            Class<? extends BoundMethodHandle> bmhClass =
-                UNSAFE.defineClass(className, classFile, 0, classFile.length,
-                                   BoundMethodHandle.class.getClassLoader(), null)
-                    .asSubclass(BoundMethodHandle.class);
-
-            return bmhClass;
-        }
-
-        static String speciesInternalClassName(String shortTypes) {
-            return SPECIES_PREFIX_PATH + shortTypes;
-        }
-
-        static byte[] generateConcreteBMHClassBytes(final String shortTypes,
-                final String types, final String className) {
-            final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
-
-            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-            final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
-            cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
-            cw.visitSource(sourceFile, null);
-
-            // emit static types and SPECIES_DATA fields
-            FieldVisitor fw = cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null);
-            fw.visitAnnotation(STABLE_SIG, true);
-            fw.visitEnd();
-
-            // emit bound argument fields
-            for (int i = 0; i < types.length(); ++i) {
-                final char t = types.charAt(i);
-                final String fieldName = makeFieldName(types, i);
-                final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
-                cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
-            }
-
-            MethodVisitor mv;
-
-            // emit constructor
-            mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0); // this
-            mv.visitVarInsn(ALOAD, 1); // type
-            mv.visitVarInsn(ALOAD, 2); // form
-
-            mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
-
-            for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
-                // i counts the arguments, j counts corresponding argument slots
-                char t = types.charAt(i);
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
-                mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
-                if (t == 'J' || t == 'D') {
-                    ++j; // adjust argument register access
-                }
-            }
-
-            mv.visitInsn(RETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-
-            // emit implementation of speciesData()
-            mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
-            mv.visitCode();
-            mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-
-            // emit implementation of fieldCount()
-            mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
-            mv.visitCode();
-            int fc = types.length();
-            if (fc <= (ICONST_5 - ICONST_0)) {
-                mv.visitInsn(ICONST_0 + fc);
-            } else {
-                mv.visitIntInsn(SIPUSH, fc);
-            }
-            mv.visitInsn(IRETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-            // emit make()  ...factory method wrapping constructor
-            mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null);
-            mv.visitCode();
-            // make instance
-            mv.visitTypeInsn(NEW, className);
-            mv.visitInsn(DUP);
-            // load mt, lf
-            mv.visitVarInsn(ALOAD, 0);  // type
-            mv.visitVarInsn(ALOAD, 1);  // form
-            // load factory method arguments
-            for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
-                // i counts the arguments, j counts corresponding argument slots
-                char t = types.charAt(i);
-                mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3
-                if (t == 'J' || t == 'D') {
-                    ++j; // adjust argument register access
-                }
-            }
-
-            // finally, invoke the constructor and return
-            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-
-            // emit copyWith()
-            mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
-            mv.visitCode();
-            // make instance
-            mv.visitTypeInsn(NEW, className);
-            mv.visitInsn(DUP);
-            // load mt, lf
-            mv.visitVarInsn(ALOAD, 1);
-            mv.visitVarInsn(ALOAD, 2);
-            // put fields on the stack
-            emitPushFields(types, className, mv);
-            // finally, invoke the constructor and return
-            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-
-            // for each type, emit copyWithExtendT()
-            for (BasicType type : BasicType.ARG_TYPES) {
-                int ord = type.ordinal();
-                char btChar = type.basicTypeChar();
-                mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE);
-                mv.visitCode();
-                // return SPECIES_DATA.extendWith(t).constructor().invokeBasic(mt, lf, argL0, ..., narg)
-                // obtain constructor
-                mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
-                int iconstInsn = ICONST_0 + ord;
-                assert(iconstInsn <= ICONST_5);
-                mv.visitInsn(iconstInsn);
-                mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
-                mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "constructor", "()" + MH_SIG, false);
-                // load mt, lf
-                mv.visitVarInsn(ALOAD, 1);
-                mv.visitVarInsn(ALOAD, 2);
-                // put fields on the stack
-                emitPushFields(types, className, mv);
-                // put narg on stack
-                mv.visitVarInsn(typeLoadOp(btChar), 3);
-                // finally, invoke the constructor and return
-                mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false);
-                mv.visitInsn(ARETURN);
-                mv.visitMaxs(0, 0);
-                mv.visitEnd();
-            }
-
-            cw.visitEnd();
-
-            return cw.toByteArray();
-        }
-
-        private static int typeLoadOp(char t) {
-            switch (t) {
-            case 'L': return ALOAD;
-            case 'I': return ILOAD;
-            case 'J': return LLOAD;
-            case 'F': return FLOAD;
-            case 'D': return DLOAD;
-            default : throw newInternalError("unrecognized type " + t);
+        class Factory extends ClassSpecializer<BoundMethodHandle, String, BoundMethodHandle.SpeciesData>.Factory {
+            @Override
+            protected String chooseFieldName(Class<?> type, int index) {
+                return "arg" + super.chooseFieldName(type, index);
             }
         }
 
-        private static void emitPushFields(String types, String className, MethodVisitor mv) {
-            for (int i = 0; i < types.length(); ++i) {
-                char tc = types.charAt(i);
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitFieldInsn(GETFIELD, className, makeFieldName(types, i), typeSig(tc));
-            }
-        }
-
-        static String typeSig(char t) {
-            return t == 'L' ? JLO_SIG : String.valueOf(t);
-        }
-
-        //
-        // Getter MH generation.
-        //
-
-        private static MethodHandle makeGetter(Class<?> cbmhClass, String types, int index) {
-            String fieldName = makeFieldName(types, index);
-            Class<?> fieldType = Wrapper.forBasicType(types.charAt(index)).primitiveType();
-            try {
-                return LOOKUP.findGetter(cbmhClass, fieldName, fieldType);
-            } catch (NoSuchFieldException | IllegalAccessException e) {
-                throw newInternalError(e);
-            }
+        @Override
+        protected Factory makeFactory() {
+            return new Factory();
         }
-
-        static MethodHandle[] makeGetters(Class<?> cbmhClass, String types, MethodHandle[] mhs) {
-            if (mhs == null)  mhs = new MethodHandle[types.length()];
-            for (int i = 0; i < mhs.length; ++i) {
-                mhs[i] = makeGetter(cbmhClass, types, i);
-                assert(mhs[i].internalMemberName().getDeclaringClass() == cbmhClass);
-            }
-            return mhs;
-        }
-
-        static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) {
-            if (mhs == null)  mhs = new MethodHandle[1];
-            if (types.equals(""))  return mhs;  // hack for empty BMH species
-            mhs[0] = makeCbmhCtor(cbmh, types);
-            return mhs;
-        }
-
-        static NamedFunction[] makeNominalGetters(String types, NamedFunction[] nfs, MethodHandle[] getters) {
-            if (nfs == null)  nfs = new NamedFunction[types.length()];
-            for (int i = 0; i < nfs.length; ++i) {
-                nfs[i] = new NamedFunction(getters[i]);
-            }
-            return nfs;
-        }
-
-        //
-        // Auxiliary methods.
-        //
-
-        static SpeciesData getSpeciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
-            try {
-                Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
-                return (SpeciesData) F_SPECIES_DATA.get(null);
-            } catch (ReflectiveOperationException ex) {
-                throw newInternalError(ex);
-            }
-        }
+      }
 
-        static void setSpeciesDataToConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh, SpeciesData speciesData) {
-            try {
-                Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
-                // ## FIXME: annotation parser can't create proxy classes until module system is fully initialzed
-                // assert F_SPECIES_DATA.getDeclaredAnnotation(Stable.class) != null;
-                F_SPECIES_DATA.set(null, speciesData);
-            } catch (ReflectiveOperationException ex) {
-                throw newInternalError(ex);
-            }
-        }
-
-        /**
-         * Field names in concrete BMHs adhere to this pattern:
-         * arg + type + index
-         * where type is a single character (L, I, J, F, D).
-         */
-        private static String makeFieldName(String types, int index) {
-            assert index >= 0 && index < types.length();
-            return "arg" + types.charAt(index) + index;
-        }
-
-        private static String makeSignature(String types, boolean ctor) {
-            StringBuilder buf = new StringBuilder(SIG_INCIPIT);
-            int len = types.length();
-            for (int i = 0; i < len; i++) {
-                buf.append(typeSig(types.charAt(i)));
-            }
-            return buf.append(')').append(ctor ? "V" : BMH_SIG).toString();
-        }
-
-        private static MethodType makeConstructorType(String types) {
-            int length = types.length();
-            Class<?> ptypes[] = new Class<?>[length + 2];
-            ptypes[0] = MethodType.class;
-            ptypes[1] = LambdaForm.class;
-            for (int i = 0; i < length; i++) {
-                ptypes[i + 2] = BasicType.basicType(types.charAt(i)).basicTypeClass();
-            }
-            return MethodType.makeImpl(BoundMethodHandle.class, ptypes, true);
-        }
-
-        static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
-            try {
-                return LOOKUP.findStatic(cbmh, "make", makeConstructorType(types));
-            } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
-                throw newInternalError(e);
-            }
-        }
-    }
-
-    static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
-
-    /**
-     * All subclasses must provide such a value describing their type signature.
-     */
-    static final SpeciesData SPECIES_DATA = SpeciesData.EMPTY;
-
-    private static final SpeciesData[] SPECIES_DATA_CACHE = new SpeciesData[6];
-    private static SpeciesData checkCache(int size, String types) {
-        int idx = size - 1;
-        SpeciesData data = SPECIES_DATA_CACHE[idx];
-        if (data != null)  return data;
-        SPECIES_DATA_CACHE[idx] = data = getSpeciesData(types);
-        return data;
-    }
-    static SpeciesData speciesData_L()      { return checkCache(1, "L"); }
-    static SpeciesData speciesData_LL()     { return checkCache(2, "LL"); }
-    static SpeciesData speciesData_LLL()    { return checkCache(3, "LLL"); }
-    static SpeciesData speciesData_LLLL()   { return checkCache(4, "LLLL"); }
-    static SpeciesData speciesData_LLLLL()  { return checkCache(5, "LLLLL"); }
+    static SpeciesData speciesData_L()      { return Species_L.BMH_SPECIES; }
+    static SpeciesData speciesData_LL()     { return SPECIALIZER.findSpecies("LL"); }
+    static SpeciesData speciesData_LLL()    { return SPECIALIZER.findSpecies("LLL"); }
+    static SpeciesData speciesData_LLLL()   { return SPECIALIZER.findSpecies("LLLL"); }
+    static SpeciesData speciesData_LLLLL()  { return SPECIALIZER.findSpecies("LLLLL"); }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,1030 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import jdk.internal.loader.BootLoader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.vm.annotation.Stable;
+import sun.invoke.util.BytecodeName;
+
+import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
+import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_getStatic;
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_putStatic;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+/**
+ * Class specialization code.
+ * @param <T> top class under which species classes are created.
+ * @param <K> key which identifies individual specializations.
+ * @param <S> species data type.
+ */
+/*non-public*/
+abstract class ClassSpecializer<T,K,S extends ClassSpecializer<T,K,S>.SpeciesData> {
+    private final Class<T> topClass;
+    private final Class<K> keyType;
+    private final Class<S> metaType;
+    private final MemberName sdAccessor;
+    private final String sdFieldName;
+    private final List<MemberName> transformMethods;
+    private final MethodType baseConstructorType;
+    private final S topSpecies;
+    private final ConcurrentMap<K, S> cache = new ConcurrentHashMap<>();
+    private final Factory factory;
+    private @Stable boolean topClassIsSuper;
+
+    /** Return the top type mirror, for type {@code T} */
+    public final Class<T> topClass() { return topClass; }
+
+    /** Return the key type mirror, for type {@code K} */
+    public final Class<K> keyType() { return keyType; }
+
+    /** Return the species metadata type mirror, for type {@code S} */
+    public final Class<S> metaType() { return metaType; }
+
+    /** Report the leading arguments (if any) required by every species factory.
+     * Every species factory adds its own field types as additional arguments,
+     * but these arguments always come first, in every factory method.
+     */
+    protected MethodType baseConstructorType() { return baseConstructorType; }
+
+    /** Return the trivial species for the null sequence of arguments. */
+    protected final S topSpecies() { return topSpecies; }
+
+    /** Return the list of transform methods originally given at creation of this specializer. */
+    protected final List<MemberName> transformMethods() { return transformMethods; }
+
+    /** Return the factory object used to build and load concrete species code. */
+    protected final Factory factory() { return factory; }
+
+    /**
+     * Constructor for this class specializer.
+     * @param topClass type mirror for T
+     * @param keyType type mirror for K
+     * @param metaType type mirror for S
+     * @param baseConstructorType principal constructor type
+     * @param sdAccessor the method used to get the speciesData
+     * @param sdFieldName the name of the species data field, inject the speciesData object
+     * @param transformMethods optional list of transformMethods
+     */
+    protected ClassSpecializer(Class<T> topClass,
+                               Class<K> keyType,
+                               Class<S> metaType,
+                               MethodType baseConstructorType,
+                               MemberName sdAccessor,
+                               String sdFieldName,
+                               List<MemberName> transformMethods) {
+        this.topClass = topClass;
+        this.keyType = keyType;
+        this.metaType = metaType;
+        this.sdAccessor = sdAccessor;
+        // FIXME: use List.copyOf once 8177290 is in
+        this.transformMethods = List.of(transformMethods.toArray(new MemberName[transformMethods.size()]));
+        this.sdFieldName = sdFieldName;
+        this.baseConstructorType = baseConstructorType.changeReturnType(void.class);
+        this.factory = makeFactory();
+        K tsk = topSpeciesKey();
+        S topSpecies = null;
+        if (tsk != null && topSpecies == null) {
+            // if there is a key, build the top species if needed:
+            topSpecies = findSpecies(tsk);
+        }
+        this.topSpecies = topSpecies;
+    }
+
+    // Utilities for subclass constructors:
+    protected static <T> Constructor<T> reflectConstructor(Class<T> defc, Class<?>... ptypes) {
+        try {
+            return defc.getDeclaredConstructor(ptypes);
+        } catch (NoSuchMethodException ex) {
+            throw newIAE(defc.getName()+"("+MethodType.methodType(void.class, ptypes)+")", ex);
+        }
+    }
+
+    protected static Field reflectField(Class<?> defc, String name) {
+        try {
+            return defc.getDeclaredField(name);
+        } catch (NoSuchFieldException ex) {
+            throw newIAE(defc.getName()+"."+name, ex);
+        }
+    }
+
+    private static RuntimeException newIAE(String message, Throwable cause) {
+        return new IllegalArgumentException(message, cause);
+    }
+
+    public final S findSpecies(K key) {
+        S speciesData = cache.computeIfAbsent(key, new Function<>() {
+            @Override
+            public S apply(K key1) {
+                return factory.loadSpecies(newSpeciesData(key1));
+            }
+        });
+        // Note:  Species instantiation may throw VirtualMachineError because of
+        // code cache overflow.  If this happens the species bytecode may be
+        // loaded but not linked to its species metadata (with MH's etc).
+        // That will cause a throw out of CHM.computeIfAbsent,
+        // which will shut down the caller thread.
+        //
+        // In a latter attempt to get the same species, the already-loaded
+        // class will be present in the system dictionary, causing an
+        // error when the species generator tries to reload it.
+        // We try to detect this case and link the pre-existing code.
+        //
+        // Although it would be better to start fresh by loading a new
+        // copy, we have to salvage the previously loaded but broken code.
+        // (As an alternative, we might spin a new class with a new name,
+        // or use the anonymous class mechanism.)
+        //
+        // In the end, as long as everybody goes through the same CHM,
+        // CHM.computeIfAbsent will ensure only one SpeciesData will be set
+        // successfully on a concrete class if ever.
+        // The concrete class is published via SpeciesData instance
+        // returned here only after the class and species data are linked together.
+        assert(speciesData != null);
+        return speciesData;
+    }
+
+    /**
+     * Meta-data wrapper for concrete subtypes of the top class.
+     * Each concrete subtype corresponds to a given sequence of basic field types (LIJFD).
+     * The fields are immutable; their values are fully specified at object construction.
+     * Each species supplies an array of getter functions which may be used in lambda forms.
+     * A concrete value is always constructed from the full tuple of its field values,
+     * accompanied by the required constructor parameters.
+     * There *may* also be transforms which cloning a species instance and
+     * either replace a constructor parameter or add one or more new field values.
+     * The shortest possible species has zero fields.
+     * Subtypes are not interrelated among themselves by subtyping, even though
+     * it would appear that a shorter species could serve as a supertype of a
+     * longer one which extends it.
+     */
+    public abstract class SpeciesData {
+        // Bootstrapping requires circular relations Class -> SpeciesData -> Class
+        // Therefore, we need non-final links in the chain.  Use @Stable fields.
+        private final K key;
+        private final List<Class<?>> fieldTypes;
+        @Stable private Class<? extends T> speciesCode;
+        @Stable private List<MethodHandle> factories;
+        @Stable private List<MethodHandle> getters;
+        @Stable private List<LambdaForm.NamedFunction> nominalGetters;
+        @Stable private final MethodHandle[] transformHelpers = new MethodHandle[transformMethods.size()];
+
+        protected SpeciesData(K key) {
+            this.key = keyType.cast(Objects.requireNonNull(key));
+            List<Class<?>> types = deriveFieldTypes(key);
+            // TODO: List.copyOf
+            int arity = types.size();
+            this.fieldTypes = List.of(types.toArray(new Class<?>[arity]));
+        }
+
+        public final K key() {
+            return key;
+        }
+
+        protected final List<Class<?>> fieldTypes() {
+            return fieldTypes;
+        }
+
+        protected final int fieldCount() {
+            return fieldTypes.size();
+        }
+
+        protected ClassSpecializer<T,K,S> outer() {
+            return ClassSpecializer.this;
+        }
+
+        protected final boolean isResolved() {
+            return speciesCode != null && factories != null && !factories.isEmpty();
+        }
+
+        @Override public String toString() {
+            return metaType.getSimpleName() + "[" + key.toString() + " => " + (isResolved() ? speciesCode.getSimpleName() : "UNRESOLVED") + "]";
+        }
+
+        @Override
+        public int hashCode() {
+            return key.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof ClassSpecializer.SpeciesData)) {
+                return false;
+            }
+            @SuppressWarnings("rawtypes")
+            ClassSpecializer.SpeciesData that = (ClassSpecializer.SpeciesData) obj;
+            return this.outer() == that.outer() && this.key.equals(that.key);
+        }
+
+        /** Throws NPE if this species is not yet resolved. */
+        protected final Class<? extends T> speciesCode() {
+            return Objects.requireNonNull(speciesCode);
+        }
+
+        /**
+         * Return a {@link MethodHandle} which can get the indexed field of this species.
+         * The return type is the type of the species field it accesses.
+         * The argument type is the {@code fieldHolder} class of this species.
+         */
+        protected MethodHandle getter(int i) {
+            return getters.get(i);
+        }
+
+        /**
+         * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
+         * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
+         * getter.
+         */
+        protected LambdaForm.NamedFunction getterFunction(int i) {
+            LambdaForm.NamedFunction nf = nominalGetters.get(i);
+            assert(nf.memberDeclaringClassOrNull() == speciesCode());
+            assert(nf.returnType() == BasicType.basicType(fieldTypes.get(i)));
+            return nf;
+        }
+
+        protected List<LambdaForm.NamedFunction> getterFunctions() {
+            return nominalGetters;
+        }
+
+        protected List<MethodHandle> getters() {
+            return getters;
+        }
+
+        protected MethodHandle factory() {
+            return factories.get(0);
+        }
+
+        protected MethodHandle transformHelper(int whichtm) {
+            MethodHandle mh = transformHelpers[whichtm];
+            if (mh != null)  return mh;
+            mh = deriveTransformHelper(transformMethods().get(whichtm), whichtm);
+            // Do a little type checking before we start using the MH.
+            // (It will be called with invokeBasic, so this is our only chance.)
+            final MethodType mt = transformHelperType(whichtm);
+            mh = mh.asType(mt);
+            return transformHelpers[whichtm] = mh;
+        }
+
+        private final MethodType transformHelperType(int whichtm) {
+            MemberName tm = transformMethods().get(whichtm);
+            ArrayList<Class<?>> args = new ArrayList<>();
+            ArrayList<Class<?>> fields = new ArrayList<>();
+            Collections.addAll(args, tm.getParameterTypes());
+            fields.addAll(fieldTypes());
+            List<Class<?>> helperArgs = deriveTransformHelperArguments(tm, whichtm, args, fields);
+            return MethodType.methodType(tm.getReturnType(), helperArgs);
+        }
+
+        // Hooks for subclasses:
+
+        /**
+         * Given a key, derive the list of field types, which all instances of this
+         * species must store.
+         */
+        protected abstract List<Class<?>> deriveFieldTypes(K key);
+
+        /**
+         * Given the index of a method in the transforms list, supply a factory
+         * method that takes the arguments of the transform, plus the local fields,
+         * and produce a value of the required type.
+         * You can override this to return null or throw if there are no transforms.
+         * This method exists so that the transforms can be "grown" lazily.
+         * This is necessary if the transform *adds* a field to an instance,
+         * which sometimtes requires the creation, on the fly, of an extended species.
+         * This method is only called once for any particular parameter.
+         * The species caches the result in a private array.
+         *
+         * @param transform the transform being implemented
+         * @param whichtm the index of that transform in the original list of transforms
+         * @return the method handle which creates a new result from a mix of transform
+         * arguments and field values
+         */
+        protected abstract MethodHandle deriveTransformHelper(MemberName transform, int whichtm);
+
+        /**
+         * During code generation, this method is called once per transform to determine
+         * what is the mix of arguments to hand to the transform-helper.  The bytecode
+         * which marshals these arguments is open-coded in the species-specific transform.
+         * The two lists are of opaque objects, which you shouldn't do anything with besides
+         * reordering them into the output list.  (They are both mutable, to make editing
+         * easier.)  The imputed types of the args correspond to the transform's parameter
+         * list, while the imputed types of the fields correspond to the species field types.
+         * After code generation, this method may be called occasionally by error-checking code.
+         *
+         * @param transform the transform being implemented
+         * @param whichtm the index of that transform in the original list of transforms
+         * @param args a list of opaque objects representing the incoming transform arguments
+         * @param fields a list of opaque objects representing the field values of the receiver
+         * @param <X> the common element type of the various lists
+         * @return a new list
+         */
+        protected abstract <X> List<X> deriveTransformHelperArguments(MemberName transform, int whichtm,
+                                                                      List<X> args, List<X> fields);
+
+        /** Given a key, generate the name of the class which implements the species for that key.
+         * This algorithm must be stable.
+         *
+         * @return class name, which by default is {@code outer().topClass().getName() + "$Species_" + deriveTypeString(key)}
+         */
+        protected String deriveClassName() {
+            return outer().topClass().getName() + "$Species_" + deriveTypeString();
+        }
+
+        /**
+         * Default implementation collects basic type characters,
+         * plus possibly type names, if some types don't correspond
+         * to basic types.
+         *
+         * @return a string suitable for use in a class name
+         */
+        protected String deriveTypeString() {
+            List<Class<?>> types = fieldTypes();
+            StringBuilder buf = new StringBuilder();
+            StringBuilder end = new StringBuilder();
+            for (Class<?> type : types) {
+                BasicType basicType = BasicType.basicType(type);
+                if (basicType.basicTypeClass() == type) {
+                    buf.append(basicType.basicTypeChar());
+                } else {
+                    buf.append('V');
+                    end.append(classSig(type));
+                }
+            }
+            String typeString;
+            if (end.length() > 0) {
+                typeString = BytecodeName.toBytecodeName(buf.append("_").append(end).toString());
+            } else {
+                typeString = buf.toString();
+            }
+            return LambdaForm.shortenSignature(typeString);
+        }
+
+        /**
+         * Report what immediate super-class to use for the concrete class of this species.
+         * Normally this is {@code topClass}, but if that is an interface, the factory must override.
+         * The super-class must provide a constructor which takes the {@code baseConstructorType} arguments, if any.
+         * This hook also allows the code generator to use more than one canned supertype for species.
+         *
+         * @return the super-class of the class to be generated
+         */
+        protected Class<? extends T> deriveSuperClass() {
+            final Class<T> topc = topClass();
+            if (!topClassIsSuper) {
+                try {
+                    final Constructor<T> con = reflectConstructor(topc, baseConstructorType().parameterArray());
+                    if (!topc.isInterface() && !Modifier.isPrivate(con.getModifiers())) {
+                        topClassIsSuper = true;
+                    }
+                } catch (Exception|InternalError ex) {
+                    // fall through...
+                }
+                if (!topClassIsSuper) {
+                    throw newInternalError("must override if the top class cannot serve as a super class");
+                }
+            }
+            return topc;
+        }
+    }
+
+    protected abstract S newSpeciesData(K key);
+
+    protected K topSpeciesKey() {
+        return null;  // null means don't report a top species
+    }
+
+    /**
+     * Code generation support for instances.
+     * Subclasses can modify the behavior.
+     */
+    public class Factory {
+        /**
+         * Get a concrete subclass of the top class for a given combination of bound types.
+         *
+         * @param speciesData the species requiring the class, not yet linked
+         * @return a linked version of the same species
+         */
+        S loadSpecies(S speciesData) {
+            String className = speciesData.deriveClassName();
+            assert(className.indexOf('/') < 0) : className;
+            Class<?> salvage = null;
+            try {
+                salvage = BootLoader.loadClassOrNull(className);
+                if (TRACE_RESOLVE && salvage != null) {
+                    // Used by jlink species pregeneration plugin, see
+                    // jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin
+                    System.out.println("[SPECIES_RESOLVE] " + className + " (salvaged)");
+                }
+            } catch (Error ex) {
+                if (TRACE_RESOLVE) {
+                    System.out.println("[SPECIES_FRESOLVE] " + className + " (Error) " + ex.getMessage());
+                }
+            }
+            final Class<? extends T> speciesCode;
+            if (salvage != null) {
+                speciesCode = salvage.asSubclass(topClass());
+                factory.linkSpeciesDataToCode(speciesData, speciesCode);
+                factory.linkCodeToSpeciesData(speciesCode, speciesData, true);
+            } else {
+                // Not pregenerated, generate the class
+                try {
+                    speciesCode = generateConcreteSpeciesCode(className, speciesData);
+                    if (TRACE_RESOLVE) {
+                        // Used by jlink species pregeneration plugin, see
+                        // jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin
+                        System.out.println("[SPECIES_RESOLVE] " + className + " (generated)");
+                    }
+                    // This operation causes a lot of churn:
+                    linkSpeciesDataToCode(speciesData, speciesCode);
+                    // This operation commits the relation, but causes little churn:
+                    linkCodeToSpeciesData(speciesCode, speciesData, false);
+                } catch (Error ex) {
+                    if (TRACE_RESOLVE) {
+                        System.out.println("[SPECIES_RESOLVE] " + className + " (Error #2)" );
+                    }
+                    // We can get here if there is a race condition loading a class.
+                    // Or maybe we are out of resources.  Back out of the CHM.get and retry.
+                    throw ex;
+                }
+            }
+
+            if (!speciesData.isResolved()) {
+                throw newInternalError("bad species class linkage for " + className + ": " + speciesData);
+            }
+            assert(speciesData == factory.loadSpeciesDataFromCode(speciesCode));
+            return speciesData;
+        }
+
+        /**
+         * Generate a concrete subclass of the top class for a given combination of bound types.
+         *
+         * A concrete species subclass roughly matches the following schema:
+         *
+         * <pre>
+         * class Species_[[types]] extends [[T]] {
+         *     final [[S]] speciesData() { return ... }
+         *     static [[T]] make([[fields]]) { return ... }
+         *     [[fields]]
+         *     final [[T]] transform([[args]]) { return ... }
+         * }
+         * </pre>
+         *
+         * The {@code [[types]]} signature is precisely the key for the species.
+         *
+         * The {@code [[fields]]} section consists of one field definition per character in
+         * the type signature, adhering to the naming schema described in the definition of
+         * {@link #chooseFieldName}.
+         *
+         * For example, a concrete species for two references and one integral bound value
+         * has a shape like the following:
+         *
+         * <pre>
+         * class TopClass { ... private static
+         * final class Species_LLI extends TopClass {
+         *     final Object argL0;
+         *     final Object argL1;
+         *     final int argI2;
+         *     private Species_LLI(CT ctarg, ..., Object argL0, Object argL1, int argI2) {
+         *         super(ctarg, ...);
+         *         this.argL0 = argL0;
+         *         this.argL1 = argL1;
+         *         this.argI2 = argI2;
+         *     }
+         *     final SpeciesData speciesData() { return BMH_SPECIES; }
+         *     &#64;Stable static SpeciesData BMH_SPECIES; // injected afterwards
+         *     static TopClass make(CT ctarg, ..., Object argL0, Object argL1, int argI2) {
+         *         return new Species_LLI(ctarg, ..., argL0, argL1, argI2);
+         *     }
+         *     final TopClass copyWith(CT ctarg, ...) {
+         *         return new Species_LLI(ctarg, ..., argL0, argL1, argI2);
+         *     }
+         *     // two transforms, for the sake of illustration:
+         *     final TopClass copyWithExtendL(CT ctarg, ..., Object narg) {
+         *         return BMH_SPECIES.transform(L_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
+         *     }
+         *     final TopClass copyWithExtendI(CT ctarg, ..., int narg) {
+         *         return BMH_SPECIES.transform(I_TYPE).invokeBasic(ctarg, ..., argL0, argL1, argI2, narg);
+         *     }
+         * }
+         * </pre>
+         *
+         * @param className of the species
+         * @param speciesData what species we are generating
+         * @return the generated concrete TopClass class
+         */
+        Class<? extends T> generateConcreteSpeciesCode(String className, ClassSpecializer<T,K,S>.SpeciesData speciesData) {
+            byte[] classFile = generateConcreteSpeciesCodeFile(className, speciesData);
+
+            // load class
+            InvokerBytecodeGenerator.maybeDump(classBCName(className), classFile);
+            Class<?> speciesCode;
+
+            ClassLoader cl = topClass().getClassLoader();
+            ProtectionDomain pd = null;
+            if (cl != null) {
+                pd = AccessController.doPrivileged(
+                        new PrivilegedAction<>() {
+                            @Override
+                            public ProtectionDomain run() {
+                                return topClass().getProtectionDomain();
+                            }
+                        });
+            }
+            try {
+                speciesCode = UNSAFE.defineClass(className, classFile, 0, classFile.length, cl, pd);
+            } catch (Exception ex) {
+                throw newInternalError(ex);
+            }
+
+            return speciesCode.asSubclass(topClass());
+        }
+
+        // These are named like constants because there is only one per specialization scheme:
+        private final String SPECIES_DATA = classBCName(metaType);
+        private final String SPECIES_DATA_SIG = classSig(SPECIES_DATA);
+        private final String SPECIES_DATA_NAME = sdAccessor.getName();
+        private final int SPECIES_DATA_MODS = sdAccessor.getModifiers();
+        private final List<String> TRANSFORM_NAMES;  // derived from transformMethods
+        private final List<MethodType> TRANSFORM_TYPES;
+        private final List<Integer> TRANSFORM_MODS;
+        {
+            // Tear apart transformMethods to get the names, types, and modifiers.
+            List<String> tns = new ArrayList<>();
+            List<MethodType> tts = new ArrayList<>();
+            List<Integer> tms = new ArrayList<>();
+            for (int i = 0; i < transformMethods.size(); i++) {
+                MemberName tm = transformMethods.get(i);
+                tns.add(tm.getName());
+                final MethodType tt = tm.getMethodType();
+                tts.add(tt);
+                tms.add(tm.getModifiers());
+            }
+            TRANSFORM_NAMES = List.of(tns.toArray(new String[0]));
+            TRANSFORM_TYPES = List.of(tts.toArray(new MethodType[0]));
+            TRANSFORM_MODS = List.of(tms.toArray(new Integer[0]));
+        }
+        private static final int ACC_PPP = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED;
+
+        /*non-public*/ byte[] generateConcreteSpeciesCodeFile(String className0, ClassSpecializer<T,K,S>.SpeciesData speciesData) {
+            final String className = classBCName(className0);
+            final String superClassName = classBCName(speciesData.deriveSuperClass());
+
+            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+            final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
+            cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, superClassName, null);
+
+            final String sourceFile = className.substring(className.lastIndexOf('.')+1);
+            cw.visitSource(sourceFile, null);
+
+            // emit static types and BMH_SPECIES fields
+            FieldVisitor fw = cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, sdFieldName, SPECIES_DATA_SIG, null, null);
+            fw.visitAnnotation(STABLE_SIG, true);
+            fw.visitEnd();
+
+            // handy holder for dealing with groups of typed values (ctor arguments and fields)
+            class Var {
+                final int index;
+                final String name;
+                final Class<?> type;
+                final String desc;
+                final BasicType basicType;
+                final int slotIndex;
+                Var(int index, int slotIndex) {
+                    this.index = index;
+                    this.slotIndex = slotIndex;
+                    name = null; type = null; desc = null;
+                    basicType = BasicType.V_TYPE;
+                }
+                Var(String name, Class<?> type, Var prev) {
+                    int slotIndex = prev.nextSlotIndex();
+                    int index = prev.nextIndex();
+                    if (name == null)  name = "x";
+                    if (name.endsWith("#"))
+                        name = name.substring(0, name.length()-1) + index;
+                    assert(!type.equals(void.class));
+                    String desc = classSig(type);
+                    BasicType basicType = BasicType.basicType(type);
+                    this.index = index;
+                    this.name = name;
+                    this.type = type;
+                    this.desc = desc;
+                    this.basicType = basicType;
+                    this.slotIndex = slotIndex;
+                }
+                Var lastOf(List<Var> vars) {
+                    int n = vars.size();
+                    return (n == 0 ? this : vars.get(n-1));
+                }
+                <X> List<Var> fromTypes(List<X> types) {
+                    Var prev = this;
+                    ArrayList<Var> result = new ArrayList<>(types.size());
+                    int i = 0;
+                    for (X x : types) {
+                        String vn = name;
+                        Class<?> vt;
+                        if (x instanceof Class) {
+                            vt = (Class<?>) x;
+                            // make the names friendlier if debugging
+                            assert((vn = vn + "_" + (i++)) != null);
+                        } else {
+                            @SuppressWarnings("unchecked")
+                            Var v = (Var) x;
+                            vn = v.name;
+                            vt = v.type;
+                        }
+                        prev = new Var(vn, vt, prev);
+                        result.add(prev);
+                    }
+                    return result;
+                }
+
+                int slotSize() { return basicType.basicTypeSlots(); }
+                int nextIndex() { return index + (slotSize() == 0 ? 0 : 1); }
+                int nextSlotIndex() { return slotIndex >= 0 ? slotIndex + slotSize() : slotIndex; }
+                boolean isInHeap() { return slotIndex < 0; }
+                void emitVarInstruction(int asmop, MethodVisitor mv) {
+                    if (asmop == ALOAD)
+                        asmop = typeLoadOp(basicType.basicTypeChar());
+                    else
+                        throw new AssertionError("bad op="+asmop+" for desc="+desc);
+                    mv.visitVarInsn(asmop, slotIndex);
+                }
+                public void emitFieldInsn(int asmop, MethodVisitor mv) {
+                    mv.visitFieldInsn(asmop, className, name, desc);
+                }
+            }
+
+            final Var NO_THIS = new Var(0, 0),
+                    AFTER_THIS = new Var(0, 1),
+                    IN_HEAP = new Var(0, -1);
+
+            // figure out the field types
+            final List<Class<?>> fieldTypes = speciesData.fieldTypes();
+            final List<Var> fields = new ArrayList<>(fieldTypes.size());
+            {
+                Var nextF = IN_HEAP;
+                for (Class<?> ft : fieldTypes) {
+                    String fn = chooseFieldName(ft, nextF.nextIndex());
+                    nextF = new Var(fn, ft, nextF);
+                    fields.add(nextF);
+                }
+            }
+
+            // emit bound argument fields
+            for (Var field : fields) {
+                cw.visitField(ACC_FINAL, field.name, field.desc, null, null).visitEnd();
+            }
+
+            MethodVisitor mv;
+
+            // emit implementation of speciesData()
+            mv = cw.visitMethod((SPECIES_DATA_MODS & ACC_PPP) + ACC_FINAL,
+                    SPECIES_DATA_NAME, "()" + SPECIES_DATA_SIG, null, null);
+            mv.visitCode();
+            mv.visitFieldInsn(GETSTATIC, className, sdFieldName, SPECIES_DATA_SIG);
+            mv.visitInsn(ARETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            // figure out the constructor arguments
+            MethodType superCtorType = ClassSpecializer.this.baseConstructorType();
+            MethodType thisCtorType = superCtorType.appendParameterTypes(fieldTypes);
+
+            // emit constructor
+            {
+                mv = cw.visitMethod(ACC_PRIVATE,
+                        "<init>", methodSig(thisCtorType), null, null);
+                mv.visitCode();
+                mv.visitVarInsn(ALOAD, 0); // this
+
+                final List<Var> ctorArgs = AFTER_THIS.fromTypes(superCtorType.parameterList());
+                for (Var ca : ctorArgs) {
+                    ca.emitVarInstruction(ALOAD, mv);
+                }
+
+                // super(ca...)
+                mv.visitMethodInsn(INVOKESPECIAL, superClassName,
+                        "<init>", methodSig(superCtorType), false);
+
+                // store down fields
+                Var lastFV = AFTER_THIS.lastOf(ctorArgs);
+                for (Var f : fields) {
+                    // this.argL1 = argL1
+                    mv.visitVarInsn(ALOAD, 0);  // this
+                    lastFV = new Var(f.name, f.type, lastFV);
+                    lastFV.emitVarInstruction(ALOAD, mv);
+                    f.emitFieldInsn(PUTFIELD, mv);
+                }
+
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            // emit make()  ...factory method wrapping constructor
+            {
+                MethodType ftryType = thisCtorType.changeReturnType(topClass());
+                mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC,
+                        "make", methodSig(ftryType), null, null);
+                mv.visitCode();
+                // make instance
+                mv.visitTypeInsn(NEW, className);
+                mv.visitInsn(DUP);
+                // load factory method arguments:  ctarg... and arg...
+                for (Var v : NO_THIS.fromTypes(ftryType.parameterList())) {
+                    v.emitVarInstruction(ALOAD, mv);
+                }
+
+                // finally, invoke the constructor and return
+                mv.visitMethodInsn(INVOKESPECIAL, className,
+                        "<init>", methodSig(thisCtorType), false);
+                mv.visitInsn(ARETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            // For each transform, emit the customized override of the transform method.
+            // This method mixes together some incoming arguments (from the transform's
+            // static type signature) with the field types themselves, and passes
+            // the resulting mish-mosh of values to a method handle produced by
+            // the species itself.  (Typically this method handle is the factory
+            // method of this species or a related one.)
+            for (int whichtm = 0; whichtm < TRANSFORM_NAMES.size(); whichtm++) {
+                final String     TNAME = TRANSFORM_NAMES.get(whichtm);
+                final MethodType TTYPE = TRANSFORM_TYPES.get(whichtm);
+                final int        TMODS = TRANSFORM_MODS.get(whichtm);
+                mv = cw.visitMethod((TMODS & ACC_PPP) | ACC_FINAL,
+                        TNAME, TTYPE.toMethodDescriptorString(), null, E_THROWABLE);
+                mv.visitCode();
+                // return a call to the corresponding "transform helper", something like this:
+                //   MY_SPECIES.transformHelper(whichtm).invokeBasic(ctarg, ..., argL0, ..., xarg)
+                mv.visitFieldInsn(GETSTATIC, className,
+                        sdFieldName, SPECIES_DATA_SIG);
+                emitIntConstant(whichtm, mv);
+                mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA,
+                        "transformHelper", "(I)" + MH_SIG, false);
+
+                List<Var> targs = AFTER_THIS.fromTypes(TTYPE.parameterList());
+                List<Var> tfields = new ArrayList<>(fields);
+                // mix them up and load them for the transform helper:
+                List<Var> helperArgs = speciesData.deriveTransformHelperArguments(transformMethods.get(whichtm), whichtm, targs, tfields);
+                List<Class<?>> helperTypes = new ArrayList<>(helperArgs.size());
+                for (Var ha : helperArgs) {
+                    helperTypes.add(ha.basicType.basicTypeClass());
+                    if (ha.isInHeap()) {
+                        assert(tfields.contains(ha));
+                        mv.visitVarInsn(ALOAD, 0);
+                        ha.emitFieldInsn(GETFIELD, mv);
+                    } else {
+                        assert(targs.contains(ha));
+                        ha.emitVarInstruction(ALOAD, mv);
+                    }
+                }
+
+                // jump into the helper (which is probably a factory method)
+                final Class<?> rtype = TTYPE.returnType();
+                final BasicType rbt = BasicType.basicType(rtype);
+                MethodType invokeBasicType = MethodType.methodType(rbt.basicTypeClass(), helperTypes);
+                mv.visitMethodInsn(INVOKEVIRTUAL, MH,
+                        "invokeBasic", methodSig(invokeBasicType), false);
+                if (rbt == BasicType.L_TYPE) {
+                    mv.visitTypeInsn(CHECKCAST, classBCName(rtype));
+                    mv.visitInsn(ARETURN);
+                } else {
+                    throw newInternalError("NYI: transform of type "+rtype);
+                }
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            cw.visitEnd();
+
+            return cw.toByteArray();
+        }
+
+        private int typeLoadOp(char t) {
+            switch (t) {
+            case 'L': return ALOAD;
+            case 'I': return ILOAD;
+            case 'J': return LLOAD;
+            case 'F': return FLOAD;
+            case 'D': return DLOAD;
+            default : throw newInternalError("unrecognized type " + t);
+            }
+        }
+
+        private void emitIntConstant(int con, MethodVisitor mv) {
+            if (ICONST_M1 - ICONST_0 <= con && con <= ICONST_5 - ICONST_0)
+                mv.visitInsn(ICONST_0 + con);
+            else if (con == (byte) con)
+                mv.visitIntInsn(BIPUSH, con);
+            else if (con == (short) con)
+                mv.visitIntInsn(SIPUSH, con);
+            else {
+                mv.visitLdcInsn(con);
+            }
+
+        }
+
+        //
+        // Getter MH generation.
+        //
+
+        private MethodHandle findGetter(Class<?> speciesCode, List<Class<?>> types, int index) {
+            Class<?> fieldType = types.get(index);
+            String fieldName = chooseFieldName(fieldType, index);
+            try {
+                return IMPL_LOOKUP.findGetter(speciesCode, fieldName, fieldType);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                throw newInternalError(e);
+            }
+        }
+
+        private List<MethodHandle> findGetters(Class<?> speciesCode, List<Class<?>> types) {
+            MethodHandle[] mhs = new MethodHandle[types.size()];
+            for (int i = 0; i < mhs.length; ++i) {
+                mhs[i] = findGetter(speciesCode, types, i);
+                assert(mhs[i].internalMemberName().getDeclaringClass() == speciesCode);
+            }
+            return List.of(mhs);
+        }
+
+        private List<MethodHandle> findFactories(Class<? extends T> speciesCode, List<Class<?>> types) {
+            MethodHandle[] mhs = new MethodHandle[1];
+            mhs[0] = findFactory(speciesCode, types);
+            return List.of(mhs);
+        }
+
+        List<LambdaForm.NamedFunction> makeNominalGetters(List<Class<?>> types, List<MethodHandle> getters) {
+            LambdaForm.NamedFunction[] nfs = new LambdaForm.NamedFunction[types.size()];
+            for (int i = 0; i < nfs.length; ++i) {
+                nfs[i] = new LambdaForm.NamedFunction(getters.get(i));
+            }
+            return List.of(nfs);
+        }
+
+        //
+        // Auxiliary methods.
+        //
+
+        protected void linkSpeciesDataToCode(ClassSpecializer<T,K,S>.SpeciesData speciesData, Class<? extends T> speciesCode) {
+            speciesData.speciesCode = speciesCode.asSubclass(topClass);
+            final List<Class<?>> types = speciesData.fieldTypes;
+            speciesData.factories = this.findFactories(speciesCode, types);
+            speciesData.getters = this.findGetters(speciesCode, types);
+            speciesData.nominalGetters = this.makeNominalGetters(types, speciesData.getters);
+        }
+
+        private Field reflectSDField(Class<? extends T> speciesCode) {
+            final Field field = reflectField(speciesCode, sdFieldName);
+            assert(field.getType() == metaType);
+            assert(Modifier.isStatic(field.getModifiers()));
+            return field;
+        }
+
+        private S readSpeciesDataFromCode(Class<? extends T> speciesCode) {
+            try {
+                MemberName sdField = IMPL_LOOKUP.resolveOrFail(REF_getStatic, speciesCode, sdFieldName, metaType);
+                Object base = MethodHandleNatives.staticFieldBase(sdField);
+                long offset = MethodHandleNatives.staticFieldOffset(sdField);
+                UNSAFE.loadFence();
+                return metaType.cast(UNSAFE.getObject(base, offset));
+            } catch (Error err) {
+                throw err;
+            } catch (Exception ex) {
+                throw newInternalError("Failed to load speciesData from speciesCode: " + speciesCode.getName(), ex);
+            } catch (Throwable t) {
+                throw uncaughtException(t);
+            }
+        }
+
+        protected S loadSpeciesDataFromCode(Class<? extends T> speciesCode) {
+            if (speciesCode == topClass()) {
+                return topSpecies;
+            }
+            S result = readSpeciesDataFromCode(speciesCode);
+            if (result.outer() != ClassSpecializer.this) {
+                throw newInternalError("wrong class");
+            }
+            return result;
+        }
+
+        protected void linkCodeToSpeciesData(Class<? extends T> speciesCode, ClassSpecializer<T,K,S>.SpeciesData speciesData, boolean salvage) {
+            try {
+                assert(readSpeciesDataFromCode(speciesCode) == null ||
+                    (salvage && readSpeciesDataFromCode(speciesCode).equals(speciesData)));
+
+                MemberName sdField = IMPL_LOOKUP.resolveOrFail(REF_putStatic, speciesCode, sdFieldName, metaType);
+                Object base = MethodHandleNatives.staticFieldBase(sdField);
+                long offset = MethodHandleNatives.staticFieldOffset(sdField);
+                UNSAFE.storeFence();
+                UNSAFE.putObject(base, offset, speciesData);
+                UNSAFE.storeFence();
+            } catch (Error err) {
+                throw err;
+            } catch (Exception ex) {
+                throw newInternalError("Failed to link speciesData to speciesCode: " + speciesCode.getName(), ex);
+            } catch (Throwable t) {
+                throw uncaughtException(t);
+            }
+        }
+
+        /**
+         * Field names in concrete species classes adhere to this pattern:
+         * type + index, where type is a single character (L, I, J, F, D).
+         * The factory subclass can customize this.
+         * The name is purely cosmetic, since it applies to a private field.
+         */
+        protected String chooseFieldName(Class<?> type, int index) {
+            BasicType bt = BasicType.basicType(type);
+            return "" + bt.basicTypeChar() + index;
+        }
+
+        MethodHandle findFactory(Class<? extends T> speciesCode, List<Class<?>> types) {
+            final MethodType type = baseConstructorType().changeReturnType(topClass()).appendParameterTypes(types);
+            try {
+                return IMPL_LOOKUP.findStatic(speciesCode, "make", type);
+            } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
+                throw newInternalError(e);
+            }
+        }
+    }
+
+    /** Hook that virtualizes the Factory class, allowing subclasses to extend it. */
+    protected Factory makeFactory() {
+        return new Factory();
+    }
+
+
+    // Other misc helpers:
+    private static final String MH = "java/lang/invoke/MethodHandle";
+    private static final String MH_SIG = "L" + MH + ";";
+    private static final String STABLE = "jdk/internal/vm/annotation/Stable";
+    private static final String STABLE_SIG = "L" + STABLE + ";";
+    private static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
+    static {
+        assert(MH_SIG.equals(classSig(MethodHandle.class)));
+        assert(MH.equals(classBCName(MethodHandle.class)));
+    }
+
+    static String methodSig(MethodType mt) {
+        return mt.toMethodDescriptorString();
+    }
+    static String classSig(Class<?> cls) {
+        if (cls.isPrimitive() || cls.isArray())
+            return MethodType.methodType(cls).toMethodDescriptorString().substring(2);
+        return classSig(classBCName(cls));
+    }
+    static String classSig(String bcName) {
+        assert(bcName.indexOf('.') < 0);
+        assert(!bcName.endsWith(";"));
+        assert(!bcName.startsWith("["));
+        return "L" + bcName + ";";
+    }
+    static String classBCName(Class<?> cls) {
+        return classBCName(className(cls));
+    }
+    static String classBCName(String str) {
+        assert(str.indexOf('/') < 0) : str;
+        return str.replace('.', '/');
+    }
+    static String className(Class<?> cls) {
+        assert(!cls.isArray() && !cls.isPrimitive());
+        return cls.getName();
+    }
+}
--- a/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,14 +25,14 @@
 
 package java.lang.invoke;
 
-import java.util.Map;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import sun.invoke.util.Wrapper;
+
 import java.util.ArrayList;
 import java.util.HashSet;
-import sun.invoke.util.Wrapper;
-
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Helper class to assist the GenerateJLIClassesPlugin to get access to
@@ -118,8 +118,7 @@
                 // require an even more complex naming scheme
                 LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]);
                 forms.add(reinvoker);
-                String speciesSig = BoundMethodHandle
-                        .speciesData(reinvoker).fieldSignature();
+                String speciesSig = BoundMethodHandle.speciesDataFor(reinvoker).key();
                 assert(speciesSig.equals("L"));
                 names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig);
 
@@ -205,20 +204,19 @@
                 DelegatingMethodHandle.NF_getTarget);
     }
 
-    static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
-            final String types) {
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(final String types) {
         for (char c : types.toCharArray()) {
             if ("LIJFD".indexOf(c) < 0) {
                 throw new IllegalArgumentException("All characters must "
                         + "correspond to a basic field type: LIJFD");
             }
         }
-        String shortTypes = LambdaForm.shortenSignature(types);
-        final String className =
-                BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
-        return Map.entry(className,
-                         BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
-                                 shortTypes, types, className));
+        final BoundMethodHandle.SpeciesData species = BoundMethodHandle.SPECIALIZER.findSpecies(types);
+        final String className = species.speciesCode().getName();
+        final ClassSpecializer.Factory factory = BoundMethodHandle.SPECIALIZER.factory();
+        final byte[] code = factory.generateConcreteSpeciesCodeFile(className, species);
+        return Map.entry(className.replace('.', '/'), code);
     }
 
 }
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Thu Nov 16 12:15:55 2017 +0000
@@ -183,8 +183,7 @@
             new java.security.PrivilegedAction<>() {
                 public Void run() {
                     try {
-                        String dumpName = className;
-                        //dumpName = dumpName.replace('/', '-');
+                        String dumpName = className.replace('.','/');
                         File dumpFile = new File(DUMP_CLASS_FILES_DIR, dumpName+".class");
                         System.out.println("dump: " + dumpFile);
                         dumpFile.getParentFile().mkdirs();
@@ -630,7 +629,7 @@
         String name = form.kind.methodName;
         switch (form.kind) {
             case BOUND_REINVOKER: {
-                name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature();
+                name = name + "_" + BoundMethodHandle.speciesDataFor(form).key();
                 return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
             }
             case DELEGATE:                  return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
--- a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Thu Nov 16 12:15:55 2017 +0000
@@ -143,12 +143,22 @@
         D_TYPE('D', double.class, Wrapper.DOUBLE),  // all primitive types
         V_TYPE('V', void.class,   Wrapper.VOID);    // not valid in all contexts
 
-        static final BasicType[] ALL_TYPES = BasicType.values();
-        static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
+        static final @Stable BasicType[] ALL_TYPES = BasicType.values();
+        static final @Stable BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1);
 
         static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
         static final int TYPE_LIMIT = ALL_TYPES.length;
 
+        // Derived int constants, which (unlike the enums) can be constant folded.
+        // We can remove them when JDK-8161245 is fixed.
+        static final byte
+                L_TYPE_NUM = (byte) L_TYPE.ordinal(),
+                I_TYPE_NUM = (byte) I_TYPE.ordinal(),
+                J_TYPE_NUM = (byte) J_TYPE.ordinal(),
+                F_TYPE_NUM = (byte) F_TYPE.ordinal(),
+                D_TYPE_NUM = (byte) D_TYPE.ordinal(),
+                V_TYPE_NUM = (byte) V_TYPE.ordinal();
+
         final char btChar;
         final Class<?> btClass;
         final Wrapper btWrapper;
@@ -679,6 +689,9 @@
         Class<?> rtype = signatureReturn(sig).btClass;
         return MethodType.makeImpl(rtype, ptypes, true);
     }
+    static MethodType basicMethodType(MethodType mt) {
+        return signatureType(basicTypeSignature(mt));
+    }
 
     /**
      * Check if i-th name is a call to MethodHandleImpl.selectAlternative.
@@ -1291,14 +1304,28 @@
         assert(sigp == sig.length);
         return String.valueOf(sig);
     }
+
+    /** Hack to make signatures more readable when they show up in method names.
+     * Signature should start with a sequence of uppercase ASCII letters.
+     * Runs of three or more are replaced by a single letter plus a decimal repeat count.
+     * A tail of anything other than uppercase ASCII is passed through unchanged.
+     * @param signature sequence of uppercase ASCII letters with possible repetitions
+     * @return same sequence, with repetitions counted by decimal numerals
+     */
     public static String shortenSignature(String signature) {
-        // Hack to make signatures more readable when they show up in method names.
         final int NO_CHAR = -1, MIN_RUN = 3;
         int c0, c1 = NO_CHAR, c1reps = 0;
         StringBuilder buf = null;
         int len = signature.length();
         if (len < MIN_RUN)  return signature;
         for (int i = 0; i <= len; i++) {
+            if (c1 != NO_CHAR && !('A' <= c1 && c1 <= 'Z')) {
+                // wrong kind of char; bail out here
+                if (buf != null) {
+                    buf.append(signature.substring(i - c1reps, len));
+                }
+                break;
+            }
             // shift in the next char:
             c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i));
             if (c1 == c0) { ++c1reps; continue; }
@@ -1342,7 +1369,7 @@
             this.arguments = that.arguments;
             this.constraint = constraint;
             assert(constraint == null || isParam());  // only params have constraints
-            assert(constraint == null || constraint instanceof BoundMethodHandle.SpeciesData || constraint instanceof Class);
+            assert(constraint == null || constraint instanceof ClassSpecializer.SpeciesData || constraint instanceof Class);
         }
         Name(MethodHandle function, Object... arguments) {
             this(new NamedFunction(function), arguments);
--- a/src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaFormBuffer.java	Thu Nov 16 12:15:55 2017 +0000
@@ -27,6 +27,8 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
+
 import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.LambdaForm.BasicType.*;
 
@@ -325,15 +327,15 @@
      *  whose function is in the corresponding position in newFns.
      *  Only do this if the arguments are exactly equal to the given.
      */
-    LambdaFormBuffer replaceFunctions(NamedFunction[] oldFns, NamedFunction[] newFns,
+    LambdaFormBuffer replaceFunctions(List<NamedFunction> oldFns, List<NamedFunction> newFns,
                                       Object... forArguments) {
         assert(inTrans());
-        if (oldFns.length == 0)  return this;
+        if (oldFns.isEmpty())  return this;
         for (int i = arity; i < length; i++) {
             Name n = names[i];
-            int nfi = indexOf(n.function, oldFns);
+            int nfi = oldFns.indexOf(n.function);
             if (nfi >= 0 && Arrays.equals(n.arguments, forArguments)) {
-                changeName(i, new Name(newFns[nfi], n.arguments));
+                changeName(i, new Name(newFns.get(nfi), n.arguments));
             }
         }
         return this;
--- a/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Thu Nov 16 12:15:55 2017 +0000
@@ -381,10 +381,11 @@
     /// Editing methods for method handles.  These need to have fast paths.
 
     private BoundMethodHandle.SpeciesData oldSpeciesData() {
-        return BoundMethodHandle.speciesData(lambdaForm);
+        return BoundMethodHandle.speciesDataFor(lambdaForm);
     }
+
     private BoundMethodHandle.SpeciesData newSpeciesData(BasicType type) {
-        return oldSpeciesData().extendWith(type);
+        return oldSpeciesData().extendWith((byte) type.ordinal());
     }
 
     BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) {
@@ -461,7 +462,7 @@
             buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress));
         } else {
             // cannot bind the MH arg itself, unless oldData is empty
-            assert(oldData == BoundMethodHandle.SpeciesData.EMPTY);
+            assert(oldData == BoundMethodHandle.SPECIALIZER.topSpecies());
             newBaseAddress = new Name(L_TYPE).withConstraint(newData);
             buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
             buf.insertParameter(0, newBaseAddress);
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -776,11 +776,11 @@
             if (PROFILE_GWT) {
                 int[] counts = new int[2];
                 mh = (BoundMethodHandle)
-                        BoundMethodHandle.speciesData_LLLL().constructor().invokeBasic(type, form,
+                        BoundMethodHandle.speciesData_LLLL().factory().invokeBasic(type, form,
                                 (Object) test, (Object) profile(target), (Object) profile(fallback), counts);
             } else {
                 mh = (BoundMethodHandle)
-                        BoundMethodHandle.speciesData_LLL().constructor().invokeBasic(type, form,
+                        BoundMethodHandle.speciesData_LLL().factory().invokeBasic(type, form,
                                 (Object) test, (Object) profile(target), (Object) profile(fallback));
             }
         } catch (Throwable ex) {
@@ -1089,7 +1089,7 @@
         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
         BoundMethodHandle mh;
         try {
-            mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) target, (Object) exType,
+            mh = (BoundMethodHandle) data.factory().invokeBasic(type, form, (Object) target, (Object) exType,
                     (Object) catcher, (Object) collectArgs, (Object) unboxResult);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
@@ -1784,6 +1784,11 @@
                 MemberName memberName = (MemberName)mname;
                 return memberName.getName();
             }
+            @Override
+            public Class<?> getDeclaringClass(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.getDeclaringClass();
+            }
 
             @Override
             public MethodType getMethodType(Object mname) {
@@ -1885,7 +1890,7 @@
         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
         BoundMethodHandle mh;
         try {
-            mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) clauseData,
+            mh = (BoundMethodHandle) data.factory().invokeBasic(type, form, (Object) clauseData,
                     (Object) collectArgs, (Object) unboxResult);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
@@ -2128,7 +2133,7 @@
         BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLL();
         BoundMethodHandle mh;
         try {
-            mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) target, (Object) cleanup,
+            mh = (BoundMethodHandle) data.factory().invokeBasic(type, form, (Object) target, (Object) cleanup,
                     (Object) collectArgs, (Object) unboxResult);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
--- a/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/SimpleMethodHandle.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,6 +25,8 @@
 
 package java.lang.invoke;
 
+import jdk.internal.vm.annotation.Stable;
+
 import static java.lang.invoke.LambdaForm.BasicType.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 
@@ -33,6 +35,7 @@
  * @author jrose
  */
 final class SimpleMethodHandle extends BoundMethodHandle {
+
     private SimpleMethodHandle(MethodType type, LambdaForm form) {
         super(type, form);
     }
@@ -41,10 +44,11 @@
         return new SimpleMethodHandle(type, form);
     }
 
-    /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.EMPTY;
+    /*non-public*/ static @Stable BoundMethodHandle.SpeciesData BMH_SPECIES;
 
-    /*non-public*/ public SpeciesData speciesData() {
-            return SPECIES_DATA;
+    @Override
+    /*non-public*/ BoundMethodHandle.SpeciesData speciesData() {
+            return BMH_SPECIES;
     }
 
     @Override
@@ -58,18 +62,13 @@
     }
 
     @Override
-    /*non-public*/ public int fieldCount() {
-        return 0;
-    }
-
-    @Override
     /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
         return BoundMethodHandle.bindSingle(mt, lf, narg); // Use known fast path.
     }
     @Override
     /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
         try {
-            return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, narg);
+            return (BoundMethodHandle) BMH_SPECIES.extendWith(I_TYPE_NUM).factory().invokeBasic(mt, lf, narg);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
         }
@@ -77,7 +76,7 @@
     @Override
     /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
         try {
-            return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, narg);
+            return (BoundMethodHandle) BMH_SPECIES.extendWith(J_TYPE_NUM).factory().invokeBasic(mt, lf, narg);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
         }
@@ -85,7 +84,7 @@
     @Override
     /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
         try {
-            return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, narg);
+            return (BoundMethodHandle) BMH_SPECIES.extendWith(F_TYPE_NUM).factory().invokeBasic(mt, lf, narg);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
         }
@@ -93,7 +92,7 @@
     @Override
     /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
         try {
-            return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, narg);
+            return (BoundMethodHandle) BMH_SPECIES.extendWith(D_TYPE_NUM).factory().invokeBasic(mt, lf, narg);
         } catch (Throwable ex) {
             throw uncaughtException(ex);
         }
--- a/src/java.base/share/classes/java/net/InetAddress.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/net/InetAddress.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1133,7 +1133,7 @@
 
     /**
      * Create an instance of the NameService interface based on
-     * the setting of the {@codejdk.net.hosts.file} system property.
+     * the setting of the {@code jdk.net.hosts.file} system property.
      *
      * <p>The default NameService is the PlatformNameService, which typically
      * delegates name and address resolution calls to the underlying
--- a/src/java.base/share/classes/java/security/Certificate.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/Certificate.java	Thu Nov 16 12:15:55 2017 +0000
@@ -57,13 +57,12 @@
  *
  * @author Benjamin Renaud
  * @since 1.1
- * @deprecated A new certificate handling package is created in the Java platform.
- *             This Certificate interface is entirely deprecated and
- *             is here to allow for a smooth transition to the new
- *             package.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by
+ *     {@code java.security.cert.Certificate} and related classes.
  * @see java.security.cert.Certificate
  */
-@Deprecated(since="1.2")
+@Deprecated(since="1.2", forRemoval=true)
 public interface Certificate {
 
     /**
--- a/src/java.base/share/classes/java/security/Identity.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/Identity.java	Thu Nov 16 12:15:55 2017 +0000
@@ -52,12 +52,13 @@
  *
  * @author Benjamin Renaud
  * @since 1.1
- * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@code java.security.KeyStore}, the
- * {@code java.security.cert} package, and
- * {@code java.security.Principal}.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by
+ *     {@code java.security.KeyStore}, the {@code java.security.cert} package,
+ *     and {@code java.security.Principal}.
  */
-@Deprecated(since="1.2")
+@Deprecated(since="1.2", forRemoval=true)
+@SuppressWarnings("removal")
 public abstract class Identity implements Principal, Serializable {
 
     /** use serialVersionUID from JDK 1.1.x for interoperability */
--- a/src/java.base/share/classes/java/security/IdentityScope.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/IdentityScope.java	Thu Nov 16 12:15:55 2017 +0000
@@ -57,12 +57,13 @@
  * @author Benjamin Renaud
  * @since 1.1
  *
- * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@code java.security.KeyStore}, the
- * {@code java.security.cert} package, and
- * {@code java.security.Principal}.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by
+ *     {@code java.security.KeyStore}, the {@code java.security.cert} package,
+ *     and {@code java.security.Principal}.
  */
-@Deprecated(since="1.2")
+@Deprecated(since="1.2", forRemoval=true)
+@SuppressWarnings("removal")
 public abstract
 class IdentityScope extends Identity {
 
--- a/src/java.base/share/classes/java/security/Signer.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/Signer.java	Thu Nov 16 12:15:55 2017 +0000
@@ -40,12 +40,13 @@
  * @author Benjamin Renaud
  * @since 1.1
  *
- * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@code java.security.KeyStore}, the
- * {@code java.security.cert} package, and
- * {@code java.security.Principal}.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by
+ *     {@code java.security.KeyStore}, the {@code java.security.cert} package,
+ *     and {@code java.security.Principal}.
  */
-@Deprecated(since="1.2")
+@Deprecated(since="1.2", forRemoval=true)
+@SuppressWarnings("removal")
 public abstract class Signer extends Identity {
 
     private static final long serialVersionUID = -1763464102261361480L;
--- a/src/java.base/share/classes/java/security/acl/Acl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/Acl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -84,11 +84,13 @@
  * @author Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
 
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
+@SuppressWarnings("removal")
 public interface Acl extends Owner {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/AclEntry.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/AclEntry.java	Thu Nov 16 12:15:55 2017 +0000
@@ -52,10 +52,12 @@
  * @author      Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
+@SuppressWarnings("removal")
 public interface AclEntry extends Cloneable {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/AclNotFoundException.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/AclNotFoundException.java	Thu Nov 16 12:15:55 2017 +0000
@@ -32,10 +32,11 @@
  * @author      Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
 public class AclNotFoundException extends Exception {
 
     private static final long serialVersionUID = 5684295034092681791L;
--- a/src/java.base/share/classes/java/security/acl/Group.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/Group.java	Thu Nov 16 12:15:55 2017 +0000
@@ -41,10 +41,11 @@
  * @author      Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
 public interface Group extends Principal {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/LastOwnerException.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/LastOwnerException.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,10 +34,11 @@
  * @author Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
 public class LastOwnerException extends Exception {
 
     private static final long serialVersionUID = -5141997548211140359L;
--- a/src/java.base/share/classes/java/security/acl/NotOwnerException.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/NotOwnerException.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,10 +33,11 @@
  * @author      Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
 public class NotOwnerException extends Exception {
 
     private static final long serialVersionUID = -5555597911163362399L;
--- a/src/java.base/share/classes/java/security/acl/Owner.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/Owner.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,10 +37,12 @@
  * @since 1.1
  * @see java.security.acl.Acl
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
+@SuppressWarnings("removal")
 public interface Owner {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/Permission.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/Permission.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,10 +33,11 @@
  * @author Satish Dharmaraj
  * @since 1.1
  *
- * @deprecated This package has been replaced by {@code java.security.Policy}
- *      and related classes since 1.2.
+ * @deprecated This class is deprecated and subject to removal in a future
+ *     version of Java SE. It has been replaced by {@code java.security.Policy}
+ *     and related classes since 1.2.
  */
-@Deprecated(since="9")
+@Deprecated(since="9", forRemoval=true)
 public interface Permission {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/package-info.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/security/acl/package-info.java	Thu Nov 16 12:15:55 2017 +0000
@@ -27,7 +27,8 @@
  * The classes and interfaces in this package have been deprecated. New
  * classes should not be added to this package. The {@code java.security}
  * package contains suitable replacements. See {@link java.security.Policy}
- * and related classes for details.
+ * and related classes for details. This package is subject to removal in a
+ * future version of Java SE.
  *
  * @since 1.1
  */
--- a/src/java.base/share/classes/java/util/stream/AbstractTask.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/util/stream/AbstractTask.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -27,6 +27,7 @@
 import java.util.Spliterator;
 import java.util.concurrent.CountedCompleter;
 import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinWorkerThread;
 
 /**
  * Abstract base class for most fork-join tasks used to implement stream ops.
@@ -88,13 +89,7 @@
                             K extends AbstractTask<P_IN, P_OUT, R, K>>
         extends CountedCompleter<R> {
 
-    /**
-     * Default target factor of leaf tasks for parallel decomposition.
-     * To allow load balancing, we over-partition, currently to approximately
-     * four tasks per processor, which enables others to help out
-     * if leaf tasks are uneven or some processors are otherwise busy.
-     */
-    static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2;
+    private static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2;
 
     /** The pipeline helper, common to all tasks in a computation */
     protected final PipelineHelper<P_OUT> helper;
@@ -157,6 +152,22 @@
     }
 
     /**
+     * Default target of leaf tasks for parallel decomposition.
+     * To allow load balancing, we over-partition, currently to approximately
+     * four tasks per processor, which enables others to help out
+     * if leaf tasks are uneven or some processors are otherwise busy.
+     */
+    public static int getLeafTarget() {
+        Thread t = Thread.currentThread();
+        if (t instanceof ForkJoinWorkerThread) {
+            return ((ForkJoinWorkerThread) t).getPool().getParallelism() << 2;
+        }
+        else {
+            return LEAF_TARGET;
+        }
+    }
+
+    /**
      * Constructs a new node of type T whose parent is the receiver; must call
      * the AbstractTask(T, Spliterator) constructor with the receiver and the
      * provided Spliterator.
@@ -181,7 +192,7 @@
      * @return suggested target leaf size
      */
     public static long suggestTargetSize(long sizeEstimate) {
-        long est = sizeEstimate / LEAF_TARGET;
+        long est = sizeEstimate / getLeafTarget();
         return est > 0L ? est : 1L;
     }
 
--- a/src/java.base/share/classes/java/util/stream/ForEachOps.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/util/stream/ForEachOps.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -28,7 +28,6 @@
 import java.util.Spliterator;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountedCompleter;
-import java.util.concurrent.ForkJoinTask;
 import java.util.function.Consumer;
 import java.util.function.DoubleConsumer;
 import java.util.function.IntConsumer;
@@ -378,7 +377,7 @@
             this.spliterator = spliterator;
             this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize());
             // Size map to avoid concurrent re-sizes
-            this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.LEAF_TARGET << 1));
+            this.completionMap = new ConcurrentHashMap<>(Math.max(16, AbstractTask.getLeafTarget() << 1));
             this.action = action;
             this.leftPredecessor = null;
         }
--- a/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -897,7 +897,7 @@
      * Note: The source spliterator may report {@code ORDERED} since that
      * spliterator be the result of a previous pipeline stage that was
      * collected to a {@code Node}. It is the order of the pipeline stage
-     * that governs whether the this slice spliterator is to be used or not.
+     * that governs whether this slice spliterator is to be used or not.
      */
     abstract static class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
         static final int CHUNK_SIZE = 1 << 7;
@@ -914,7 +914,7 @@
             this.unlimited = limit < 0;
             this.skipThreshold = limit >= 0 ? limit : 0;
             this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
-                ((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE;
+                                                        ((skip + limit) / AbstractTask.getLeafTarget()) + 1) : CHUNK_SIZE;
             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
         }
 
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -30,34 +30,40 @@
 
 public interface JavaLangInvokeAccess {
     /**
-     * Create a new MemberName instance. Used by {@see StackFrameInfo}.
+     * Create a new MemberName instance. Used by {@code StackFrameInfo}.
      */
     Object newMemberName();
 
     /**
-     * Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
+     * Returns the name for the given MemberName. Used by {@code StackFrameInfo}.
      */
     String getName(Object mname);
 
     /**
      * Returns the {@code MethodType} for the given MemberName.
-     * Used by {@see StackFrameInfo}.
+     * Used by {@code StackFrameInfo}.
      */
     MethodType getMethodType(Object mname);
 
     /**
      * Returns the descriptor for the given MemberName.
-     * Used by {@see StackFrameInfo}.
+     * Used by {@code StackFrameInfo}.
      */
     String getMethodDescriptor(Object mname);
 
     /**
-     * Returns {@code true} if the given MemberName is a native method. Used by
-     * {@see StackFrameInfo}.
+     * Returns {@code true} if the given MemberName is a native method.
+     * Used by {@code StackFrameInfo}.
      */
     boolean isNative(Object mname);
 
     /**
+     * Returns the declaring class for the given MemberName.
+     * Used by {@code StackFrameInfo}.
+     */
+    Class<?> getDeclaringClass(Object mname);
+
+    /**
      * Returns a {@code byte[]} representation of a class implementing
      * DirectMethodHandle of each pairwise combination of {@code MethodType} and
      * an {@code int} representing method type.  Used by
--- a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Thu Nov 16 12:15:55 2017 +0000
@@ -456,21 +456,21 @@
         {"the.tsa.certificate", "The TSA certificate"},
         {"the.input", "The input"},
         {"reply", "Reply"},
-        {"one.in.many", "%s #%d of %d"},
+        {"one.in.many", "%1$s #%2$d of %3$d"},
         {"alias.in.cacerts", "Issuer <%s> in cacerts"},
         {"alias.in.keystore", "Issuer <%s>"},
         {"with.weak", "%s (weak)"},
-        {"key.bit", "%d-bit %s key"},
-        {"key.bit.weak", "%d-bit %s key (weak)"},
+        {"key.bit", "%1$d-bit %2$s key"},
+        {"key.bit.weak", "%1$d-bit %2$s key (weak)"},
         {"unknown.size.1", "unknown size %s key"},
         {".PATTERN.printX509Cert.with.weak",
                 "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"},
         {"PKCS.10.with.weak",
                 "PKCS #10 Certificate Request (Version 1.0)\n" +
-                        "Subject: %s\nFormat: %s\nPublic Key: %s\nSignature algorithm: %s\n"},
-        {"verified.by.s.in.s.weak", "Verified by %s in %s with a %s"},
-        {"whose.sigalg.risk", "%s uses the %s signature algorithm which is considered a security risk."},
-        {"whose.key.risk", "%s uses a %s which is considered a security risk."},
+                        "Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"},
+        {"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"},
+        {"whose.sigalg.risk", "%1$s uses the %2$s signature algorithm which is considered a security risk."},
+        {"whose.key.risk", "%1$s uses a %2$s which is considered a security risk."},
         {"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
         {"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
         {"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
--- a/src/java.base/share/native/include/classfile_constants.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/native/include/classfile_constants.h	Thu Nov 16 12:15:55 2017 +0000
@@ -54,9 +54,29 @@
     JVM_ACC_STRICT        = 0x0800,
     JVM_ACC_SYNTHETIC     = 0x1000,
     JVM_ACC_ANNOTATION    = 0x2000,
-    JVM_ACC_ENUM          = 0x4000
+    JVM_ACC_ENUM          = 0x4000,
+    JVM_ACC_MODULE        = 0x8000
 };
 
+#define JVM_ACC_PUBLIC_BIT        0
+#define JVM_ACC_PRIVATE_BIT       1
+#define JVM_ACC_PROTECTED_BIT     2
+#define JVM_ACC_STATIC_BIT        3
+#define JVM_ACC_FINAL_BIT         4
+#define JVM_ACC_SYNCHRONIZED_BIT  5
+#define JVM_ACC_SUPER_BIT         5
+#define JVM_ACC_VOLATILE_BIT      6
+#define JVM_ACC_BRIDGE_BIT        6
+#define JVM_ACC_TRANSIENT_BIT     7
+#define JVM_ACC_VARARGS_BIT       7
+#define JVM_ACC_NATIVE_BIT        8
+#define JVM_ACC_INTERFACE_BIT     9
+#define JVM_ACC_ABSTRACT_BIT      10
+#define JVM_ACC_STRICT_BIT        11
+#define JVM_ACC_SYNTHETIC_BIT     12
+#define JVM_ACC_ANNOTATION_BIT    13
+#define JVM_ACC_ENUM_BIT          14
+
 /* Used in newarray instruction. */
 
 enum {
@@ -86,8 +106,9 @@
     JVM_CONSTANT_InterfaceMethodref     = 11,
     JVM_CONSTANT_NameAndType            = 12,
     JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
-    JVM_CONSTANT_MethodType             = 16,   // JSR 292
-    JVM_CONSTANT_InvokeDynamic          = 18
+    JVM_CONSTANT_MethodType             = 16,  // JSR 292
+    JVM_CONSTANT_InvokeDynamic          = 18,
+    JVM_CONSTANT_ExternalMax            = 18
 };
 
 /* JVM_CONSTANT_MethodHandle subtypes */
--- a/src/java.base/share/native/include/jvm.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/share/native/include/jvm.h	Thu Nov 16 12:15:55 2017 +0000
@@ -1155,20 +1155,25 @@
  * be renamed to JVM_* in the future?
  */
 
-/*
- * BE CAREFUL! The following functions do not implement the
- * full feature set of standard C printf formats.
- */
-int
+/* jio_snprintf() and jio_vsnprintf() behave like snprintf(3) and vsnprintf(3),
+ *  respectively, with the following differences:
+ * - The string written to str is always zero-terminated, also in case of
+ *   truncation (count is too small to hold the result string), unless count
+ *   is 0. In case of truncation count-1 characters are written and '\0'
+ *   appendend.
+ * - If count is too small to hold the whole string, -1 is returned across
+ *   all platforms. */
+
+JNIEXPORT int
 jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
 
-int
+JNIEXPORT int
 jio_snprintf(char *str, size_t count, const char *fmt, ...);
 
-int
+JNIEXPORT int
 jio_fprintf(FILE *, const char *fmt, ...);
 
-int
+JNIEXPORT int
 jio_vfprintf(FILE *, const char *fmt, va_list args);
 
 
--- a/src/java.base/solaris/native/libjsig/jsig.c	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/solaris/native/libjsig/jsig.c	Thu Nov 16 12:15:55 2017 +0000
@@ -37,7 +37,7 @@
 #include <dlfcn.h>
 #include <thread.h>
 #include <synch.h>
-#include "jvm_solaris.h"
+#include "jvm_md.h"
 
 #define bool int
 #define true 1
--- a/src/java.base/unix/native/include/jni_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/unix/native/include/jni_md.h	Thu Nov 16 12:15:55 2017 +0000
@@ -30,8 +30,13 @@
   #define __has_attribute(x) 0
 #endif
 #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
-  #define JNIEXPORT     __attribute__((visibility("default")))
-  #define JNIIMPORT     __attribute__((visibility("default")))
+  #ifdef ARM
+    #define JNIEXPORT     __attribute__((externally_visible,visibility("default")))
+    #define JNIIMPORT     __attribute__((externally_visible,visibility("default")))
+  #else
+    #define JNIEXPORT     __attribute__((visibility("default")))
+    #define JNIIMPORT     __attribute__((visibility("default")))
+  #endif
 #else
   #define JNIEXPORT
   #define JNIIMPORT
@@ -40,7 +45,7 @@
 #define JNICALL
 
 typedef int jint;
-#ifdef _LP64 /* 64-bit Solaris */
+#ifdef _LP64
 typedef long jlong;
 #else
 typedef long long jlong;
--- a/src/java.base/unix/native/include/jvm_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/unix/native/include/jvm_md.h	Thu Nov 16 12:15:55 2017 +0000
@@ -39,6 +39,10 @@
 
 #define JNI_ONLOAD_SYMBOLS   {"JNI_OnLoad"}
 #define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
+#define JVM_ONLOAD_SYMBOLS      {"JVM_OnLoad"}
+#define AGENT_ONLOAD_SYMBOLS    {"Agent_OnLoad"}
+#define AGENT_ONUNLOAD_SYMBOLS  {"Agent_OnUnload"}
+#define AGENT_ONATTACH_SYMBOLS  {"Agent_OnAttach"}
 
 #define JNI_LIB_PREFIX "lib"
 #ifdef __APPLE__
@@ -50,7 +54,15 @@
 #endif
 #define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX
 
+#if defined(AIX) || defined(SOLARIS)
 #define JVM_MAXPATHLEN MAXPATHLEN
+#else
+// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may
+//       cause problems if JVM and the rest of JDK are built on different
+//       Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1,
+//       so buffers declared in VM are always >= 4096.
+#define JVM_MAXPATHLEN MAXPATHLEN + 1
+#endif
 
 #define JVM_R_OK    R_OK
 #define JVM_W_OK    W_OK
@@ -67,19 +79,22 @@
 #include <errno.h>
 #include <signal.h>
 
-/* O Flags */
+/* Signals */
 
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
-/* Signals */
+#include <sys/socket.h>   // for socklen_t
 
 #define JVM_SIGINT     SIGINT
 #define JVM_SIGTERM    SIGTERM
 
+#define BREAK_SIGNAL     SIGQUIT           /* Thread dumping support.    */
+#ifdef SOLARIS
+#define ASYNC_SIGNAL     SIGJVM2           /* Event-based suspend/resume support */
+#endif // SOLARIS
+#define SHUTDOWN1_SIGNAL SIGHUP            /* Shutdown Hooks support.    */
+#define SHUTDOWN2_SIGNAL SIGINT
+#define SHUTDOWN3_SIGNAL SIGTERM
+
+/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */
+#define JSIG_VERSION_1_4_1   0x30140100
 
 #endif /* !_JAVASOFT_JVM_MD_H_ */
--- a/src/java.base/unix/native/libjava/UnixFileSystem_md.c	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/unix/native/libjava/UnixFileSystem_md.c	Thu Nov 16 12:15:55 2017 +0000
@@ -38,11 +38,13 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
 
 #include "jni.h"
 #include "jni_util.h"
 #include "jlong.h"
-#include "jvm.h"
 #include "io_util.h"
 #include "io_util_md.h"
 #include "java_io_FileSystem.h"
@@ -97,9 +99,9 @@
     jstring rv = NULL;
 
     WITH_PLATFORM_STRING(env, pathname, path) {
-        char canonicalPath[JVM_MAXPATHLEN];
+        char canonicalPath[PATH_MAX];
         if (canonicalize((char *)path,
-                         canonicalPath, JVM_MAXPATHLEN) < 0) {
+                         canonicalPath, PATH_MAX) < 0) {
             JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
         } else {
 #ifdef MACOSX
--- a/src/java.base/windows/native/include/jni_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/windows/native/include/jni_md.h	Thu Nov 16 12:15:55 2017 +0000
@@ -30,6 +30,7 @@
 #define JNIIMPORT __declspec(dllimport)
 #define JNICALL __stdcall
 
+// 'long' is always 32 bit on windows so this matches what jdk expects
 typedef long jint;
 typedef __int64 jlong;
 typedef signed char jbyte;
--- a/src/java.base/windows/native/include/jvm_md.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.base/windows/native/include/jvm_md.h	Thu Nov 16 12:15:55 2017 +0000
@@ -31,13 +31,20 @@
  * JNI conversion, which should be sorted out later.
  */
 
+#include <windows.h>
 #include <windef.h>
 #include <winbase.h>
 
 #include "jni.h"
 
+typedef int socklen_t;
+
 #define JNI_ONLOAD_SYMBOLS   {"_JNI_OnLoad@8", "JNI_OnLoad"}
 #define JNI_ONUNLOAD_SYMBOLS {"_JNI_OnUnload@8", "JNI_OnUnload"}
+#define JVM_ONLOAD_SYMBOLS      {"_JVM_OnLoad@12", "JVM_OnLoad"}
+#define AGENT_ONLOAD_SYMBOLS    {"_Agent_OnLoad@12", "Agent_OnLoad"}
+#define AGENT_ONUNLOAD_SYMBOLS  {"_Agent_OnUnload@4", "Agent_OnUnload"}
+#define AGENT_ONATTACH_SYMBOLS  {"_Agent_OnAttach@12", "Agent_OnAttach"}
 
 #define JNI_LIB_PREFIX ""
 #define JNI_LIB_SUFFIX ".dll"
@@ -63,21 +70,16 @@
 #define JVM_X_OK    1
 #define JVM_F_OK    0
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 JNIEXPORT void * JNICALL
 JVM_GetThreadInterruptEvent();
 
-/*
- * These routines are only reentrant on Windows
- */
-
-JNIEXPORT struct protoent * JNICALL
-JVM_GetProtoByName(char* name);
-
-JNIEXPORT struct hostent* JNICALL
-JVM_GetHostByAddr(const char* name, int len, int type);
-
-JNIEXPORT struct hostent* JNICALL
-JVM_GetHostByName(char* name);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
 
 /*
  * File I/O
@@ -89,19 +91,12 @@
 #include <errno.h>
 #include <signal.h>
 
-/* O Flags */
-
-#define JVM_O_RDONLY     O_RDONLY
-#define JVM_O_WRONLY     O_WRONLY
-#define JVM_O_RDWR       O_RDWR
-#define JVM_O_O_APPEND   O_APPEND
-#define JVM_O_EXCL       O_EXCL
-#define JVM_O_CREAT      O_CREAT
-
 /* Signals */
 
 #define JVM_SIGINT     SIGINT
 #define JVM_SIGTERM    SIGTERM
 
+#define SHUTDOWN1_SIGNAL SIGINT            /* Shutdown Hooks support. */
+#define SHUTDOWN2_SIGNAL SIGTERM
 
 #endif /* !_JAVASOFT_JVM_MD_H_ */
--- a/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -103,6 +103,9 @@
             }
         } else {
             mTransformerManager.addTransformer(transformer);
+            if (mTransformerManager.getTransformerCount() == 1) {
+                setHasTransformers(mNativeAgent, true);
+            }
         }
     }
 
@@ -114,8 +117,12 @@
         TransformerManager mgr = findTransformerManager(transformer);
         if (mgr != null) {
             mgr.removeTransformer(transformer);
-            if (mgr.isRetransformable() && mgr.getTransformerCount() == 0) {
-                setHasRetransformableTransformers(mNativeAgent, false);
+            if (mgr.getTransformerCount() == 0) {
+                if (mgr.isRetransformable()) {
+                    setHasRetransformableTransformers(mNativeAgent, false);
+                } else {
+                    setHasTransformers(mNativeAgent, false);
+                }
             }
             return true;
         }
@@ -362,6 +369,9 @@
     isRetransformClassesSupported0(long nativeAgent);
 
     private native void
+    setHasTransformers(long nativeAgent, boolean has);
+
+    private native void
     setHasRetransformableTransformers(long nativeAgent, boolean has);
 
     private native void
--- a/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,6 +78,17 @@
 
 /*
  * Class:     sun_instrument_InstrumentationImpl
+ * Method:    setHasTransformers
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_instrument_InstrumentationImpl_setHasTransformers
+  (JNIEnv * jnienv, jobject implThis, jlong agent, jboolean has) {
+    setHasTransformers(jnienv, (JPLISAgent*)(intptr_t)agent, has);
+}
+
+/*
+ * Class:     sun_instrument_InstrumentationImpl
  * Method:    setHasRetransformableTransformers
  * Signature: (Z)V
  */
--- a/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Thu Nov 16 12:15:55 2017 +0000
@@ -395,7 +395,7 @@
         jplis_assert(success);
 
         /*
-         *  Turn on the ClassFileLoadHook.
+         * Setup ClassFileLoadHook handler.
          */
         if (success) {
             success = setLivePhaseEventHandlers(agent);
--- a/src/java.instrument/share/native/libinstrument/JPLISAgent.c	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.instrument/share/native/libinstrument/JPLISAgent.c	Thu Nov 16 12:15:55 2017 +0000
@@ -404,8 +404,8 @@
 
 
     /*
-     *  Then turn off the VMInit handler and turn on the ClassFileLoadHook.
-     *  This way it is on before anyone registers a transformer.
+     *  Register a handler for ClassFileLoadHook (without enabling this event).
+     *  Turn off the VMInit handler.
      */
     if ( result ) {
         result = setLivePhaseEventHandlers(agent);
@@ -649,17 +649,6 @@
         jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
     }
 
-    if ( jvmtierror == JVMTI_ERROR_NONE ) {
-        /* turn on ClassFileLoadHook */
-        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
-                                                    jvmtienv,
-                                                    JVMTI_ENABLE,
-                                                    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
-                                                    NULL /* all threads */);
-        check_phase_ret_false(jvmtierror);
-        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
-    }
-
     return (jvmtierror == JVMTI_ERROR_NONE);
 }
 
@@ -1097,6 +1086,21 @@
 }
 
 void
+setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
+    jvmtiEnv *          jvmtienv = jvmti(agent);
+    jvmtiError          jvmtierror;
+
+    jplis_assert(jvmtienv != NULL);
+    jvmtierror = (*jvmtienv)->SetEventNotificationMode(
+                                            jvmtienv,
+                                            has? JVMTI_ENABLE : JVMTI_DISABLE,
+                                            JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+                                            NULL /* all threads */);
+    check_phase_ret(jvmtierror);
+    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
+}
+
+void
 setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
     jvmtiEnv *          retransformerEnv     = retransformableEnvironment(agent);
     jvmtiError          jvmtierror;
@@ -1107,6 +1111,7 @@
                                                     has? JVMTI_ENABLE : JVMTI_DISABLE,
                                                     JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
                                                     NULL /* all threads */);
+    check_phase_ret(jvmtierror);
     jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
 }
 
@@ -1185,6 +1190,10 @@
         deallocate(retransformerEnv, (void*)classArray);
     }
 
+    /* Return back if we executed the JVMTI API in a wrong phase
+     */
+    check_phase_ret(errorCode);
+
     if (errorCode != JVMTI_ERROR_NONE) {
         createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
     }
--- a/src/java.instrument/share/native/libinstrument/JPLISAgent.h	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.instrument/share/native/libinstrument/JPLISAgent.h	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,11 @@
                     JNIEnv *        jnienv,
                     jthread         thread);
 
-/* ClassFileLoadHook event handler. Installed during VMInit, then left in place forever. */
+/*
+ * ClassFileLoadHook event handler.
+ * Enabled when the first transformer is added;
+ * Disabled when the last transformer is removed.
+ */
 extern void JNICALL
 eventHandlerClassFileLoadHook(  jvmtiEnv *              jvmtienv,
                                 JNIEnv *                jnienv,
@@ -241,6 +245,9 @@
 isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent);
 
 extern void
+setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);
+
+extern void
 setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);
 
 extern void
--- a/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.management/share/classes/java/lang/management/RuntimeMXBean.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,6 +25,9 @@
 
 package java.lang.management;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 /**
  * The management interface for the runtime system of
  * the Java virtual machine.
@@ -61,6 +64,22 @@
  */
 public interface RuntimeMXBean extends PlatformManagedObject {
     /**
+     * Returns the {@linkplain ProcessHandle#pid process ID} representing
+     * the running Java virtual machine.
+     *
+     * @implSpec The default implementation returns {@link ProcessHandle#pid process ID}
+     * of the {@linkplain ProcessHandle#current current process}.
+     *
+     * @return the process ID representing the running Java virtual machine.
+     *
+     * @since 10
+     */
+    public default long getPid() {
+        return AccessController.doPrivileged((PrivilegedAction<Long>)
+                () -> ProcessHandle.current().pid());
+    }
+
+    /**
      * Returns the name representing the running Java virtual machine.
      * The returned name string can be any arbitrary string and
      * a Java virtual machine implementation can choose
--- a/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -176,6 +176,8 @@
      * @param args names of the arguments in the method call.
      *
      * @return The String used to invoke the method in the syntax of the scripting language.
+     *
+     * @throws NullPointerException if obj or m or args or any of the elements of args is null.
      */
     public String getMethodCallSyntax(String obj, String m, String... args);
 
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Thu Nov 16 12:15:55 2017 +0000
@@ -192,6 +192,8 @@
 
         {"StubRoutines::_checkcast_arraycopy", "_aot_stub_routines_checkcast_arraycopy"},
 
+        {"StubRoutines::_generic_arraycopy", "_aot_stub_routines_generic_arraycopy"},
+
         {"StubRoutines::_aescrypt_encryptBlock", "_aot_stub_routines_aescrypt_encryptBlock"},
         {"StubRoutines::_aescrypt_decryptBlock", "_aot_stub_routines_aescrypt_decryptBlock"},
         {"StubRoutines::_cipherBlockChaining_encryptAESCrypt", "_aot_stub_routines_cipherBlockChaining_encryptAESCrypt"},
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapPair.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapPair.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,8 +34,8 @@
 import java.util.Observer;
 
 public class ImmutableOopMapPair {
-  private static CIntegerField pcField;
-  private static CIntegerField offsetField;
+  private static CIntegerField pcOffsetField;
+  private static CIntegerField oopmapOffsetField;
   private static long classSize;
 
   static {
@@ -57,18 +57,18 @@
   }
 
   public int getPC() {
-    return (int) pcField.getValue(address);
+    return (int) pcOffsetField.getValue(address);
   }
 
   public int getOffset() {
-    return (int) offsetField.getValue(address);
+    return (int) oopmapOffsetField.getValue(address);
   }
 
   private static void initialize(TypeDataBase db) {
     Type type = db.lookupType("ImmutableOopMapPair");
 
-    pcField = type.getCIntegerField("_pc_offset");
-    offsetField = type.getCIntegerField("_oopmap_offset");
+    pcOffsetField = type.getCIntegerField("_pc_offset");
+    oopmapOffsetField = type.getCIntegerField("_oopmap_offset");
     classSize = type.getSize();
   }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/cms/CompactibleFreeListSpace.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/cms/CompactibleFreeListSpace.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,10 +41,11 @@
    private static AddressField dictionaryField;
    private static long         smallLinearAllocBlockFieldOffset;
 
-   private int    heapWordSize;     // 4 for 32bit, 8 for 64 bits
-   private int    IndexSetStart;    // for small indexed list
-   private int    IndexSetSize;
-   private int    IndexSetStride;
+   private int heapWordSize;     // 4 for 32bit, 8 for 64 bits
+   private int IndexSetStart;    // for small indexed list
+   private int IndexSetSize;
+   private int IndexSetStride;
+   private static long MinChunkSizeInBytes;
 
    static {
       VM.registerVMInitializedObserver(new Observer() {
@@ -57,8 +58,6 @@
    private static synchronized void initialize(TypeDataBase db) {
       long sizeofFreeChunk = db.lookupType("FreeChunk").getSize();
       VM vm = VM.getVM();
-      MinChunkSizeInBytes = numQuanta(sizeofFreeChunk, vm.getMinObjAlignmentInBytes()) *
-                     vm.getMinObjAlignmentInBytes();
 
      Type type = db.lookupType("CompactibleFreeListSpace");
      collectorField = type.getAddressField("_collector");
@@ -66,6 +65,7 @@
      dictionaryField      = type.getAddressField("_dictionary");
      indexedFreeListField = type.getAddressField("_indexedFreeList[0]");
      smallLinearAllocBlockFieldOffset = type.getField("_smallLinearAllocBlock").getOffset();
+     MinChunkSizeInBytes = (type.getCIntegerField("_min_chunk_size_in_bytes")).getValue();
    }
 
    public CompactibleFreeListSpace(Address addr) {
@@ -74,7 +74,7 @@
       heapWordSize   = vm.getHeapWordSize();
       IndexSetStart  = vm.getMinObjAlignmentInBytes() / heapWordSize;
       IndexSetStride = IndexSetStart;
-      IndexSetSize   = 257;
+      IndexSetSize   = vm.getIndexSetSize();
    }
 
    // Accessing block offset table
@@ -201,14 +201,8 @@
    // Unlike corresponding VM code, we operate on byte size rather than
    // HeapWord size for convenience.
 
-   private static long numQuanta(long x, long y) {
-      return  ((x+y-1)/y);
-   }
-
    public static long adjustObjectSizeInBytes(long sizeInBytes) {
       return Oop.alignObjectSize(Math.max(sizeInBytes, MinChunkSizeInBytes));
    }
 
-   // FIXME: should I read this directly from VM?
-   private static long MinChunkSizeInBytes;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/serial/SerialHeap.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
+ * 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 sun.jvm.hotspot.gc.serial;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.gc.shared.GenCollectedHeap;
+import sun.jvm.hotspot.gc.shared.CollectedHeapName;
+
+public class SerialHeap extends GenCollectedHeap {
+
+  public SerialHeap(Address addr) {
+    super(addr);
+  }
+
+  public CollectedHeapName kind() {
+    return CollectedHeapName.SERIAL_HEAP;
+  }
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,6 +33,7 @@
 
   public static final CollectedHeapName GEN_COLLECTED_HEAP = new CollectedHeapName("GenCollectedHeap");
   public static final CollectedHeapName CMS_HEAP = new CollectedHeapName("CMSHeap");
+  public static final CollectedHeapName SERIAL_HEAP = new CollectedHeapName("SerialHeap");
   public static final CollectedHeapName G1_COLLECTED_HEAP = new CollectedHeapName("G1CollectedHeap");
   public static final CollectedHeapName PARALLEL_SCAVENGE_HEAP = new CollectedHeapName("ParallelScavengeHeap");
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java	Thu Nov 16 12:15:55 2017 +0000
@@ -28,6 +28,7 @@
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.gc.cms.CMSHeap;
+import sun.jvm.hotspot.gc.serial.SerialHeap;
 import sun.jvm.hotspot.gc.shared.*;
 import sun.jvm.hotspot.gc.g1.G1CollectedHeap;
 import sun.jvm.hotspot.gc.parallel.*;
@@ -77,8 +78,8 @@
     collectedHeapField = type.getAddressField("_collectedHeap");
 
     heapConstructor = new VirtualConstructor(db);
-    heapConstructor.addMapping("GenCollectedHeap", GenCollectedHeap.class);
     heapConstructor.addMapping("CMSHeap", CMSHeap.class);
+    heapConstructor.addMapping("SerialHeap", SerialHeap.class);
     heapConstructor.addMapping("ParallelScavengeHeap", ParallelScavengeHeap.class);
     heapConstructor.addMapping("G1CollectedHeap", G1CollectedHeap.class);
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/TypeArrayKlass.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/TypeArrayKlass.java	Thu Nov 16 12:15:55 2017 +0000
@@ -44,14 +44,14 @@
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type t             = db.lookupType("TypeArrayKlass");
-    maxLength          = new CIntField(t.getCIntegerField("_max_length"), 0);
+    maxLength          = new IntField(t.getJIntField("_max_length"), 0);
   }
 
   public TypeArrayKlass(Address addr) {
     super(addr);
   }
 
-  private static CIntField  maxLength;
+  private static IntField  maxLength;
 
   public long getMaxLength()          { return  maxLength.getValue(this); }
 
@@ -98,7 +98,7 @@
 
   public void iterateFields(MetadataVisitor visitor) {
     super.iterateFields(visitor);
-      visitor.doCInt(maxLength, true);
+      visitor.doInt(maxLength, true);
     }
 
   public Klass arrayKlassImpl(boolean orNull, int n) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Arguments.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Arguments.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -42,11 +42,11 @@
     }
 
     public static String getJVMFlags() {
-        return buildString(jvmFlagsField, jvmFlagsCount);
+        return buildString(jvmFlagsArrayField, numJvmFlags);
     }
 
     public static String getJVMArgs() {
-        return buildString(jvmArgsField, jvmArgsCount);
+        return buildString(jvmArgsArrayField, numJvmArgs);
     }
 
     public static String getJavaCommand() {
@@ -56,20 +56,20 @@
     // Internals only below this point
 
     // Fields
-    private static AddressField jvmFlagsField;
-    private static AddressField jvmArgsField;
+    private static AddressField jvmFlagsArrayField;
+    private static AddressField jvmArgsArrayField;
     private static AddressField javaCommandField;
-    private static long jvmFlagsCount;
-    private static long jvmArgsCount;
+    private static long numJvmFlags;
+    private static long numJvmArgs;
 
     private static synchronized void initialize(TypeDataBase db) {
         Type argumentsType = db.lookupType("Arguments");
-        jvmFlagsField = argumentsType.getAddressField("_jvm_flags_array");
-        jvmArgsField = argumentsType.getAddressField("_jvm_args_array");
+        jvmFlagsArrayField = argumentsType.getAddressField("_jvm_flags_array");
+        jvmArgsArrayField = argumentsType.getAddressField("_jvm_args_array");
         javaCommandField = argumentsType.getAddressField("_java_command");
 
-        jvmArgsCount = argumentsType.getCIntegerField("_num_jvm_args").getValue();
-        jvmFlagsCount = argumentsType.getCIntegerField("_num_jvm_flags").getValue();
+        numJvmArgs = argumentsType.getCIntegerField("_num_jvm_args").getValue();
+        numJvmFlags = argumentsType.getCIntegerField("_num_jvm_flags").getValue();
     }
 
     private static String buildString(AddressField arrayField, long count) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompilerThread.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/CompilerThread.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, 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
@@ -39,19 +39,19 @@
       });
   }
 
-  private static AddressField _env_field;
+  private static AddressField envField;
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type      = db.lookupType("CompilerThread");
 
-    _env_field = type.getAddressField("_env");
+    envField = type.getAddressField("_env");
   }
 
   private ciEnv _env;
 
   public synchronized ciEnv env() {
     if (_env == null) {
-      Address v = _env_field.getValue(this.getAddress());
+      Address v = envField.getValue(this.getAddress());
       if (v != null) {
         _env = new ciEnv(v);
       }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JNIid.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2002, 2012, 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 sun.jvm.hotspot.runtime;
-
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.types.*;
-
-public class JNIid extends VMObject {
-  private static MetadataField holder;
-  private static AddressField next;
-  private static CIntegerField offset;
-  private static MetadataField resolvedMethod;
-  private static MetadataField resolvedReceiver;
-
-  private ObjectHeap heap;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static synchronized void initialize(TypeDataBase db) {
-
-    // FIXME: JNIid has been removed as part of redesign of JNI method,
-    // field ID generation. Please refer to src/share/vm/prims/jniId.hpp/.cpp
-    // For now, commenting out the below code.
-
-    /***********************************************************
-    Type type = db.lookupType("JNIid");
-
-    holder = type.getOopField("_holder");
-    next = type.getAddressField("_next");
-    offset = type.getCIntegerField("_offset");
-    resolvedMethod = type.getOopField("_resolved_method");
-    resolvedReceiver = type.getOopField("_resolved_receiver");
-    ***********************************************************/
-  }
-
-  public JNIid(Address addr, ObjectHeap heap) {
-    super(addr);
-    this.heap = heap;
-  }
-
-  public JNIid next() {
-    Address nextAddr = next.getValue(addr);
-    if (nextAddr == null) {
-      return null;
-    }
-    return new JNIid(nextAddr, heap);
-  }
-
-  public Klass     holder()           { return (Klass) holder.getValue(addr); }
-  public int       offset()           { return (int) offset.getValue(addr); }
-  public Method    method() {
-    return ((InstanceKlass) holder()).getMethods().at(offset());
-  }
-  public Method    resolvedMethod()   { return (Method)resolvedMethod.getValue(addr); }
-  public Klass     resolvedReceiver() { return (Klass) resolvedReceiver.getValue(addr); }
-}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/PerfMemory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/PerfMemory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
     private static AddressField  topField;
     private static CIntegerField capacityField;
     private static AddressField  prologueField;
-    private static JIntField     initializedField;
+    private static CIntegerField initializedField;
 
     static {
         VM.registerVMInitializedObserver(new Observer() {
@@ -52,7 +52,7 @@
         topField = type.getAddressField("_top");
         capacityField = type.getCIntegerField("_capacity");
         prologueField = type.getAddressField("_prologue");
-        initializedField = type.getJIntField("_initialized");
+        initializedField = type.getCIntegerField("_initialized");
     }
 
     // Accessors
@@ -73,7 +73,7 @@
     }
 
     public static boolean initialized() {
-        return ((int) initializedField.getValue()) != 0;
+        return (initializedField.getValue()) != 0;
     }
 
     public static PerfDataPrologue prologue() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, 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
@@ -105,6 +105,7 @@
   private int          heapOopSize;
   private int          klassPtrSize;
   private int          oopSize;
+  private final int    IndexSetSize;
   /** This is only present in a non-core build */
   private CodeCache    codeCache;
   /** This is only present in a C1 build */
@@ -376,6 +377,7 @@
     bytesPerWord = db.lookupIntConstant("BytesPerWord").intValue();
     heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
     oopSize  = db.lookupIntConstant("oopSize").intValue();
+    IndexSetSize = db.lookupIntConstant("CompactibleFreeListSpace::IndexSetSize").intValue();
 
     intType = db.lookupType("int");
     uintType = db.lookupType("uint");
@@ -594,6 +596,10 @@
     return heapOopSize;
   }
 
+  public int getIndexSetSize() {
+    return IndexSetSize;
+  }
+
   public int getKlassPtrSize() {
     return klassPtrSize;
   }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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,7 +43,7 @@
   private static AddressField  osThreadField;
 
   // Field from OSThread
-  private static Field         osThreadThreadIdField;
+  private static Field         threadIdField;
 
   // This is currently unneeded but is being kept in case we change
   // the currentFrameGuess algorithm
@@ -64,7 +64,7 @@
     osThreadField           = type.getAddressField("_osthread");
 
     type = db.lookupType("OSThread");
-    osThreadThreadIdField = type.getField("_thread_id");
+    threadIdField = type.getField("_thread_id");
   }
 
   public Address getLastJavaFP(Address addr) {
@@ -130,7 +130,7 @@
     Address osThreadAddr = osThreadField.getValue(addr);
     // Get the address of the thread_id within the OSThread
     Address threadIdAddr =
-      osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
+      osThreadAddr.addOffsetTo(threadIdField.getOffset());
     JVMDebugger debugger = VM.getVM().getDebugger();
     return debugger.getThreadForIdentifierAddress(threadIdAddr);
   }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_x86/Win32X86JavaThreadPDAccess.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, 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
@@ -42,7 +42,7 @@
   private static AddressField  osThreadField;
 
   // Field from OSThread
-  private static Field         osThreadThreadIdField;
+  private static Field         threadIdField;
 
   // This is currently unneeded but is being kept in case we change
   // the currentFrameGuess algorithm
@@ -63,7 +63,7 @@
     osThreadField           = type.getAddressField("_osthread");
 
     type = db.lookupType("OSThread");
-    osThreadThreadIdField = type.getField("_thread_id");
+    threadIdField = type.getField("_thread_id");
   }
 
   public Address getLastJavaFP(Address addr) {
@@ -129,7 +129,7 @@
     Address osThreadAddr = osThreadField.getValue(addr);
     // Get the address of the thread_id within the OSThread
     Address threadIdAddr =
-      osThreadAddr.addOffsetTo(osThreadThreadIdField.getOffset());
+      osThreadAddr.addOffsetTo(threadIdField.getOffset());
     JVMDebugger debugger = VM.getVM().getDebugger();
     return debugger.getThreadForIdentifierAddress(threadIdAddr);
   }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/overview.html	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
-Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-This code is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-version 2 for more details (a copy is included in the LICENSE file that
-accompanied this code).
-
-You should have received a copy of the GNU General Public License version
-2 along with this work; if not, write to the Free Software Foundation,
-Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-or visit www.oracle.com if you need additional information or have any
-questions.
--->
-
-</head>
-<body>
-
-The <code>jdk.vm.ci.code</code> project provides an API to the runtime's native code cache.
-It allows installation and execution of native code.
-
-</body>
-</html>
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Thu Nov 16 12:15:55 2017 +0000
@@ -470,7 +470,7 @@
     /**
      * Sets flags on {@code method} indicating that it should never be inlined or compiled by the VM.
      */
-    native void setNotInlineableOrCompileable(HotSpotResolvedJavaMethodImpl method);
+    native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Invalidates the profiling information for {@code method} and (re)initializes it such that
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java	Thu Nov 16 12:15:55 2017 +0000
@@ -30,13 +30,10 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 /**
- * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
- * weak reference to an instance of this class. This is necessary to keep the nmethod from being
- * unloaded while the associated {@link HotSpotNmethod} instance is alive.
- * <p>
- * Note that there is no (current) way for the reference from an nmethod to a {@link HotSpotNmethod}
- * instance to be anything but weak. This is due to the fact that HotSpot does not treat nmethods as
- * strong GC roots.
+ * Implementation of {@link InstalledCode} for code installed as an nmethod.
+ *
+ * When a {@link HotSpotNmethod} dies, it triggers unloading of the nmethod unless
+ * {@link #isDefault() == true}.
  */
 public class HotSpotNmethod extends HotSpotInstalledCode {
 
@@ -54,6 +51,11 @@
         this.isDefault = isDefault;
     }
 
+    /**
+     * Determines if the nmethod associated with this object is the compiled entry point for
+     * {@link #getMethod()}. If {@code false}, then the nmethod is unloaded when the VM determines
+     * this object has died.
+     */
     public boolean isDefault() {
         return isDefault;
     }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Thu Nov 16 12:15:55 2017 +0000
@@ -59,7 +59,7 @@
     /**
      * Sets flags on {@code method} indicating that it should never be inlined or compiled by the VM.
      */
-    void setNotInlineableOrCompileable();
+    void setNotInlinableOrCompilable();
 
     /**
      * Returns true if this method is one of the special methods that is ignored by security stack
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -320,8 +320,8 @@
     /**
      * Sets flags on {@code method} indicating that it should never be inlined or compiled by the VM.
      */
-    public void setNotInlineableOrCompileable() {
-        compilerToVM().setNotInlineableOrCompileable(this);
+    public void setNotInlinableOrCompilable() {
+        compilerToVM().setNotInlinableOrCompilable(this);
     }
 
     /**
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -538,7 +538,7 @@
         return result;
     }
 
-    synchronized HotSpotResolvedJavaField createField(JavaType type, long offset, int rawFlags, int index) {
+    HotSpotResolvedJavaField createField(JavaType type, long offset, int rawFlags, int index) {
         return new HotSpotResolvedJavaFieldImpl(this, type, offset, rawFlags, index);
     }
 
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/overview.html	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
-Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-This code is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-version 2 for more details (a copy is included in the LICENSE file that
-accompanied this code).
-
-You should have received a copy of the GNU General Public License version
-2 along with this work; if not, write to the Free Software Foundation,
-Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-or visit www.oracle.com if you need additional information or have any
-questions.
--->
-
-</head>
-<body>
-
-The <code>jdk.vm.ci.meta</code> project provides an API to the runtime data structures
-for various Java elements. Unlike standard Java reflection, it can model elements that are not yet loaded.
-It can also expose profiling information collected by the runtime system.
-
-</body>
-</html>
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,6 +34,9 @@
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 /**
  * Tests for {@link GraalDirectives#blackhole}.
@@ -129,6 +132,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
         ParameterNode arg = graph.getParameter(0);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -46,6 +46,9 @@
 import org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class ControlFlowAnchorDirectiveTest extends GraalCompilerTest {
 
@@ -239,6 +242,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         List<ControlFlowAnchorNode> anchors = graph.getNodes().filter(ControlFlowAnchorNode.class).snapshot();
         for (int i = 0; i < anchors.size(); i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,6 +37,9 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 /**
  * Tests for {@link GraalDirectives#opaque}.
@@ -128,6 +131,11 @@
     }
 
     @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
+    @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         OpaqueSnippet snippet = graph.method().getAnnotation(OpaqueSnippet.class);
         for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.replacements/src/org/graalvm/compiler/api/replacements/Snippet.java	Thu Nov 16 12:15:55 2017 +0000
@@ -36,6 +36,13 @@
 public @interface Snippet {
 
     /**
+     * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+     * call must use exactly the same arguments as the call that is being intrinsified. For well
+     * known snippets that are used after frame state assignment, we want to relax this restriction.
+     */
+    boolean allowPartialIntrinsicArgumentMismatch() default false;
+
+    /**
      * Denotes a snippet parameter representing 0 or more arguments that will be bound during
      * snippet template instantiation. During snippet template creation, its value must be an array
      * whose length specifies the number of arguments (the contents of the array are ignored) bound
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,10 +22,14 @@
  */
 package org.graalvm.compiler.asm.amd64;
 
-import static org.graalvm.compiler.core.common.NumUtil.isByte;
-import static org.graalvm.compiler.core.common.NumUtil.isInt;
-import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
-import static org.graalvm.compiler.core.common.NumUtil.isUByte;
+import static jdk.vm.ci.amd64.AMD64.CPU;
+import static jdk.vm.ci.amd64.AMD64.XMM;
+import static jdk.vm.ci.amd64.AMD64.r12;
+import static jdk.vm.ci.amd64.AMD64.r13;
+import static jdk.vm.ci.amd64.AMD64.rbp;
+import static jdk.vm.ci.amd64.AMD64.rip;
+import static jdk.vm.ci.amd64.AMD64.rsp;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
@@ -47,25 +51,24 @@
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
-import static jdk.vm.ci.amd64.AMD64.CPU;
-import static jdk.vm.ci.amd64.AMD64.XMM;
-import static jdk.vm.ci.amd64.AMD64.r12;
-import static jdk.vm.ci.amd64.AMD64.r13;
-import static jdk.vm.ci.amd64.AMD64.rbp;
-import static jdk.vm.ci.amd64.AMD64.rip;
-import static jdk.vm.ci.amd64.AMD64.rsp;
-import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
+import static org.graalvm.compiler.core.common.NumUtil.isByte;
+import static org.graalvm.compiler.core.common.NumUtil.isInt;
+import static org.graalvm.compiler.core.common.NumUtil.isShiftCount;
+import static org.graalvm.compiler.core.common.NumUtil.isUByte;
 
 import org.graalvm.compiler.asm.Assembler;
 import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.debug.GraalError;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.Register.RegisterCategory;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.PlatformKind;
 
 /**
  * This class implements an assembler that can encode most X86 instructions.
@@ -225,7 +228,7 @@
      * The x86 operand sizes.
      */
     public enum OperandSize {
-        BYTE(1) {
+        BYTE(1, AMD64Kind.BYTE) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 assert imm == (byte) imm;
@@ -238,7 +241,7 @@
             }
         },
 
-        WORD(2, 0x66) {
+        WORD(2, AMD64Kind.WORD, 0x66) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 assert imm == (short) imm;
@@ -251,7 +254,7 @@
             }
         },
 
-        DWORD(4) {
+        DWORD(4, AMD64Kind.DWORD) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 asm.emitInt(imm);
@@ -263,7 +266,7 @@
             }
         },
 
-        QWORD(8) {
+        QWORD(8, AMD64Kind.QWORD) {
             @Override
             protected void emitImmediate(AMD64Assembler asm, int imm) {
                 asm.emitInt(imm);
@@ -275,34 +278,35 @@
             }
         },
 
-        SS(4, 0xF3, true),
-
-        SD(8, 0xF2, true),
-
-        PS(16, true),
-
-        PD(16, 0x66, true);
+        SS(4, AMD64Kind.SINGLE, 0xF3, true),
+
+        SD(8, AMD64Kind.DOUBLE, 0xF2, true),
+
+        PS(16, AMD64Kind.V128_SINGLE, true),
+
+        PD(16, AMD64Kind.V128_DOUBLE, 0x66, true);
 
         private final int sizePrefix;
-
         private final int bytes;
         private final boolean xmm;
-
-        OperandSize(int bytes) {
-            this(bytes, 0);
+        private final AMD64Kind kind;
+
+        OperandSize(int bytes, AMD64Kind kind) {
+            this(bytes, kind, 0);
         }
 
-        OperandSize(int bytes, int sizePrefix) {
-            this(bytes, sizePrefix, false);
+        OperandSize(int bytes, AMD64Kind kind, int sizePrefix) {
+            this(bytes, kind, sizePrefix, false);
         }
 
-        OperandSize(int bytes, boolean xmm) {
-            this(bytes, 0, xmm);
+        OperandSize(int bytes, AMD64Kind kind, boolean xmm) {
+            this(bytes, kind, 0, xmm);
         }
 
-        OperandSize(int bytes, int sizePrefix, boolean xmm) {
+        OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) {
             this.sizePrefix = sizePrefix;
             this.bytes = bytes;
+            this.kind = kind;
             this.xmm = xmm;
         }
 
@@ -314,6 +318,19 @@
             return xmm;
         }
 
+        public AMD64Kind getKind() {
+            return kind;
+        }
+
+        public static OperandSize get(PlatformKind kind) {
+            for (OperandSize operandSize : OperandSize.values()) {
+                if (operandSize.kind.equals(kind)) {
+                    return operandSize;
+                }
+            }
+            throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString());
+        }
+
         /**
          * Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded
          * as sign-extended 32-bit values.
@@ -2230,6 +2247,14 @@
         emitOperandHelper(dst, src, 0);
     }
 
+    public final void movzbl(Register dst, Register src) {
+        AMD64RMOp.MOVZXB.emit(this, OperandSize.DWORD, dst, src);
+    }
+
+    public final void movzbq(Register dst, Register src) {
+        AMD64RMOp.MOVZXB.emit(this, OperandSize.QWORD, dst, src);
+    }
+
     public final void movzwl(Register dst, AMD64Address src) {
         prefix(src, dst);
         emitByte(0x0F);
@@ -3198,6 +3223,13 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void setb(ConditionFlag cc, Register dst) {
+        int encode = prefixAndEncode(dst.encoding, true);
+        emitByte(0x0F);
+        emitByte(0x90 | cc.getValue());
+        emitByte(0xC0 | encode);
+    }
+
     public final void cmovq(ConditionFlag cc, Register dst, AMD64Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -31,8 +31,8 @@
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
 
 import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64Kind;
@@ -281,6 +281,16 @@
 
     }
 
+    public final void setl(ConditionFlag cc, Register dst) {
+        setb(cc, dst);
+        movzbl(dst, dst);
+    }
+
+    public final void setq(ConditionFlag cc, Register dst) {
+        setb(cc, dst);
+        movzbq(dst, dst);
+    }
+
     public final void flog(Register dest, Register value, boolean base10) {
         if (base10) {
             fldlg2();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64AddressLoweringTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,126 @@
+/*
+ * 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.core.amd64.test;
+
+import static org.junit.Assume.assumeTrue;
+
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
+import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
+import org.graalvm.compiler.core.amd64.AMD64AddressNode;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import jdk.vm.ci.amd64.AMD64;
+
+public class AMD64AddressLoweringTest extends GraalCompilerTest {
+
+    private StructuredGraph graph;
+    private AMD64AddressLowering lowering;
+
+    @Before
+    public void checkAMD64() {
+        assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+        graph = new StructuredGraph.Builder(getInitialOptions(), getDebugContext()).build();
+        lowering = new AMD64AddressLowering();
+    }
+
+    @Test
+    public void convertBaseAndIndexToDisplacement() {
+        ValueNode base = graph.unique(const64(1000));
+        ValueNode index = graph.unique(const64(10));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times1, 1010);
+    }
+
+    @Test
+    public void convertBaseToDisplacement() {
+        ValueNode constantAddress = graph.addOrUniqueWithInputs(const64(1000));
+        AddressNode result = lowering.lower(constantAddress, null);
+        assertAddress(result, null, null, Scale.Times1, 1000);
+    }
+
+    @Test
+    public void convertBaseAndShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+        ValueNode index = graph.addOrUniqueWithInputs(new LeftShiftNode(const64(10), const32(1)));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times2, 1020);
+    }
+
+    @Test
+    public void convertBaseAndNegatedShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(const64(1000));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, 960);
+    }
+
+    @Test
+    public void convertNegatedBaseAndNegatedShiftedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, -1040);
+    }
+
+    @Test
+    public void convertNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(const64(10), const32(2))));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(const64(1000)));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, -1040);
+    }
+
+    @Test
+    public void convertTwoLevelsOfNegatedShiftedBaseAndNegatedIndexToDisplacement() {
+        ValueNode base = graph.addOrUniqueWithInputs(new NegateNode(new LeftShiftNode(new NegateNode(new LeftShiftNode(const64(500), const32(1))), const32(1))));
+        ValueNode index = graph.addOrUniqueWithInputs(new NegateNode(new AddNode(new NegateNode(const64(13)), const64(3))));
+        AddressNode result = lowering.lower(base, index);
+        assertAddress(result, null, null, Scale.Times4, 2010);
+    }
+
+    private static ConstantNode const64(long value) {
+        return ConstantNode.forIntegerBits(Long.SIZE, value);
+    }
+
+    private static ConstantNode const32(long value) {
+        return ConstantNode.forIntegerBits(Integer.SIZE, value);
+    }
+
+    private static void assertAddress(AddressNode actual, ValueNode expectedBase, ValueNode expectedIndex, Scale expectedScale, int expectedDisplacement) {
+        AMD64AddressNode address = (AMD64AddressNode) actual;
+        Assert.assertEquals(expectedBase, address.getBase());
+        Assert.assertEquals(expectedIndex, address.getIndex());
+        Assert.assertEquals(expectedScale, address.getScale());
+        Assert.assertEquals(expectedDisplacement, address.getDisplacement());
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressLowering.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,21 +23,22 @@
 
 package org.graalvm.compiler.core.amd64;
 
-import jdk.vm.ci.meta.JavaConstant;
-
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
+import org.graalvm.compiler.nodes.calc.NegateNode;
 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
 
+import jdk.vm.ci.meta.JavaConstant;
+
 public class AMD64AddressLowering extends AddressLowering {
-
     @Override
     public AddressNode lower(ValueNode address) {
         return lower(address, null);
@@ -46,24 +47,37 @@
     @Override
     public AddressNode lower(ValueNode base, ValueNode offset) {
         AMD64AddressNode ret = new AMD64AddressNode(base, offset);
+        StructuredGraph graph = base.graph();
+
         boolean changed;
         do {
-            changed = improve(base.getDebug(), ret);
+            changed = improve(graph, base.getDebug(), ret, false, false);
         } while (changed);
-        return base.graph().unique(ret);
+
+        return graph.unique(ret);
     }
 
     /**
-     * @param debug
+     * Tries to optimize addresses so that they match the AMD64-specific addressing mode better
+     * (base + index * scale + displacement).
+     *
+     * @param graph the current graph
+     * @param debug the current debug context
+     * @param ret the address that should be optimized
+     * @param isBaseNegated determines if the address base is negated. if so, all values that are
+     *            extracted from the base will be negated as well
+     * @param isIndexNegated determines if the index is negated. if so, all values that are
+     *            extracted from the index will be negated as well
+     * @return true if the address was modified
      */
-    protected boolean improve(DebugContext debug, AMD64AddressNode ret) {
-        ValueNode newBase = improveInput(ret, ret.getBase(), 0);
+    protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean isBaseNegated, boolean isIndexNegated) {
+        ValueNode newBase = improveInput(ret, ret.getBase(), 0, isBaseNegated);
         if (newBase != ret.getBase()) {
             ret.setBase(newBase);
             return true;
         }
 
-        ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2);
+        ValueNode newIdx = improveInput(ret, ret.getIndex(), ret.getScale().log2, isIndexNegated);
         if (newIdx != ret.getIndex()) {
             ret.setIndex(newIdx);
             return true;
@@ -83,55 +97,122 @@
         }
 
         if (ret.getScale() == Scale.Times1) {
-            if (ret.getBase() == null || ret.getIndex() == null) {
-                if (ret.getBase() instanceof AddNode) {
-                    AddNode add = (AddNode) ret.getBase();
-                    ret.setBase(add.getX());
-                    ret.setIndex(add.getY());
-                    return true;
-                } else if (ret.getIndex() instanceof AddNode) {
-                    AddNode add = (AddNode) ret.getIndex();
-                    ret.setBase(add.getX());
-                    ret.setIndex(add.getY());
-                    return true;
-                }
+            if (ret.getIndex() == null && ret.getBase() instanceof AddNode) {
+                AddNode add = (AddNode) ret.getBase();
+                ret.setBase(add.getX());
+                ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
+                return true;
+            } else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
+                AddNode add = (AddNode) ret.getIndex();
+                ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
+                ret.setIndex(add.getY());
+                return true;
             }
 
             if (ret.getBase() instanceof LeftShiftNode && !(ret.getIndex() instanceof LeftShiftNode)) {
                 ValueNode tmp = ret.getBase();
-                ret.setBase(ret.getIndex());
-                ret.setIndex(tmp);
+                ret.setBase(considerNegation(graph, ret.getIndex(), isIndexNegated != isBaseNegated));
+                ret.setIndex(considerNegation(graph, tmp, isIndexNegated != isBaseNegated));
                 return true;
             }
         }
 
+        return improveNegation(graph, debug, ret, isBaseNegated, isIndexNegated);
+    }
+
+    private boolean improveNegation(StructuredGraph graph, DebugContext debug, AMD64AddressNode ret, boolean originalBaseNegated, boolean originalIndexNegated) {
+        boolean baseNegated = originalBaseNegated;
+        boolean indexNegated = originalIndexNegated;
+
+        ValueNode originalBase = ret.getBase();
+        ValueNode originalIndex = ret.getIndex();
+
+        if (ret.getBase() instanceof NegateNode) {
+            NegateNode negate = (NegateNode) ret.getBase();
+            ret.setBase(negate.getValue());
+            baseNegated = !baseNegated;
+        }
+
+        if (ret.getIndex() instanceof NegateNode) {
+            NegateNode negate = (NegateNode) ret.getIndex();
+            ret.setIndex(negate.getValue());
+            indexNegated = !indexNegated;
+        }
+
+        if (baseNegated != originalBaseNegated || indexNegated != originalIndexNegated) {
+            ValueNode base = ret.getBase();
+            ValueNode index = ret.getIndex();
+
+            boolean improved = improve(graph, debug, ret, baseNegated, indexNegated);
+            if (baseNegated != originalBaseNegated) {
+                if (base == ret.getBase()) {
+                    ret.setBase(originalBase);
+                } else if (ret.getBase() != null) {
+                    ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
+                }
+            }
+
+            if (indexNegated != originalIndexNegated) {
+                if (index == ret.getIndex()) {
+                    ret.setIndex(originalIndex);
+                } else if (ret.getIndex() != null) {
+                    ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
+                }
+            }
+            return improved;
+        } else {
+            assert ret.getBase() == originalBase && ret.getIndex() == originalIndex;
+        }
         return false;
     }
 
-    private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift) {
+    private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
+        if (negate && value != null) {
+            return graph.maybeAddOrUnique(NegateNode.create(value));
+        }
+        return value;
+    }
+
+    private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
         if (node == null) {
             return null;
         }
 
         JavaConstant c = node.asJavaConstant();
         if (c != null) {
-            return improveConstDisp(address, node, c, null, shift);
+            return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
         } else {
-            if (node.stamp() instanceof IntegerStamp && ((IntegerStamp) node.stamp()).getBits() == 64) {
-                if (node instanceof ZeroExtendNode) {
-                    if (((ZeroExtendNode) node).getInputBits() == 32) {
-                        /*
-                         * We can just swallow a zero-extend from 32 bit to 64 bit because the upper
-                         * half of the register will always be zero.
-                         */
-                        return ((ZeroExtendNode) node).getValue();
+            if (node.stamp() instanceof IntegerStamp) {
+                if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
+                    /*
+                     * we can't just swallow all zero-extends as we might encounter something like
+                     * the following: ZeroExtend(Add(negativeValue, positiveValue)).
+                     *
+                     * if we swallow the zero-extend in this case and subsequently optimize the add,
+                     * we might end up with a negative value that has less than 64 bits in base or
+                     * index. such a value would require sign extension instead of zero-extension
+                     * but the backend can only do zero-extension. if we ever want to optimize that
+                     * further, we would also need to be careful about over-/underflows.
+                     *
+                     * furthermore, we also can't swallow zero-extends with less than 32 bits as
+                     * most of these values are immediately sign-extended to 32 bit by the backend
+                     * (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
+                     * expect).
+                     */
+                    ValueNode value = ((ZeroExtendNode) node).getValue();
+                    if (!mightBeOptimized(value)) {
+                        // if the value is not optimized further by the address lowering, then we
+                        // can safely rely on the backend doing the implicitly zero-extension.
+                        return value;
                     }
-                } else if (node instanceof AddNode) {
+                }
+
+                if (node instanceof AddNode) {
                     AddNode add = (AddNode) node;
                     if (add.getX().isConstant()) {
-                        return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift);
+                        return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift, negateExtractedDisplacement);
                     } else if (add.getY().isConstant()) {
-                        return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift);
+                        return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift, negateExtractedDisplacement);
                     }
                 }
             }
@@ -140,15 +221,30 @@
         return node;
     }
 
-    private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift) {
+    /**
+     * This method returns true for all nodes that might be optimized by the address lowering.
+     */
+    protected boolean mightBeOptimized(ValueNode value) {
+        return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
+    }
+
+    private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
         if (c.getJavaKind().isNumericInteger()) {
-            long disp = address.getDisplacement();
-            disp += c.asLong() << shift;
-            if (NumUtil.isInt(disp)) {
-                address.setDisplacement((int) disp);
+            long delta = c.asLong() << shift;
+            if (updateDisplacement(address, delta, negateExtractedDisplacement)) {
                 return other;
             }
         }
         return original;
     }
+
+    protected static boolean updateDisplacement(AMD64AddressNode address, long displacementDelta, boolean negateDelta) {
+        long sign = negateDelta ? -1 : 1;
+        long disp = address.getDisplacement() + displacementDelta * sign;
+        if (NumUtil.isInt(disp)) {
+            address.setDisplacement((int) disp);
+            return true;
+        }
+        return false;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,15 +33,17 @@
 import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue;
 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
+import static org.graalvm.compiler.lir.LIRValueUtil.isIntConstant;
 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
 
-import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
 import org.graalvm.compiler.core.common.spi.LIRKindTool;
@@ -58,13 +60,17 @@
 import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
 import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
 import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
+import org.graalvm.compiler.lir.amd64.AMD64Binary;
 import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
 import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp;
 import org.graalvm.compiler.lir.amd64.AMD64Call;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatBranchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
+import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
 import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
@@ -257,8 +263,7 @@
 
     @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
-        boolean mirrored = emitCompare(cmpKind, left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        Condition finalCondition = emitCompare(cmpKind, left, right, cond);
         if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
             append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
         } else {
@@ -290,14 +295,60 @@
 
     @Override
     public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(cmpKind, left, right);
-        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        boolean isFloatComparison = cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE;
 
-        Variable result = newVariable(trueValue.getValueKind());
-        if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
-            append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+        Condition finalCondition = cond;
+        Value finalTrueValue = trueValue;
+        Value finalFalseValue = falseValue;
+        if (isFloatComparison) {
+            // eliminate the parity check in case of a float comparison
+            Value finalLeft = left;
+            Value finalRight = right;
+            if (unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition)) {
+                if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.mirror())) {
+                    finalCondition = finalCondition.mirror();
+                    finalLeft = right;
+                    finalRight = left;
+                } else if (finalCondition != Condition.EQ && finalCondition != Condition.NE) {
+                    // negating EQ and NE does not make any sense as we would need to negate
+                    // unorderedIsTrue as well (otherwise, we would no longer fulfill the Java
+                    // NaN semantics)
+                    assert unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate());
+                    finalCondition = finalCondition.negate();
+                    finalTrueValue = falseValue;
+                    finalFalseValue = trueValue;
+                }
+            }
+            emitRawCompare(cmpKind, finalLeft, finalRight);
         } else {
-            append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
+            finalCondition = emitCompare(cmpKind, left, right, cond);
+        }
+
+        boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition);
+        Variable result = newVariable(finalTrueValue.getValueKind());
+        if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 1) && isIntConstant(finalFalseValue, 0)) {
+            if (isFloatComparison) {
+                append(new FloatCondSetOp(result, finalCondition));
+            } else {
+                append(new CondSetOp(result, finalCondition));
+            }
+        } else if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 0) && isIntConstant(finalFalseValue, 1)) {
+            if (isFloatComparison) {
+                if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate())) {
+                    append(new FloatCondSetOp(result, finalCondition.negate()));
+                } else {
+                    append(new FloatCondSetOp(result, finalCondition));
+                    Variable negatedResult = newVariable(result.getValueKind());
+                    append(new AMD64Binary.ConstOp(AMD64BinaryArithmetic.XOR, OperandSize.get(result.getPlatformKind()), negatedResult, result, 1));
+                    result = negatedResult;
+                }
+            } else {
+                append(new CondSetOp(result, finalCondition.negate()));
+            }
+        } else if (isFloatComparison) {
+            append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(finalTrueValue), load(finalFalseValue)));
+        } else {
+            append(new CondMoveOp(result, finalCondition, load(finalTrueValue), loadNonConst(finalFalseValue)));
         }
         return result;
     }
@@ -394,23 +445,21 @@
      *
      * @param a the left operand of the comparison
      * @param b the right operand of the comparison
+     * @param cond the condition of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    private boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
-        Variable left;
-        Value right;
-        boolean mirrored;
+    private Condition emitCompare(PlatformKind cmpKind, Value a, Value b, Condition cond) {
         if (LIRValueUtil.isVariable(b)) {
-            left = load(b);
-            right = loadNonConst(a);
-            mirrored = true;
+            emitRawCompare(cmpKind, b, a);
+            return cond.mirror();
         } else {
-            left = load(a);
-            right = loadNonConst(b);
-            mirrored = false;
+            emitRawCompare(cmpKind, a, b);
+            return cond;
         }
-        ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, left, right);
-        return mirrored;
+    }
+
+    private void emitRawCompare(PlatformKind cmpKind, Value left, Value right) {
+        ((AMD64ArithmeticLIRGeneratorTool) arithmeticLIRGen).emitCompareOp((AMD64Kind) cmpKind, load(left), loadNonConst(right));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRKindTool.java	Thu Nov 16 12:15:55 2017 +0000
@@ -28,7 +28,7 @@
 
 import jdk.vm.ci.amd64.AMD64Kind;
 
-public class AMD64LIRKindTool implements LIRKindTool {
+public abstract class AMD64LIRKindTool implements LIRKindTool {
 
     @Override
     public LIRKind getIntegerKind(int bits) {
@@ -67,12 +67,8 @@
     }
 
     @Override
-    public LIRKind getNarrowOopKind() {
-        return LIRKind.reference(AMD64Kind.DWORD);
-    }
+    public abstract LIRKind getNarrowOopKind();
 
     @Override
-    public LIRKind getNarrowPointerKind() {
-        return LIRKind.value(AMD64Kind.DWORD);
-    }
+    public abstract LIRKind getNarrowPointerKind();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompressEncoding.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,14 +34,6 @@
         this.shift = shift;
     }
 
-    public int compress(long ptr) {
-        if (ptr == 0L) {
-            return 0;
-        } else {
-            return (int) ((ptr - base) >>> shift);
-        }
-    }
-
     public boolean hasBase() {
         return base != 0;
     }
@@ -58,14 +50,6 @@
         return shift;
     }
 
-    public long uncompress(int ptr) {
-        if (ptr == 0) {
-            return 0L;
-        } else {
-            return ((ptr & 0xFFFFFFFFL) << shift) + base;
-        }
-    }
-
     @Override
     public String toString() {
         return "base: " + base + " shift: " + shift;
@@ -85,8 +69,7 @@
         if (obj instanceof CompressEncoding) {
             CompressEncoding other = (CompressEncoding) obj;
             return base == other.base && shift == other.shift;
-        } else {
-            return false;
         }
+        return false;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/FloatConvert.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,21 +25,23 @@
 import org.graalvm.compiler.debug.GraalError;
 
 public enum FloatConvert {
-    F2I(FloatConvertCategory.FloatingPointToInteger),
-    D2I(FloatConvertCategory.FloatingPointToInteger),
-    F2L(FloatConvertCategory.FloatingPointToInteger),
-    D2L(FloatConvertCategory.FloatingPointToInteger),
-    I2F(FloatConvertCategory.IntegerToFloatingPoint),
-    L2F(FloatConvertCategory.IntegerToFloatingPoint),
-    D2F(FloatConvertCategory.FloatingPointToFloatingPoint),
-    I2D(FloatConvertCategory.IntegerToFloatingPoint),
-    L2D(FloatConvertCategory.IntegerToFloatingPoint),
-    F2D(FloatConvertCategory.FloatingPointToFloatingPoint);
+    F2I(FloatConvertCategory.FloatingPointToInteger, 32),
+    D2I(FloatConvertCategory.FloatingPointToInteger, 64),
+    F2L(FloatConvertCategory.FloatingPointToInteger, 32),
+    D2L(FloatConvertCategory.FloatingPointToInteger, 64),
+    I2F(FloatConvertCategory.IntegerToFloatingPoint, 32),
+    L2F(FloatConvertCategory.IntegerToFloatingPoint, 64),
+    D2F(FloatConvertCategory.FloatingPointToFloatingPoint, 64),
+    I2D(FloatConvertCategory.IntegerToFloatingPoint, 32),
+    L2D(FloatConvertCategory.IntegerToFloatingPoint, 64),
+    F2D(FloatConvertCategory.FloatingPointToFloatingPoint, 32);
 
-    private FloatConvertCategory category;
+    private final FloatConvertCategory category;
+    private final int inputBits;
 
-    FloatConvert(FloatConvertCategory category) {
+    FloatConvert(FloatConvertCategory category, int inputBits) {
         this.category = category;
+        this.inputBits = inputBits;
     }
 
     public FloatConvertCategory getCategory() {
@@ -72,4 +74,8 @@
                 throw GraalError.shouldNotReachHere();
         }
     }
+
+    public int getInputBits() {
+        return inputBits;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java	Thu Nov 16 12:15:55 2017 +0000
@@ -41,7 +41,6 @@
         this.parent = parent;
         if (parent != null) {
             this.depth = parent.getDepth() + 1;
-            parent.getChildren().add(this);
         } else {
             this.depth = 1;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/ArithmeticOpTable.java	Thu Nov 16 12:15:55 2017 +0000
@@ -96,6 +96,22 @@
         }
     }
 
+    public BinaryOp<?>[] getBinaryOps() {
+        return new BinaryOp<?>[]{add, sub, mul, mulHigh, umulHigh, div, rem, and, or, xor};
+    }
+
+    public UnaryOp<?>[] getUnaryOps() {
+        return new UnaryOp<?>[]{neg, not, abs, sqrt};
+    }
+
+    public ShiftOp<?>[] getShiftOps() {
+        return new ShiftOp<?>[]{shl, shr, ushr};
+    }
+
+    public IntegerConvertOp<?>[] getIntegerConvertOps() {
+        return new IntegerConvertOp<?>[]{zeroExtend, signExtend, narrow};
+    }
+
     public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
 
     public interface ArithmeticOpWrapper {
@@ -562,7 +578,10 @@
         }
 
         /**
-         * Apply the operation to two {@linkplain Constant Constants}.
+         * Applies this operation to {@code a} and {@code b}.
+         *
+         * @return the result of applying this operation or {@code null} if applying it would raise
+         *         an exception (e.g., {@link ArithmeticException} for dividing by 0)
          */
         public abstract Constant foldConstant(Constant a, Constant b);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -291,7 +291,7 @@
 
     @Override
     public JavaConstant asConstant() {
-        if (nonNaN && Double.compare(lowerBound, upperBound) == 0) {
+        if (isConstant()) {
             switch (getBits()) {
                 case 32:
                     return JavaConstant.forFloat((float) lowerBound);
@@ -302,6 +302,68 @@
         return null;
     }
 
+    private boolean isConstant() {
+        /*
+         * There are many forms of NaNs and any operations on them can silently convert them into
+         * the canonical NaN.
+         */
+        return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
+    }
+
+    private static FloatStamp stampForConstant(Constant constant) {
+        FloatStamp result;
+        PrimitiveConstant value = (PrimitiveConstant) constant;
+        switch (value.getJavaKind()) {
+            case Float:
+                if (Float.isNaN(value.asFloat())) {
+                    result = new FloatStamp(32, Double.NaN, Double.NaN, false);
+                } else {
+                    result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+                }
+                break;
+            case Double:
+                if (Double.isNaN(value.asDouble())) {
+                    result = new FloatStamp(64, Double.NaN, Double.NaN, false);
+                } else {
+                    result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+                }
+                break;
+            default:
+                throw GraalError.shouldNotReachHere();
+        }
+        if (result.isConstant()) {
+            return result;
+        }
+        return null;
+    }
+
+    private static Stamp maybeFoldConstant(UnaryOp<?> op, FloatStamp stamp) {
+        if (stamp.isConstant()) {
+            JavaConstant constant = stamp.asConstant();
+            Constant folded = op.foldConstant(constant);
+            if (folded != null) {
+                return FloatStamp.stampForConstant(folded);
+            }
+        }
+        return null;
+    }
+
+    private static Stamp maybeFoldConstant(BinaryOp<?> op, FloatStamp stamp1, FloatStamp stamp2) {
+        if (stamp1.isConstant() && stamp2.isConstant()) {
+            JavaConstant constant1 = stamp1.asConstant();
+            JavaConstant constant2 = stamp2.asConstant();
+            Constant folded = op.foldConstant(constant1, constant2);
+            if (folded != null) {
+                FloatStamp stamp = stampForConstant(folded);
+                if (stamp != null && stamp.isConstant()) {
+                    assert stamp.asConstant().equals(folded);
+                    return stamp;
+                }
+            }
+        }
+        return null;
+    }
+
     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 
                     new UnaryOp.Neg() {
@@ -322,8 +384,13 @@
                         @Override
                         public Stamp foldStamp(Stamp s) {
                             FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
                         }
+
                     },
 
                     new BinaryOp.Add(false, true) {
@@ -344,8 +411,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -381,8 +453,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -418,9 +495,14 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp a, Stamp b) {
-                            // TODO
-                            return a.unrestricted();
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
+                            return stamp1.unrestricted();
                         }
 
                         @Override
@@ -450,17 +532,24 @@
                             assert a.getJavaKind() == b.getJavaKind();
                             switch (a.getJavaKind()) {
                                 case Float:
-                                    return JavaConstant.forFloat(a.asFloat() / b.asFloat());
+                                    float floatDivisor = b.asFloat();
+                                    return (floatDivisor == 0) ? null : JavaConstant.forFloat(a.asFloat() / floatDivisor);
                                 case Double:
-                                    return JavaConstant.forDouble(a.asDouble() / b.asDouble());
+                                    double doubleDivisor = b.asDouble();
+                                    return (doubleDivisor == 0) ? null : JavaConstant.forDouble(a.asDouble() / doubleDivisor);
                                 default:
                                     throw GraalError.shouldNotReachHere();
                             }
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -496,8 +585,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
-                            // TODO
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
                     },
@@ -521,6 +615,17 @@
 
                         @Override
                         public Stamp foldStamp(Stamp s) {
+                            FloatStamp stamp = (FloatStamp) s;
+                            JavaConstant constant = stamp.asConstant();
+                            if (constant != null) {
+                                Constant folded = foldConstant(constant);
+                                if (folded != null) {
+                                    FloatStamp result = stampForConstant(folded);
+                                    if (result != null && result.isConstant()) {
+                                        return result;
+                                    }
+                                }
+                            }
                             return s.unrestricted();
                         }
                     },
@@ -547,7 +652,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -576,7 +687,9 @@
                                 case Float:
                                     int fa = Float.floatToRawIntBits(a.asFloat());
                                     int fb = Float.floatToRawIntBits(b.asFloat());
-                                    return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb));
+                                    float floatOr = Float.intBitsToFloat(fa | fb);
+                                    assert (fa | fb) == Float.floatToRawIntBits((floatOr));
+                                    return JavaConstant.forFloat(floatOr);
                                 case Double:
                                     long da = Double.doubleToRawLongBits(a.asDouble());
                                     long db = Double.doubleToRawLongBits(b.asDouble());
@@ -587,7 +700,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -627,7 +746,13 @@
                         }
 
                         @Override
-                        public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                        public Stamp foldStamp(Stamp s1, Stamp s2) {
+                            FloatStamp stamp1 = (FloatStamp) s1;
+                            FloatStamp stamp2 = (FloatStamp) s2;
+                            Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return stamp1.unrestricted();
                         }
 
@@ -665,6 +790,10 @@
                         @Override
                         public Stamp foldStamp(Stamp s) {
                             FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             if (stamp.isNaN()) {
                                 return stamp;
                             }
@@ -689,6 +818,11 @@
 
                         @Override
                         public Stamp foldStamp(Stamp s) {
+                            FloatStamp stamp = (FloatStamp) s;
+                            Stamp folded = maybeFoldConstant(this, stamp);
+                            if (folded != null) {
+                                return folded;
+                            }
                             return s.unrestricted();
                         }
                     },
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -597,6 +597,10 @@
                         public Stamp foldStamp(Stamp s) {
                             IntegerStamp stamp = (IntegerStamp) s;
                             int bits = stamp.getBits();
+                            if (stamp.lowerBound == stamp.upperBound) {
+                                long value = CodeUtil.convert(-stamp.lowerBound(), stamp.getBits(), false);
+                                return StampFactory.forInteger(stamp.getBits(), value, value);
+                            }
                             if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
                                 // TODO(ls) check if the mask calculation is correct...
                                 return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
@@ -624,6 +628,11 @@
                             int bits = a.getBits();
                             assert bits == b.getBits();
 
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+                                long value = CodeUtil.convert(a.lowerBound() + b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             if (a.isUnrestricted()) {
                                 return a;
                             } else if (b.isUnrestricted()) {
@@ -711,6 +720,12 @@
 
                             int bits = a.getBits();
                             assert bits == b.getBits();
+
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
+                                long value = CodeUtil.convert(a.lowerBound() * b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             // if a==0 or b==0 result of a*b is always 0
                             if (a.upMask() == 0) {
                                 return a;
@@ -791,7 +806,7 @@
                                 long maxPosB = b.upperBound();
 
                                 // multiplication has shift semantics
-                                long newUpMask = ~CodeUtil.mask(Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask)) & CodeUtil.mask(bits);
+                                long newUpMask = ~CodeUtil.mask(Math.min(64, Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask))) & CodeUtil.mask(bits);
 
                                 if (a.canBePositive()) {
                                     if (b.canBePositive()) {
@@ -1023,6 +1038,9 @@
                             PrimitiveConstant a = (PrimitiveConstant) const1;
                             PrimitiveConstant b = (PrimitiveConstant) const2;
                             assert a.getJavaKind() == b.getJavaKind();
+                            if (b.asLong() == 0) {
+                                return null;
+                            }
                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() / b.asLong());
                         }
 
@@ -1031,9 +1049,12 @@
                             IntegerStamp a = (IntegerStamp) stamp1;
                             IntegerStamp b = (IntegerStamp) stamp2;
                             assert a.getBits() == b.getBits();
-                            if (b.isStrictlyPositive()) {
-                                long newLowerBound = a.lowerBound() / b.upperBound();
-                                long newUpperBound = a.upperBound() / b.lowerBound();
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+                                long value = CodeUtil.convert(a.lowerBound() / b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            } else if (b.isStrictlyPositive()) {
+                                long newLowerBound = a.lowerBound() < 0 ? a.lowerBound() / b.lowerBound() : a.lowerBound() / b.upperBound();
+                                long newUpperBound = a.upperBound() < 0 ? a.upperBound() / b.upperBound() : a.upperBound() / b.lowerBound();
                                 return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
                             } else {
                                 return a.unrestricted();
@@ -1054,6 +1075,9 @@
                             PrimitiveConstant a = (PrimitiveConstant) const1;
                             PrimitiveConstant b = (PrimitiveConstant) const2;
                             assert a.getJavaKind() == b.getJavaKind();
+                            if (b.asLong() == 0) {
+                                return null;
+                            }
                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() % b.asLong());
                         }
 
@@ -1062,6 +1086,12 @@
                             IntegerStamp a = (IntegerStamp) stamp1;
                             IntegerStamp b = (IntegerStamp) stamp2;
                             assert a.getBits() == b.getBits();
+
+                            if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
+                                long value = CodeUtil.convert(a.lowerBound() % b.lowerBound(), a.getBits(), false);
+                                return StampFactory.forInteger(a.getBits(), value, value);
+                            }
+
                             // zero is always possible
                             long newLowerBound = Math.min(a.lowerBound(), 0);
                             long newUpperBound = Math.max(a.upperBound(), 0);
@@ -1364,6 +1394,10 @@
                         public Stamp foldStamp(Stamp input) {
                             IntegerStamp stamp = (IntegerStamp) input;
                             int bits = stamp.getBits();
+                            if (stamp.lowerBound == stamp.upperBound) {
+                                long value = CodeUtil.convert(Math.abs(stamp.lowerBound()), stamp.getBits(), false);
+                                return StampFactory.forInteger(stamp.getBits(), value, value);
+                            }
                             if (stamp.lowerBound() == CodeUtil.minValue(bits)) {
                                 return input.unrestricted();
                             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Thu Nov 16 12:15:55 2017 +0000
@@ -49,8 +49,8 @@
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -73,6 +73,8 @@
 import org.graalvm.compiler.phases.verify.VerifyBailoutUsage;
 import org.graalvm.compiler.phases.verify.VerifyCallerSensitiveMethods;
 import org.graalvm.compiler.phases.verify.VerifyDebugUsage;
+import org.graalvm.compiler.phases.verify.VerifyGetOptionsUsage;
+import org.graalvm.compiler.phases.verify.VerifyGraphAddUsage;
 import org.graalvm.compiler.phases.verify.VerifyInstanceOfUsage;
 import org.graalvm.compiler.phases.verify.VerifyUpdateUsages;
 import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
@@ -381,6 +383,8 @@
         new VerifyUpdateUsages().apply(graph, context);
         new VerifyBailoutUsage().apply(graph, context);
         new VerifyInstanceOfUsage().apply(graph, context);
+        new VerifyGraphAddUsage().apply(graph, context);
+        new VerifyGetOptionsUsage().apply(graph, context);
         if (graph.method().isBridge()) {
             BridgeMethodUtils.getBridgedMethod(graph.method());
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
+import org.graalvm.compiler.nodes.GuardNode;
+import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
+import org.graalvm.compiler.nodes.java.LoadIndexedNode;
+import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.DeoptimizationReason;
+
+/**
+ * Check that multiple bounds checks are correctly grouped together.
+ */
+public class ConditionalEliminationTest14 extends ConditionalEliminationTestBase {
+
+    public static void test1Snippet(Object[] args) {
+        Object a5 = args[5];
+        Object a7 = args[7];
+        Object a6 = args[6];
+
+        /*
+         * The order of the conditions matters: The scheduler processes the floating reads for the
+         * array loads in the order of the conditions here, and we want the index 7 access to be
+         * processed before the index 6 access.
+         */
+        if (a5 != null && a7 != null && a6 != null) {
+            sink1 = 1;
+        }
+        sink0 = 0;
+    }
+
+    @Test
+    public void test1() {
+        StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        PhaseContext context = new PhaseContext(getProviders());
+
+        /* Convert the LoadIndexNode to ReadNode with floating guards. */
+        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+        /* Convert the ReadNode to FloatingReadNode. */
+        new FloatingReadPhase().apply(graph);
+        /* Apply the phase that we want to test. */
+        new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
+
+        Assert.assertEquals("All guards must be floating", 0, graph.getNodes(FixedGuardNode.TYPE).count());
+        Assert.assertEquals("All array accesses must have been lowered", 0, graph.getNodes().filter(LoadIndexedNode.class).count());
+        Assert.assertEquals("All reads must be floating", 0, graph.getNodes().filter(ReadNode.class).count());
+        Assert.assertEquals("Must have floating reads (3 array accesses, 1 array length)", 4, graph.getNodes().filter(FloatingReadNode.class).count());
+
+        NodeIterable<GuardNode> boundsChecks = graph.getNodes(GuardNode.TYPE).filter(n -> ((GuardNode) n).getReason() == DeoptimizationReason.BoundsCheckException);
+        Assert.assertEquals("Must have only 1 bounds check remaining", 1, boundsChecks.count());
+        LogicNode condition = boundsChecks.first().getCondition();
+        Assert.assertTrue("Bounds check must check for array length 8", condition instanceof IntegerBelowNode && ((IntegerBelowNode) condition).getY().valueEquals(ConstantNode.forInt(8)));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -27,12 +27,15 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 
@@ -45,6 +48,15 @@
     protected static int sink1;
     protected static int sink2;
 
+    /**
+     * These tests assume all code paths in called routines are reachable so disable removal of dead
+     * code based on method profiles.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     protected void testConditionalElimination(String snippet, String referenceSnippet) {
         testConditionalElimination(snippet, referenceSnippet, false, false);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/DumpPathTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,111 @@
+/*
+ * 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.core.test;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.util.EconomicMap;
+import org.junit.Test;
+
+/**
+ * Check that setting the dump path results in files ending up in the right directory with matching
+ * names.
+ */
+public class DumpPathTest extends GraalCompilerTest {
+
+    public static Object snippet() {
+        return new String("snippet");
+    }
+
+    @Test
+    public void testDump() throws IOException {
+        Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest");
+        String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
+        EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
+        overrides.put(DebugOptions.DumpPath, dumpDirectoryPath.toString());
+        overrides.put(DebugOptions.PrintGraphFile, true);
+        overrides.put(DebugOptions.PrintCanonicalGraphStrings, true);
+        overrides.put(DebugOptions.Dump, "*");
+
+        // Generate dump files.
+        test(new OptionValues(getInitialOptions(), overrides), "snippet");
+        // Check that Ideal files got created, in the right place.
+        checkForFiles(dumpDirectoryPath, extensions);
+
+        // Clean up the generated files.
+        scrubDirectory(dumpDirectoryPath);
+    }
+
+    /**
+     * Check that the given directory contains file or directory names with all the given
+     * extensions.
+     */
+    private static void checkForFiles(Path directoryPath, String[] extensions) throws IOException {
+        String[] paths = new String[extensions.length];
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+            for (Path filePath : stream) {
+                String fileName = filePath.getFileName().toString();
+                for (int i = 0; i < extensions.length; i++) {
+                    String extension = extensions[i];
+                    if (fileName.endsWith(extensions[i])) {
+                        assertTrue(paths[i] == null, "multiple files found for %s in %s", extension, directoryPath);
+                        paths[i] = fileName.replace(extensions[i], "");
+                    }
+                }
+            }
+        }
+        for (int i = 0; i < paths.length; i++) {
+            assertTrue(paths[i] != null, "missing file for extension %s in %s", extensions[i], directoryPath);
+        }
+        // Ensure that all file names are the same.
+        for (int i = 1; i < paths.length; i++) {
+            assertTrue(paths[0].equals(paths[i]), paths[0] + " != " + paths[i]);
+        }
+    }
+
+    /**
+     * Remove the temporary directory.
+     */
+    private static void scrubDirectory(Path directoryPath) {
+        try {
+            try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
+                for (Path filePath : stream) {
+                    if (Files.isRegularFile(filePath)) {
+                        Files.delete(filePath);
+                    } else if (Files.isDirectory(filePath)) {
+                        scrubDirectory(filePath);
+                    }
+                }
+            }
+            Files.delete(directoryPath);
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -72,7 +72,7 @@
         Assert.assertTrue(constructors.length == 1);
         final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
         OptionValues options = getInitialOptions();
-        StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options), allowAssumptions).method(javaMethod).build();
+        StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), allowAssumptions).method(javaMethod).build();
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
         new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -389,7 +389,7 @@
      * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
      */
     protected DebugContext getDebugContext() {
-        return getDebugContext(getInitialOptions());
+        return getDebugContext(getInitialOptions(), null, null);
     }
 
     @Override
@@ -862,7 +862,7 @@
         Result actual = executeActual(options, method, receiver, args);
         profile = method.getProfilingInfo(); // profile can change after execution
         for (DeoptimizationReason reason : shouldNotDeopt) {
-            Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
+            Assert.assertEquals("wrong number of deopt counts for " + reason, (int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
         }
         return actual;
     }
@@ -1216,15 +1216,15 @@
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
         OptionValues options = getInitialOptions();
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+        return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
     }
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, OptionValues options) {
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(compilationId);
+        return new Builder(options, getDebugContext(options, compilationId.toString(CompilationIdentifier.Verbosity.ID), method), allowAssumptions).method(method).compilationId(compilationId);
     }
 
     protected final Builder builder(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, OptionValues options) {
-        return new Builder(options, getDebugContext(options), allowAssumptions).method(method).compilationId(getCompilationId(method));
+        return new Builder(options, getDebugContext(options, null, method), allowAssumptions).method(method).compilationId(getCompilationId(method));
     }
 
     protected PhaseSuite<HighTierContext> getDebugGraphBuilderSuite() {
@@ -1234,6 +1234,7 @@
     @SuppressWarnings("try")
     protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
         ResolvedJavaMethod javaMethod = builder.getMethod();
+        builder.speculationLog(getSpeculationLog());
         if (builder.getCancellable() == null) {
             builder.cancellable(getCancellable(javaMethod));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalDebugHandlersFactoryTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -31,8 +31,12 @@
 import java.nio.file.Paths;
 import java.util.Comparator;
 
-import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.debug.PathUtilities;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.test.AddExports;
+import org.junit.Assume;
 import org.junit.Test;
 
 @AddExports("jdk.internal.vm.compiler/org.graalvm.compiler.printer")
@@ -40,23 +44,28 @@
 
     @Test
     public void createUniqueTest() throws Exception {
-        Field maxFileNameLengthField = GraalDebugHandlersFactory.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
-        maxFileNameLengthField.setAccessible(true);
+        Field maxFileNameLengthField = PathUtilities.class.getDeclaredField("MAX_FILE_NAME_LENGTH");
+        try {
+            maxFileNameLengthField.setAccessible(true);
+        } catch (RuntimeException ex) {
+            Assume.assumeFalse("If InaccessibleObjectException is thrown, skip the test, we are on JDK9", ex.getClass().getSimpleName().equals("InaccessibleObjectException"));
+        }
         int maxFileNameLength = maxFileNameLengthField.getInt(null);
-        Method createUniqueMethod = GraalDebugHandlersFactory.class.getDeclaredMethod("createUnique", Path.class, String.class, String.class, String.class, boolean.class);
+        Method createUniqueMethod = PathUtilities.class.getDeclaredMethod("createUnique", OptionValues.class, OptionKey.class, String.class, String.class, String.class, boolean.class);
         createUniqueMethod.setAccessible(true);
         Path tmpDir = Files.createTempDirectory(Paths.get("."), "createUniqueTest");
+        OptionValues options = new OptionValues(OptionValues.asMap(DebugOptions.DumpPath, tmpDir.toString()));
         try {
             for (boolean createDirectory : new boolean[]{true, false}) {
                 for (String ext : new String[]{"", ".bgv", ".graph-strings"}) {
                     for (int i = 0; i < maxFileNameLength + 5; i++) {
                         String id = new String(new char[i]).replace('\0', 'i');
                         String label = "";
-                        createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+                        createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
 
                         id = "";
                         label = new String(new char[i]).replace('\0', 'l');
-                        createUniqueMethod.invoke(null, tmpDir, id, label, ext, createDirectory);
+                        createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -144,6 +144,11 @@
     public void test01() {
         Super inheritsHC = new Super();
         Person overridesHC = new Person(0);
+
+        // Ensure the profile for getSuperAge includes both receiver types
+        getSuperAge(inheritsHC);
+        getSuperAge(overridesHC);
+
         test("getSuperAge", inheritsHC);
         test("getSuperAge", overridesHC);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.core.test;
 
+import java.util.HashMap;
+
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.core.phases.MidTier;
 import org.graalvm.compiler.nodes.InvokeNode;
@@ -139,6 +141,10 @@
     public void test08() {
         initialize(Appendable.class);
         checkForGuardedIntrinsicPattern("hashCodeInterface");
+
+        // Ensure the profile for the dispatch in hashCodeSnippet01
+        // has a receiver type that does not select Object.hashCode intrinsic
+        hashCodeSnippet01(new HashMap<>());
         checkForGuardedIntrinsicPattern("hashCodeSnippet01");
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MarkUnsafeAccessTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,6 +25,7 @@
 import static java.nio.file.StandardOpenOption.READ;
 import static java.nio.file.StandardOpenOption.WRITE;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
@@ -33,22 +34,20 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.InvalidInstalledCodeException;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-
-import sun.misc.Unsafe;
-
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
 import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import sun.misc.Unsafe;
 
 public class MarkUnsafeAccessTest extends GraalCompilerTest {
 
@@ -170,7 +169,9 @@
         try {
             mbb.position(BLOCK_SIZE);
             getter.get(mbb);
-            System.currentTimeMillis(); // materialize async exception
+
+            // Make a call that goes into native code to materialize async exception
+            new File("").exists();
         } catch (InternalError e) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -26,12 +26,23 @@
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class MergeCanonicalizerTest extends GraalCompilerTest {
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     public static int staticField;
 
     private int field;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ProfilingInfoTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,15 +24,17 @@
 
 import java.io.Serializable;
 
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
 import jdk.vm.ci.meta.JavaTypeProfile;
 import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.TriState;
 
-import org.junit.Assert;
-import org.junit.Test;
-
 /**
  * Tests profiling information provided by the runtime.
  * <p>
@@ -40,7 +42,7 @@
  * information may be gathered for any given method. For example, HotSpot's advanced compilation
  * policy can decide to only gather partial profiles in a first level compilation (see
  * AdvancedThresholdPolicy::common(...) in advancedThresholdPolicy.cpp). Because of this,
- * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only set's
+ * occasionally tests for {@link ProfilingInfo#getNullSeen(int)} can fail since HotSpot only sets
  * the null_seen bit when doing full profiling.
  */
 public class ProfilingInfoTest extends GraalCompilerTest {
@@ -182,6 +184,14 @@
         Assert.assertNull(typeProfile);
     }
 
+    public ProfilingInfoTest() {
+        // These tests are explicitly testing the profiling behavior of the
+        // interpreter. C1-based profiling differs slightly and when -Xcomp
+        // is present, profiles will be created by C1 compiled code, not the
+        // interpreter.
+        Assume.assumeTrue(!SubprocessUtil.getVMCommandLine().contains("-Xcomp"));
+    }
+
     @Test
     public void testExceptionSeen() {
         // NullPointerException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SubWordReturnTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,143 @@
+/*
+ * 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.core.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class SubWordReturnTest extends GraalCompilerTest {
+
+    private final JavaKind kind;
+    private final int value;
+
+    private final String generatedClassName;
+    private final String generatedClassNameInternal;
+
+    private final String testMethodName;
+
+    /**
+     * The {@link AsmLoader} generates a class looking like this for the types byte, short, int and
+     * char.
+     */
+    static class ByteGetter {
+
+        // private static int intField = 1000000;
+
+        private static byte get() {
+            // GETSTATIC intField
+            // IRETURN
+            return 0;
+        }
+
+        public static int testByteSnippet() {
+            return get();
+        }
+    }
+
+    @Parameters(name = "{0}, {1}")
+    public static List<Object[]> data() {
+        ArrayList<Object[]> ret = new ArrayList<>();
+        for (int i : new int[]{1000000, 1000001, -1000000, -1}) {
+            ret.add(new Object[]{JavaKind.Boolean, i});
+            ret.add(new Object[]{JavaKind.Byte, i});
+            ret.add(new Object[]{JavaKind.Short, i});
+            ret.add(new Object[]{JavaKind.Char, i});
+        }
+        return ret;
+    }
+
+    public SubWordReturnTest(JavaKind kind, int value) {
+        this.kind = kind;
+        this.value = value;
+
+        this.generatedClassName = SubWordReturnTest.class.getName() + "$" + kind.toString() + "Getter";
+        this.generatedClassNameInternal = generatedClassName.replace('.', '/');
+        this.testMethodName = "test" + kind.name() + "Snippet";
+    }
+
+    @Test
+    public void test() throws ClassNotFoundException {
+        Class<?> testClass = new AsmLoader(SubWordReturnTest.class.getClassLoader()).findClass(generatedClassName);
+        ResolvedJavaMethod method = getResolvedJavaMethod(testClass, testMethodName);
+        test(method, null);
+    }
+
+    class AsmLoader extends ClassLoader implements Opcodes {
+
+        Class<?> loaded;
+
+        AsmLoader(ClassLoader parent) {
+            super(parent);
+        }
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            if (name.equals(generatedClassName)) {
+                if (loaded == null) {
+                    byte[] gen = generateClass();
+                    loaded = defineClass(name, gen, 0, gen.length);
+                }
+                return loaded;
+            } else {
+                return super.findClass(name);
+            }
+        }
+
+        private byte[] generateClass() {
+            ClassWriter cw = new ClassWriter(0);
+            cw.visit(52, ACC_SUPER | ACC_PUBLIC, generatedClassNameInternal, null, "java/lang/Object", null);
+
+            FieldVisitor intField = cw.visitField(ACC_PRIVATE | ACC_STATIC, "intField", "I", null, value);
+            intField.visitEnd();
+
+            MethodVisitor get = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "get", "()" + kind.getTypeChar(), null, null);
+            get.visitCode();
+            get.visitFieldInsn(GETSTATIC, generatedClassNameInternal, "intField", "I");
+            get.visitInsn(IRETURN);
+            get.visitMaxs(1, 0);
+            get.visitEnd();
+
+            MethodVisitor snippet = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, testMethodName, "()I", null, null);
+            snippet.visitCode();
+            snippet.visitMethodInsn(INVOKESTATIC, generatedClassNameInternal, "get", "()" + kind.getTypeChar(), false);
+            snippet.visitInsn(IRETURN);
+            snippet.visitMaxs(1, 0);
+            snippet.visitEnd();
+
+            cw.visitEnd();
+            return cw.toByteArray();
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -87,7 +87,7 @@
         ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(INNER_CLASS_NAME), name);
         try {
             OptionValues options = getInitialOptions();
-            StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options)).method(method).build();
+            StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, method)).method(method).build();
             Plugins plugins = new Plugins(new InvocationPlugins());
             GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
             OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -32,9 +32,20 @@
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
 
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class UnsafeVirtualizationTest extends GraalCompilerTest {
 
-    public static class A {
+    public static class Base {
+        /*
+         * This padding ensure that the size of the Base class ends up as a multiple of 8, which
+         * makes the first field of the subclass 8-byte aligned.
+         */
+        double padding;
+    }
+
+    public static class A extends Base {
         int f1;
         int f2;
     }
@@ -56,39 +67,96 @@
         AF2Offset = o2;
     }
 
-    public static int unsafeSnippet0(int i1, int i2) {
+    public static int unsafeSnippet1(double i1) {
         A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1 + i2);
+        UNSAFE.putDouble(a, AF1Offset, i1);
         return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
     }
 
-    public static int unsafeSnippet1(int i1, int i2) {
+    public static long unsafeSnippet2a(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        a.f1 = i1;
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet2b(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        a.f2 = i1;
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet3a(int i1) {
         A a = new A();
-        UNSAFE.putDouble(a, AF1Offset, i1 + i2);
-        a.f2 = i1;
-        return (int) UNSAFE.getDouble(a, AF1Offset);
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putInt(a, AF1Offset, i1);
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static long unsafeSnippet3b(int i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putInt(a, AF2Offset, i1);
+        return UNSAFE.getLong(a, AF1Offset);
+    }
+
+    public static int unsafeSnippet4(double i1) {
+        A a = new A();
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        UNSAFE.putDouble(a, AF1Offset, i1);
+        return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset);
     }
 
     @Test
     public void testUnsafePEA01() {
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), false);
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet0", AllowAssumptions.NO), true);
+        testPartialEscapeReadElimination("unsafeSnippet1", false, 1.0);
+        testPartialEscapeReadElimination("unsafeSnippet1", true, 1.0);
     }
 
     @Test
     public void testUnsafePEA02() {
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), false);
-        testPartialEscapeReadElimination(parseEager("unsafeSnippet1", AllowAssumptions.NO), true);
+        testPartialEscapeReadElimination("unsafeSnippet2a", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet2a", true, 1);
+
+        testPartialEscapeReadElimination("unsafeSnippet2b", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet2b", true, 1);
     }
 
-    public void testPartialEscapeReadElimination(StructuredGraph graph, boolean canonicalizeBefore) {
+    @Test
+    public void testUnsafePEA03() {
+        testPartialEscapeReadElimination("unsafeSnippet3a", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet3a", true, 1);
+
+        testPartialEscapeReadElimination("unsafeSnippet3b", false, 1);
+        testPartialEscapeReadElimination("unsafeSnippet3b", true, 1);
+    }
+
+    @Test
+    public void testUnsafePEA04() {
+        testPartialEscapeReadElimination("unsafeSnippet4", false, 1.0);
+        testPartialEscapeReadElimination("unsafeSnippet4", true, 1.0);
+    }
+
+    public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) {
+        assert AF1Offset % 8 == 0 : "First of the two int-fields must be 8-byte aligned";
+
+        ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+        StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
         OptionValues options = graph.getOptions();
         PhaseContext context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         if (canonicalizeBefore) {
             canonicalizer.apply(graph, context);
         }
+        Result r = executeExpected(method, null, args);
         new PartialEscapePhase(true, true, canonicalizer, null, options).apply(graph, context);
+        try {
+            InstalledCode code = getCode(method, graph);
+            Object result = code.executeVarargs(args);
+            assertEquals(r, new Result(result, null));
+        } catch (Throwable e) {
+            assertFalse(true, e.toString());
+        }
     }
-
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -77,7 +77,7 @@
 
         @Override
         public String toString() {
-            return "{" + x + "," + y + "}";
+            return "{" + x + "," + y + "," + z + "}";
         }
 
         @Override
@@ -158,11 +158,19 @@
             context = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
             new DeadCodeEliminationPhase().apply(graph);
-            new CanonicalizerPhase().apply(graph, context);
+            canonicalizeGraph();
             new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
+            postEACanonicalizeGraph();
             returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
         } catch (Throwable e) {
             throw debug.handle(e);
         }
     }
+
+    protected void postEACanonicalizeGraph() {
+    }
+
+    protected void canonicalizeGraph() {
+        new CanonicalizerPhase().apply(graph, context);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -27,9 +27,20 @@
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.code.SourceStackTraceBailoutException;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class PEAAssertionsTest extends GraalCompilerTest {
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     public static Object field;
 
     public static void snippet1(int i) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/TrufflePEATest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.core.test.ea;
 
+import java.lang.reflect.Field;
+
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -33,10 +35,9 @@
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
+
 import sun.misc.Unsafe;
 
-import java.lang.reflect.Field;
-
 public class TrufflePEATest extends GraalCompilerTest {
 
     /**
@@ -56,6 +57,7 @@
     static class DynamicObject {
         int primitiveField0;
         int primitiveField1;
+        int primitiveField2;
     }
 
     private static final long offsetLong1 = Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * 1;
@@ -66,7 +68,15 @@
     static {
         try {
             Field primitiveField0 = DynamicObject.class.getDeclaredField("primitiveField0");
-            primitiveField0Offset = UNSAFE.objectFieldOffset(primitiveField0);
+            long offset = UNSAFE.objectFieldOffset(primitiveField0);
+            if (offset % 8 == 0) {
+                primitiveField0Offset = offset;
+            } else {
+                Field primitiveField1 = DynamicObject.class.getDeclaredField("primitiveField1");
+                offset = UNSAFE.objectFieldOffset(primitiveField1);
+                assert offset % 8 == 0;
+                primitiveField0Offset = offset;
+            }
         } catch (NoSuchFieldException | SecurityException e) {
             throw new AssertionError(e);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,14 +22,26 @@
  */
 package org.graalvm.compiler.core.test.ea;
 
-import jdk.vm.ci.meta.JavaConstant;
+import java.nio.ByteBuffer;
 
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
+import org.graalvm.compiler.nodes.extended.RawLoadNode;
+import org.graalvm.compiler.nodes.extended.RawStoreNode;
+import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
+import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.junit.Assert;
 import org.junit.Test;
 
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.ValuePhiNode;
-import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 public class UnsafeEATest extends EATestBase {
 
@@ -56,6 +68,64 @@
         }
     }
 
+    @Override
+    protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
+        // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been
+        // canonicalized into AccessFieldNodes.
+        testingUnsafe = true;
+        super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+        testingUnsafe = false;
+        super.testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis);
+        if (expectedConstantResult != null) {
+            // Check that a compiled version of this method returns the same value if we expect a
+            // constant result.
+            ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
+            JavaKind[] javaKinds = method.getSignature().toParameterKinds(false);
+            Object[] args = new Object[javaKinds.length];
+            int i = 0;
+            for (JavaKind k : javaKinds) {
+                args[i++] = JavaConstant.defaultForKind(k).asBoxedPrimitive();
+            }
+            Result result = executeExpected(method, null, args);
+            assertTrue(result.returnValue.equals(expectedConstantResult.asBoxedPrimitive()));
+        }
+    }
+
+    @Override
+    protected void canonicalizeGraph() {
+        if (testingUnsafe) {
+            // For testing purposes we'd like to ensure that our raw unsafe operations stay as
+            // unsafe nodes, so force them to appear to have LocationIdentity.any to disable
+            // transformation into field access nodes.
+            for (Node node : graph.getNodes().filter(x -> x instanceof UnsafeAccessNode).snapshot()) {
+                if (node instanceof RawStoreNode) {
+                    RawStoreNode store = (RawStoreNode) node;
+                    RawStoreNode newStore = graph.add(new RawStoreNode(store.object(), store.offset(), store.value(), store.accessKind(), NamedLocationIdentity.any(),
+                                    store.needsBarrier(), store.stateAfter(), true));
+                    graph.replaceFixedWithFixed(store, newStore);
+                } else if (node instanceof RawLoadNode) {
+                    RawLoadNode load = (RawLoadNode) node;
+                    RawLoadNode newLoad = graph.add(new RawLoadNode(load.object(), load.offset(), load.accessKind(), NamedLocationIdentity.any(),
+                                    true));
+                    graph.replaceFixedWithFixed(load, newLoad);
+                }
+            }
+        }
+        super.canonicalizeGraph();
+    }
+
+    @Override
+    protected void postEACanonicalizeGraph() {
+        // Simplify any UnpackEndianHalfNode so we end up with constants.
+        Graph.Mark mark = graph.getMark();
+        for (UnpackEndianHalfNode node : graph.getNodes().filter(UnpackEndianHalfNode.class)) {
+            node.lower(getTarget().arch.getByteOrder());
+        }
+        new CanonicalizerPhase().applyIncremental(graph, context, mark);
+    }
+
+    private boolean testingUnsafe;
+
     @Test
     public void testSimpleInt() {
         testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false);
@@ -90,6 +160,82 @@
     }
 
     @Test
+    public void testSimpleDoubleOverwriteWithInt() {
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithIntSnippet", JavaConstant.forInt(10), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
+    public void testSimpleDoubleOverwriteWithSecondInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putDouble(10.1);
+        int value = bb.getInt(4);
+
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithSecondIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset2);
+    }
+
+    @Test
+    public void testSimpleDoubleOverwriteWithFirstInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putDouble(10.1);
+        int value = bb.getInt(0);
+
+        testEscapeAnalysis("testSimpleDoubleOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleDoubleOverwriteWithFirstIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putDouble(x, fieldOffset1, 10.1);
+        UNSAFE.putInt(x, fieldOffset2, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
+    public void testSimpleLongOverwriteWithSecondInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putLong(0, 0x1122334455667788L);
+        int value = bb.getInt(4);
+
+        testEscapeAnalysis("testSimpleLongOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleLongOverwriteWithSecondIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, fieldOffset1, 10);
+        return UNSAFE.getInt(x, fieldOffset2);
+    }
+
+    @Test
+    public void testSimpleLongOverwriteWithFirstInt() {
+        ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder());
+        bb.putLong(0, 0x1122334455667788L);
+        int value = bb.getInt(0);
+
+        testEscapeAnalysis("testSimpleLongOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false);
+    }
+
+    public static int testSimpleLongOverwriteWithFirstIntSnippet() {
+        TestClassInt x = new TestClassInt();
+        UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L);
+        UNSAFE.putInt(x, fieldOffset2, 10);
+        return UNSAFE.getInt(x, fieldOffset1);
+    }
+
+    @Test
     public void testMergedDouble() {
         testEscapeAnalysis("testMergedDoubleSnippet", null, false);
         Assert.assertEquals(1, returnNodes.size());
@@ -111,6 +257,32 @@
         return UNSAFE.getDouble(x, fieldOffset1);
     }
 
+    static class ExtendedTestClassInt extends TestClassInt {
+        public long l;
+    }
+
+    @Test
+    public void testMergedVirtualObjects() {
+        testEscapeAnalysis("testMergedVirtualObjectsSnippet", null, false);
+    }
+
+    public static TestClassInt testMergedVirtualObjectsSnippet(int value) {
+        TestClassInt x;
+        if (value == 1) {
+            x = new TestClassInt();
+            UNSAFE.putDouble(x, fieldOffset1, 10);
+        } else {
+            x = new TestClassInt();
+            UNSAFE.putInt(x, fieldOffset1, 0);
+        }
+        UNSAFE.putInt(x, fieldOffset1, 0);
+        if (value == 2) {
+            UNSAFE.putInt(x, fieldOffset2, 0);
+        }
+        GraalDirectives.deoptimizeAndInvalidate();
+        return x;
+    }
+
     @Test
     public void testMaterializedDouble() {
         test("testMaterializedDoubleSnippet");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -146,7 +146,7 @@
 
     private StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) {
         OptionValues options = getInitialOptions();
-        StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options), AllowAssumptions.NO).method(method).build();
+        StructuredGraph newGraph = new StructuredGraph.Builder(options, getDebugContext(options, null, method), AllowAssumptions.NO).method(method).build();
         context.getGraphBuilderSuite().apply(newGraph, context);
         new DeadCodeEliminationPhase(Optional).apply(newGraph);
         canonicalizer.apply(newGraph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Thu Nov 16 12:15:55 2017 +0000
@@ -47,7 +47,7 @@
      public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
     @Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
                    "by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
-    public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(5);
+    public static final OptionKey<Integer> MaxCompilationProblemsPerAction = new OptionKey<>(2);
     @Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.User)
     public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);
     // @formatter:on
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -132,8 +132,17 @@
                             slotKinds[pos] = toSlotKind(value);
                             pos++;
                         } else {
-                            assert currentField.values().get(i - 1).getStackKind() == JavaKind.Double || currentField.values().get(i - 1).getStackKind() == JavaKind.Long : vobjNode + " " + i + " " +
-                                            currentField.values().get(i - 1);
+                            assert value.getStackKind() == JavaKind.Illegal;
+                            ValueNode previousValue = currentField.values().get(i - 1);
+                            assert (previousValue != null && previousValue.getStackKind().needsTwoSlots()) : vobjNode + " " + i +
+                                            " " + previousValue + " " + currentField.values().snapshot();
+                            if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
+                                // Don't allow the IllegalConstant to leak into the debug info
+                                JavaKind entryKind = vobjNode.entryKind(i);
+                                values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
+                                slotKinds[pos] = entryKind.getStackKind();
+                                pos++;
+                            }
                         }
                     }
                     if (pos != entryCount) {
@@ -164,19 +173,19 @@
             if (!type.isArray()) {
                 ResolvedJavaField[] fields = type.getInstanceFields(true);
                 int fieldIndex = 0;
-                for (int i = 0; i < values.length; i++) {
-                    ResolvedJavaField field = fields[fieldIndex++];
-                    JavaKind valKind = slotKinds[i].getStackKind();
+                for (int valueIndex = 0; valueIndex < values.length; valueIndex++, fieldIndex++) {
+                    ResolvedJavaField field = fields[fieldIndex];
+                    JavaKind valKind = slotKinds[valueIndex].getStackKind();
                     JavaKind fieldKind = storageKind(field.getType());
-                    if (fieldKind == JavaKind.Object) {
-                        assert valKind.isObject() : field + ": " + valKind + " != " + fieldKind;
+                    if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
+                        assert fieldIndex + 1 < fields.length : String.format("Not enough fields for fieldIndex = %d valueIndex = %d %s %s", fieldIndex, valueIndex, Arrays.toString(fields),
+                                        Arrays.toString(values));
+                        assert storageKind(fields[fieldIndex + 1].getType()) == JavaKind.Int : String.format("fieldIndex = %d valueIndex = %d %s %s %s", fieldIndex, valueIndex,
+                                        storageKind(fields[fieldIndex + 1].getType()), Arrays.toString(fields),
+                                        Arrays.toString(values));
+                        fieldIndex++;
                     } else {
-                        if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && fieldKind == JavaKind.Int) {
-                            assert storageKind(fields[fieldIndex].getType()) == JavaKind.Int;
-                            fieldIndex++;
-                        } else {
-                            assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
-                        }
+                        assert valKind == fieldKind.getStackKind() : field + ": " + valKind + " != " + fieldKind;
                     }
                 }
                 assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -59,6 +59,7 @@
 import org.graalvm.compiler.lir.SwitchStrategy;
 import org.graalvm.compiler.lir.Variable;
 import org.graalvm.compiler.lir.debug.LIRGenerationDebugContext;
+import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGenerator;
 import org.graalvm.compiler.lir.gen.LIRGenerator.Options;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
@@ -577,9 +578,9 @@
     @Override
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
-        CallingConvention invokeCc = gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()),
-                        callTarget.signature(), gen);
-        gen.getResult().getFrameMapBuilder().callsMethod(invokeCc);
+        FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
+        CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
+        frameMapBuilder.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java	Thu Nov 16 12:15:55 2017 +0000
@@ -195,9 +195,12 @@
     public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
                     SpeculationLog speculationLog, InstalledCode predefinedInstalledCode, boolean isDefault, Object[] context) {
         Object[] debugContext = context != null ? context : new Object[]{getProviders().getCodeCache(), method, compilationResult};
-        CodeInstallationTask[] tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
-        for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
-            tasks[i] = codeInstallationTaskFactories.get(i).create();
+        CodeInstallationTask[] tasks;
+        synchronized (this) {
+            tasks = new CodeInstallationTask[codeInstallationTaskFactories.size()];
+            for (int i = 0; i < codeInstallationTaskFactories.size(); i++) {
+                tasks[i] = codeInstallationTaskFactories.get(i).create();
+            }
         }
         try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
                         DebugContext.Activation a = debug.activate()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java	Thu Nov 16 12:15:55 2017 +0000
@@ -29,9 +29,11 @@
 import static org.graalvm.compiler.debug.DebugOptions.Dump;
 import static org.graalvm.compiler.debug.DebugOptions.DumpOnError;
 import static org.graalvm.compiler.debug.DebugOptions.DumpOnPhaseChange;
+import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
 import static org.graalvm.compiler.debug.DebugOptions.ListMetrics;
 import static org.graalvm.compiler.debug.DebugOptions.Log;
 import static org.graalvm.compiler.debug.DebugOptions.MemUseTrackers;
+import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
 import static org.graalvm.compiler.debug.DebugOptions.Time;
 import static org.graalvm.compiler.debug.DebugOptions.Timers;
 import static org.graalvm.compiler.debug.DebugOptions.TrackMemUse;
@@ -56,6 +58,7 @@
 
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.graphio.GraphOutput;
 import org.graalvm.util.EconomicMap;
 import org.graalvm.util.EconomicSet;
 import org.graalvm.util.Pair;
@@ -98,6 +101,8 @@
     CloseableCounter currentMemUseTracker;
     Scope lastClosedScope;
     Throwable lastExceptionThrown;
+    private IgvDumpChannel sharedChannel;
+    private GraphOutput<?, ?> parentOutput;
 
     /**
      * Stores the {@link MetricKey} values.
@@ -111,6 +116,19 @@
         return immutable.scopesEnabled;
     }
 
+    public <G, N, M> GraphOutput<G, M> buildOutput(GraphOutput.Builder<G, N, M> builder) throws IOException {
+        if (parentOutput != null) {
+            return builder.build(parentOutput);
+        } else {
+            if (sharedChannel == null) {
+                sharedChannel = new IgvDumpChannel(() -> getDumpPath(".bgv", false), immutable.options);
+            }
+            final GraphOutput<G, M> output = builder.build(sharedChannel);
+            parentOutput = output;
+            return output;
+        }
+    }
+
     /**
      * The immutable configuration that can be shared between {@link DebugContext} objects.
      */
@@ -323,6 +341,14 @@
             String compilableName = compilable instanceof JavaMethod ? ((JavaMethod) compilable).format("%H.%n(%p)%R") : String.valueOf(compilable);
             return identifier + ":" + compilableName;
         }
+
+        final String getLabel() {
+            if (compilable instanceof JavaMethod) {
+                JavaMethod method = (JavaMethod) compilable;
+                return method.format("%h.%n(%p)%r");
+            }
+            return String.valueOf(compilable);
+        }
     }
 
     private final Description description;
@@ -394,6 +420,20 @@
         }
     }
 
+    public Path getDumpPath(String extension, boolean directory) {
+        try {
+            String id = description == null ? null : description.identifier;
+            String label = description == null ? null : description.getLabel();
+            Path result = PathUtilities.createUnique(immutable.options, DumpPath, id, label, extension, directory);
+            if (ShowDumpFiles.getValue(immutable.options)) {
+                TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
+            }
+            return result;
+        } catch (IOException ex) {
+            throw rethrowSilently(RuntimeException.class, ex);
+        }
+    }
+
     /**
      * A special dump level that indicates the dumping machinery is enabled but no dumps will be
      * produced except through other options.
@@ -2043,4 +2083,9 @@
         }
         out.println();
     }
+
+    @SuppressWarnings({"unused", "unchecked"})
+    private static <E extends Exception> E rethrowSilently(Class<E> type, Throwable ex) throws E {
+        throw (E) ex;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugHandlersFactory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -35,6 +35,9 @@
 
     /**
      * Creates {@link DebugHandler}s based on {@code options}.
+     *
+     * @param options options to control type and name of the channel
+     * @return list of debug handers that have been created
      */
     List<DebugHandler> createHandlers(OptionValues options);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Thu Nov 16 12:15:55 2017 +0000
@@ -128,8 +128,6 @@
     public static final OptionKey<Boolean> PrintGraphProbabilities = new OptionKey<>(false);
     @Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug)
     public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true);
-    @Option(help = "Dump graphs in binary format instead of XML format.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> PrintBinaryGraphs = new OptionKey<>(true);
     @Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
     public static final OptionKey<Boolean> PrintGraphFile = new OptionKey<>(false);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/IgvDumpChannel.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,119 @@
+/*
+ * 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.debug;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.function.Supplier;
+import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
+import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
+import org.graalvm.compiler.options.OptionValues;
+
+final class IgvDumpChannel implements WritableByteChannel {
+    private final Supplier<Path> pathProvider;
+    private final OptionValues options;
+    private WritableByteChannel sharedChannel;
+    private boolean closed;
+
+    IgvDumpChannel(Supplier<Path> pathProvider, OptionValues options) {
+        this.pathProvider = pathProvider;
+        this.options = options;
+    }
+
+    @Override
+    public int write(ByteBuffer src) throws IOException {
+        return channel().write(src);
+    }
+
+    @Override
+    public boolean isOpen() {
+        return !closed;
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    void realClose() throws IOException {
+        closed = true;
+        if (sharedChannel != null) {
+            sharedChannel.close();
+            sharedChannel = null;
+        }
+    }
+
+    WritableByteChannel channel() throws IOException {
+        if (closed) {
+            throw new IOException();
+        }
+        if (sharedChannel == null) {
+            if (DebugOptions.PrintGraphFile.getValue(options)) {
+                sharedChannel = createFileChannel(pathProvider);
+            } else {
+                sharedChannel = createNetworkChannel(pathProvider, options);
+            }
+        }
+        return sharedChannel;
+    }
+
+    private static WritableByteChannel createNetworkChannel(Supplier<Path> pathProvider, OptionValues options) throws IOException {
+        String host = PrintGraphHost.getValue(options);
+        int port = PrintBinaryGraphPort.getValue(options);
+        try {
+            WritableByteChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
+            TTY.println("Connected to the IGV on %s:%d", host, port);
+            return channel;
+        } catch (ClosedByInterruptException | InterruptedIOException e) {
+            /*
+             * Interrupts should not count as errors because they may be caused by a cancelled Graal
+             * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
+             * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
+             */
+            return null;
+        } catch (IOException e) {
+            if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
+                return createFileChannel(pathProvider);
+            } else {
+                throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
+            }
+        }
+    }
+
+    private static WritableByteChannel createFileChannel(Supplier<Path> pathProvider) throws IOException {
+        Path path = pathProvider.get();
+        try {
+            return FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
+        } catch (IOException e) {
+            throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/PathUtilities.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,12 +22,13 @@
  */
 package org.graalvm.compiler.debug;
 
+import java.io.File;
 import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.graalvm.compiler.options.OptionKey;
@@ -39,54 +40,6 @@
 public class PathUtilities {
 
     private static final AtomicLong globalTimeStamp = new AtomicLong();
-    /**
-     * This generates a per thread persistent id to aid mapping related dump files with each other.
-     */
-    private static final ThreadLocal<PerThreadSequence> threadDumpId = new ThreadLocal<>();
-    private static final AtomicInteger dumpId = new AtomicInteger();
-
-    static class PerThreadSequence {
-        final int threadID;
-        HashMap<String, Integer> sequences = new HashMap<>(2);
-
-        PerThreadSequence(int threadID) {
-            this.threadID = threadID;
-        }
-
-        String generateID(String extension) {
-            Integer box = sequences.get(extension);
-            if (box == null) {
-                sequences.put(extension, 1);
-                return Integer.toString(threadID);
-            } else {
-                sequences.put(extension, box + 1);
-                return Integer.toString(threadID) + '-' + box;
-            }
-        }
-    }
-
-    private static String getThreadDumpId(String extension) {
-        PerThreadSequence id = threadDumpId.get();
-        if (id == null) {
-            id = new PerThreadSequence(dumpId.incrementAndGet());
-            threadDumpId.set(id);
-        }
-        return id.generateID(extension);
-    }
-
-    /**
-     * Prepends a period (i.e., {@code '.'}) to an non-null, non-empty string representation a file
-     * extension if the string does not already start with a period.
-     *
-     * @return {@code ext} unmodified if it is null, empty or already starts with a period other
-     *         {@code "." + ext}
-     */
-    public static String formatExtension(String ext) {
-        if (ext == null || ext.length() == 0) {
-            return "";
-        }
-        return "." + ext;
-    }
 
     /**
      * Gets a time stamp for the current process. This method will always return the same value for
@@ -100,43 +53,6 @@
     }
 
     /**
-     * Generates a {@link Path} using the format "%s-%d_%d%s" with the {@code baseNameOption}, a
-     * {@link #getGlobalTimeStamp() global timestamp} , {@link #getThreadDumpId a per thread unique
-     * id} and an optional {@code extension}.
-     *
-     * @return the output file path or null if the flag is null
-     */
-    public static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
-        return getPath(options, baseNameOption, extension, true);
-    }
-
-    /**
-     * Generate a {@link Path} using the format "%s-%d_%s" with the {@code baseNameOption}, a
-     * {@link #getGlobalTimeStamp() global timestamp} and an optional {@code extension} .
-     *
-     * @return the output file path or null if the flag is null
-     */
-    public static Path getPathGlobal(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
-        return getPath(options, baseNameOption, extension, false);
-    }
-
-    private static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension, boolean includeThreadId) throws IOException {
-        if (baseNameOption.getValue(options) == null) {
-            return null;
-        }
-        String ext = formatExtension(extension);
-        final String name = includeThreadId
-                        ? String.format("%s-%d_%s%s", baseNameOption.getValue(options), getGlobalTimeStamp(), getThreadDumpId(ext), ext)
-                        : String.format("%s-%d%s", baseNameOption.getValue(options), getGlobalTimeStamp(), ext);
-        Path result = Paths.get(name);
-        if (result.isAbsolute()) {
-            return result;
-        }
-        Path dumpDir = DebugOptions.getDumpDirectory(options);
-        return dumpDir.resolve(name).normalize();
-    }
-
-    /**
      * Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
      * without causing an {@link InvalidPathException}.
      *
@@ -145,21 +61,80 @@
      */
     public static String sanitizeFileName(String name) {
         try {
-            Paths.get(name);
-            return name;
+            Path path = Paths.get(name);
+            if (path.getNameCount() == 0) {
+                return name;
+            }
         } catch (InvalidPathException e) {
             // fall through
         }
         StringBuilder buf = new StringBuilder(name.length());
         for (int i = 0; i < name.length(); i++) {
             char c = name.charAt(i);
-            try {
-                Paths.get(String.valueOf(c));
-            } catch (InvalidPathException e) {
-                buf.append('_');
+            if (c != File.separatorChar && c != ' ' && !Character.isISOControl(c)) {
+                try {
+                    Paths.get(String.valueOf(c));
+                    buf.append(c);
+                    continue;
+                } catch (InvalidPathException e) {
+                }
             }
-            buf.append(c);
+            buf.append('_');
         }
         return buf.toString();
     }
+
+    /**
+     * A maximum file name length supported by most file systems. There is no platform independent
+     * way to get this in Java.
+     */
+    private static final int MAX_FILE_NAME_LENGTH = 255;
+
+    private static final String ELLIPSIS = "...";
+
+    static Path createUnique(OptionValues options, OptionKey<String> baseNameOption, String id, String label, String ext, boolean createDirectory) throws IOException {
+        String uniqueTag = "";
+        int dumpCounter = 1;
+        String prefix;
+        if (id == null) {
+            prefix = baseNameOption.getValue(options);
+            int slash = prefix.lastIndexOf(File.separatorChar);
+            prefix = prefix.substring(slash + 1);
+        } else {
+            prefix = id;
+        }
+        for (;;) {
+            int fileNameLengthWithoutLabel = uniqueTag.length() + ext.length() + prefix.length() + "[]".length();
+            int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
+            String fileName;
+            if (labelLengthLimit < ELLIPSIS.length()) {
+                // This means `id` is very long
+                String suffix = uniqueTag + ext;
+                int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), prefix.length());
+                fileName = sanitizeFileName(prefix.substring(0, idLengthLimit) + suffix);
+            } else {
+                if (label == null) {
+                    fileName = sanitizeFileName(prefix + uniqueTag + ext);
+                } else {
+                    String adjustedLabel = label;
+                    if (label.length() > labelLengthLimit) {
+                        adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
+                    }
+                    fileName = sanitizeFileName(prefix + '[' + adjustedLabel + ']' + uniqueTag + ext);
+                }
+            }
+            Path dumpDir = DebugOptions.getDumpDirectory(options);
+            Path result = Paths.get(dumpDir.toString(), fileName);
+            try {
+                if (createDirectory) {
+                    return Files.createDirectory(result);
+                } else {
+                    return Files.createFile(result);
+                }
+            } catch (FileAlreadyExistsException e) {
+                uniqueTag = "_" + dumpCounter++;
+            }
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,51 @@
+/*
+ * 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.graph.test.graphio;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import static org.junit.Assert.assertTrue;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class GraphSnippetTest {
+    @Test
+    public void dumpTheFile() throws Exception {
+        Class<?> snippets = null;
+        try {
+            snippets = Class.forName("org.graalvm.graphio.GraphSnippets");
+        } catch (ClassNotFoundException notFound) {
+            Assume.assumeNoException("The snippets class has to be around", notFound);
+        }
+        Method dump = null;
+        try {
+            dump = snippets.getDeclaredMethod("dump", File.class);
+            dump.setAccessible(true);
+        } catch (RuntimeException ex) {
+            Assume.assumeTrue("Only run the test, if the method is accessible", dump != null && dump.isAccessible());
+        }
+        File diamond = File.createTempFile("diamond", ".bgv");
+        dump.invoke(null, diamond);
+        assertTrue("File .bgv created: " + diamond, diamond.length() > 50);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,311 @@
+/*
+ * 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.graph.test.graphio;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.graalvm.graphio.GraphOutput;
+import org.graalvm.graphio.GraphStructure;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class NodeEncodingTest {
+
+    private ByteArrayOutputStream out;
+
+    @Before
+    public void initOutput() {
+        out = new ByteArrayOutputStream();
+    }
+
+    @Test
+    public void version40TheNodeIsntDumpedWithItsID() throws Exception {
+        runTheNodeIsntDumpedWithItsID(true);
+    }
+
+    @Test
+    public void defaultVersionTheNodeIsntDumpedWithItsID() throws Exception {
+        runTheNodeIsntDumpedWithItsID(false);
+    }
+
+    private void runTheNodeIsntDumpedWithItsID(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+        assertByte(false, out.toByteArray(), 33);
+        assertEquals("Node class of the node has been requested", 1, node.nodeClassRequested);
+        assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+        assertFalse("No to string ops", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeInVersion10() throws Exception {
+        runTheNodeIsTreatedAsString(true);
+    }
+
+    private void runTheNodeIsTreatedAsString(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(1, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 1.0", 0, node.idTested);
+        assertByte(false, out.toByteArray(), 33);
+        assertEquals("Node class was needed to find out it is not a NodeClass instance", 1, node.nodeClassRequested);
+        assertEquals("Node class template name wasn't needed however", 0, clazz.nameTemplateQueried);
+        assertTrue("Node sent as a string version 1.0", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeInVersion15() throws Exception {
+        runTheNodeIsTreatedPoolEntry(true);
+    }
+
+    private void runTheNodeIsTreatedPoolEntry(boolean explicitVersion) throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = explicitVersion ? GraphOutput.newBuilder(new MockStructure()).protocolVersion(5, 0).build(w) : GraphOutput.newBuilder(new MockStructure()).build(w)) {
+            dump.beginGroup(graph, "test1", "t1", null, 0, Collections.singletonMap("node", node));
+            dump.endGroup();
+        }
+
+        assertEquals("Node is always requested", 1, node.nodeRequested);
+        assertEquals("Id of our node is requested in version 5.0", 1, node.idTested);
+        assertByte(true, out.toByteArray(), 33);
+        assertTrue("Node class was needed at least once", 1 <= node.nodeClassRequested);
+        assertEquals("Node class template name sent to server", 1, clazz.nameTemplateQueried);
+        assertFalse("Node.toString() isn't needed", node.toStringRequested);
+    }
+
+    @Test
+    public void dumpingNodeTwiceInVersion4() throws Exception {
+        WritableByteChannel w = Channels.newChannel(out);
+        MockGraph graph = new MockGraph();
+        MockNodeClass clazz = new MockNodeClass("clazz");
+        MockNode node = new MockNode(clazz, 33); // random value otherwise not found in the stream
+        try (GraphOutput<MockGraph, ?> dump = GraphOutput.newBuilder(new MockStructure()).protocolVersion(4, 0).build(w)) {
+            Map<String, Object> props = new LinkedHashMap<>();
+            props.put("node1", node);
+            props.put("node2", node);
+            props.put("node3", node);
+            dump.beginGroup(graph, "test1", "t1", null, 0, props);
+            dump.endGroup();
+        }
+
+        assertEquals("Node requested three times", 3, node.nodeRequested);
+        assertEquals("Nobody asks for id of a node in version 4.0", 0, node.idTested);
+        // check there is no encoded string for object #3
+        assertByte(false, out.toByteArray(), 1, 0, 3);
+        assertEquals("Node class of the node has been requested three times", 3, node.nodeClassRequested);
+        assertEquals("Node class template name stored", 1, clazz.nameTemplateQueried);
+        assertFalse("No to string ops", node.toStringRequested);
+    }
+
+    private static void assertByte(boolean shouldBeFound, byte[] arr, int... value) {
+        boolean found = false;
+        int at = 0;
+        for (int i = 0; i < arr.length; i++) {
+            if (arr[i] == value[at]) {
+                if (++at == value.length) {
+                    found = true;
+                    break;
+                }
+            } else {
+                at = 0;
+            }
+        }
+        if (shouldBeFound == found) {
+            return;
+        }
+        if (shouldBeFound) {
+            fail("Value " + value + " not found in\n" + Arrays.toString(arr));
+        } else {
+            fail("Value " + value + " surprisingly found in\n" + Arrays.toString(arr));
+        }
+    }
+
+    private static final class MockStructure implements GraphStructure<MockGraph, MockNode, MockNodeClass, MockNodeClass> {
+
+        @Override
+        public MockGraph graph(MockGraph currentGraph, Object obj) {
+            return obj instanceof MockGraph ? (MockGraph) obj : null;
+        }
+
+        @Override
+        public Iterable<? extends MockNode> nodes(MockGraph graph) {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public int nodesCount(MockGraph graph) {
+            return 0;
+        }
+
+        @Override
+        public int nodeId(MockNode node) {
+            node.idTested++;
+            return node.id;
+        }
+
+        @Override
+        public boolean nodeHasPredecessor(MockNode node) {
+            return false;
+        }
+
+        @Override
+        public void nodeProperties(MockGraph graph, MockNode node, Map<String, ? super Object> properties) {
+        }
+
+        @Override
+        public MockNode node(Object obj) {
+            if (obj instanceof MockNode) {
+                ((MockNode) obj).nodeRequested++;
+                return (MockNode) obj;
+            }
+            return null;
+        }
+
+        @Override
+        public MockNodeClass nodeClass(Object obj) {
+            if (obj instanceof MockNode) {
+                ((MockNode) obj).nodeClassRequested++;
+            }
+            return obj instanceof MockNodeClass ? (MockNodeClass) obj : null;
+        }
+
+        @Override
+        public MockNodeClass classForNode(MockNode n) {
+            n.nodeClassRequested++;
+            return n.clazz;
+        }
+
+        @Override
+        public String nameTemplate(MockNodeClass nodeClass) {
+            nodeClass.nameTemplateQueried++;
+            return "";
+        }
+
+        @Override
+        public Object nodeClassType(MockNodeClass nodeClass) {
+            return nodeClass.getClass();
+        }
+
+        @Override
+        public MockNodeClass portInputs(MockNodeClass nodeClass) {
+            return nodeClass;
+        }
+
+        @Override
+        public MockNodeClass portOutputs(MockNodeClass nodeClass) {
+            return nodeClass;
+        }
+
+        @Override
+        public int portSize(MockNodeClass port) {
+            return 0;
+        }
+
+        @Override
+        public boolean edgeDirect(MockNodeClass port, int index) {
+            return false;
+        }
+
+        @Override
+        public String edgeName(MockNodeClass port, int index) {
+            return null;
+        }
+
+        @Override
+        public Object edgeType(MockNodeClass port, int index) {
+            return null;
+        }
+
+        @Override
+        public Collection<? extends MockNode> edgeNodes(MockGraph graph, MockNode node, MockNodeClass port, int index) {
+            return null;
+        }
+    }
+
+    private static final class MockGraph {
+
+    }
+
+    private static final class MockNode {
+        final MockNodeClass clazz;
+        final int id;
+        int idTested;
+        int nodeClassRequested;
+        int nodeRequested;
+        boolean toStringRequested;
+
+        MockNode(MockNodeClass clazz, int id) {
+            this.clazz = clazz;
+            this.id = id;
+        }
+
+        @Override
+        public String toString() {
+            this.toStringRequested = true;
+            return "MockNode{" + "id=" + id + ", class=" + clazz + '}';
+        }
+    }
+
+    private static final class MockNodeClass {
+        final String name;
+        int nameTemplateQueried;
+
+        MockNodeClass(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return "MockNodeClass{" + "name=" + name + '}';
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Thu Nov 16 12:15:55 2017 +0000
@@ -514,30 +514,61 @@
         /**
          * A node was added to a graph.
          */
-        NODE_ADDED;
+        NODE_ADDED,
+
+        /**
+         * A node was removed from the graph.
+         */
+        NODE_REMOVED;
     }
 
     /**
      * Client interested in one or more node related events.
      */
-    public interface NodeEventListener {
+    public abstract static class NodeEventListener {
 
         /**
-         * Default handler for events.
+         * A method called when a change event occurs.
+         *
+         * This method dispatches the event to user-defined triggers. The methods that change the
+         * graph (typically in Graph and Node) must call this method to dispatch the event.
          *
          * @param e an event
          * @param node the node related to {@code e}
          */
-        default void event(NodeEvent e, Node node) {
+        final void event(NodeEvent e, Node node) {
+            switch (e) {
+                case INPUT_CHANGED:
+                    inputChanged(node);
+                    break;
+                case ZERO_USAGES:
+                    usagesDroppedToZero(node);
+                    break;
+                case NODE_ADDED:
+                    nodeAdded(node);
+                    break;
+                case NODE_REMOVED:
+                    nodeRemoved(node);
+                    break;
+            }
+            changed(e, node);
         }
 
         /**
-         * Notifies this listener of a change in a node's inputs.
+         * Notifies this listener about any change event in the graph.
+         *
+         * @param e an event
+         * @param node the node related to {@code e}
+         */
+        public void changed(NodeEvent e, Node node) {
+        }
+
+        /**
+         * Notifies this listener about a change in a node's inputs.
          *
          * @param node a node who has had one of its inputs changed
          */
-        default void inputChanged(Node node) {
-            event(NodeEvent.INPUT_CHANGED, node);
+        public void inputChanged(Node node) {
         }
 
         /**
@@ -545,8 +576,7 @@
          *
          * @param node a node whose {@link Node#usages()} just became empty
          */
-        default void usagesDroppedToZero(Node node) {
-            event(NodeEvent.ZERO_USAGES, node);
+        public void usagesDroppedToZero(Node node) {
         }
 
         /**
@@ -554,8 +584,15 @@
          *
          * @param node a node that was just added to the graph
          */
-        default void nodeAdded(Node node) {
-            event(NodeEvent.NODE_ADDED, node);
+        public void nodeAdded(Node node) {
+        }
+
+        /**
+         * Notifies this listener of a removed node.
+         *
+         * @param node
+         */
+        public void nodeRemoved(Node node) {
         }
     }
 
@@ -583,7 +620,7 @@
         }
     }
 
-    private static class ChainedNodeEventListener implements NodeEventListener {
+    private static class ChainedNodeEventListener extends NodeEventListener {
 
         NodeEventListener head;
         NodeEventListener next;
@@ -595,20 +632,32 @@
 
         @Override
         public void nodeAdded(Node node) {
-            head.nodeAdded(node);
-            next.nodeAdded(node);
+            head.event(NodeEvent.NODE_ADDED, node);
+            next.event(NodeEvent.NODE_ADDED, node);
         }
 
         @Override
         public void inputChanged(Node node) {
-            head.inputChanged(node);
-            next.inputChanged(node);
+            head.event(NodeEvent.INPUT_CHANGED, node);
+            next.event(NodeEvent.INPUT_CHANGED, node);
         }
 
         @Override
         public void usagesDroppedToZero(Node node) {
-            head.usagesDroppedToZero(node);
-            next.usagesDroppedToZero(node);
+            head.event(NodeEvent.ZERO_USAGES, node);
+            next.event(NodeEvent.ZERO_USAGES, node);
+        }
+
+        @Override
+        public void nodeRemoved(Node node) {
+            head.event(NodeEvent.NODE_REMOVED, node);
+            next.event(NodeEvent.NODE_REMOVED, node);
+        }
+
+        @Override
+        public void changed(NodeEvent e, Node node) {
+            head.event(e, node);
+            next.event(e, node);
         }
     }
 
@@ -1023,7 +1072,7 @@
         updateNodeCaches(node);
 
         if (nodeEventListener != null) {
-            nodeEventListener.nodeAdded(node);
+            nodeEventListener.event(NodeEvent.NODE_ADDED, node);
         }
         afterRegister(node);
     }
@@ -1085,6 +1134,10 @@
         nodes[node.id] = null;
         nodesDeletedSinceLastCompression++;
 
+        if (nodeEventListener != null) {
+            nodeEventListener.event(NodeEvent.NODE_ADDED, node);
+        }
+
         // nodes aren't removed from the type cache here - they will be removed during iteration
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Thu Nov 16 12:15:55 2017 +0000
@@ -752,7 +752,7 @@
             assert !graph.isFrozen();
             NodeEventListener listener = graph.nodeEventListener;
             if (listener != null) {
-                listener.inputChanged(node);
+                listener.event(Graph.NodeEvent.INPUT_CHANGED, node);
             }
         }
     }
@@ -762,7 +762,7 @@
             assert !graph.isFrozen();
             NodeEventListener listener = graph.nodeEventListener;
             if (listener != null && node.isAlive()) {
-                listener.usagesDroppedToZero(node);
+                listener.event(Graph.NodeEvent.ZERO_USAGES, node);
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -183,8 +183,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new AArch64BreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java	Thu Nov 16 12:15:55 2017 +0000
@@ -32,7 +32,6 @@
 import org.graalvm.compiler.core.amd64.AMD64AddressNode;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.debug.CounterKey;
@@ -44,6 +43,7 @@
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CompressionNode;
 import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -93,76 +93,76 @@
     }
 
     @Override
-    protected boolean improve(DebugContext debug, AMD64AddressNode addr) {
-
-        boolean result = false;
-
-        while (super.improve(debug, addr)) {
-            result = true;
+    protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
+        if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
+            return true;
         }
 
         if (addr.getScale() == Scale.Times1) {
             if (addr.getIndex() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase())) {
+                if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
                     counterFoldedUncompressDuringAddressLowering.increment(debug);
                     return true;
                 }
             }
 
             if (addr.getBase() instanceof CompressionNode) {
-                if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex())) {
+                if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
                     counterFoldedUncompressDuringAddressLowering.increment(debug);
                     return true;
                 }
             }
         }
 
-        return result;
+        return false;
+    }
+
+    @Override
+    protected boolean mightBeOptimized(ValueNode value) {
+        return super.mightBeOptimized(value) || value instanceof CompressionNode;
     }
 
-    private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
-        if (compression.getOp() == CompressionOp.Uncompress) {
-            CompressEncoding encoding = compression.getEncoding();
-            Scale scale = Scale.fromShift(encoding.getShift());
-            if (scale == null) {
+    private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
+        if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
+            return false;
+        }
+
+        CompressEncoding encoding = compression.getEncoding();
+        Scale scale = Scale.fromShift(encoding.getShift());
+        if (scale == null) {
+            return false;
+        }
+
+        if (heapBaseRegister != null && encoding.getBase() == heapBase) {
+            if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
+                // With PIC it is only legal to do for oops since the base value may be
+                // different at runtime.
+                ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+                addr.setBase(base);
+            } else {
                 return false;
             }
-
-            if (heapBaseRegister != null && encoding.getBase() == heapBase) {
-                if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
-                    // With PIC it is only legal to do for oops since the base value may be
-                    // different at runtime.
-                    ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
+        } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
+            if (generatePIC) {
+                if (other == null) {
+                    ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
                     addr.setBase(base);
                 } else {
                     return false;
                 }
-            } else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
-                if (generatePIC) {
-                    if (other == null) {
-                        ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
-                        addr.setBase(base);
-                    } else {
-                        return false;
-                    }
+            } else {
+                if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
+                    addr.setBase(other);
                 } else {
-                    long disp = addr.getDisplacement() + encoding.getBase();
-                    if (NumUtil.isInt(disp)) {
-                        addr.setDisplacement((int) disp);
-                        addr.setBase(other);
-                    } else {
-                        return false;
-                    }
+                    return false;
                 }
-            } else {
-                addr.setBase(other);
             }
+        } else {
+            addr.setBase(other);
+        }
 
-            addr.setScale(scale);
-            addr.setIndex(compression.getValue());
-            return true;
-        } else {
-            return false;
-        }
+        addr.setScale(scale);
+        addr.setIndex(compression.getValue());
+        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Nov 16 12:15:55 2017 +0000
@@ -39,7 +39,6 @@
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.core.amd64.AMD64ArithmeticLIRGenerator;
 import org.graalvm.compiler.core.amd64.AMD64LIRGenerator;
-import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
 import org.graalvm.compiler.core.amd64.AMD64MoveFactoryBase.BackupSlotProvider;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
@@ -116,7 +115,7 @@
     }
 
     private AMD64HotSpotLIRGenerator(HotSpotProviders providers, GraalHotSpotVMConfig config, LIRGenerationResult lirGenRes, BackupSlotProvider backupSlotProvider) {
-        this(new AMD64LIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
+        this(new AMD64HotSpotLIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
     }
 
     protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, GraalHotSpotVMConfig config,
@@ -363,7 +362,7 @@
         Stub stub = getStub();
         if (destroysRegisters) {
             if (stub != null && stub.preservesRegisters()) {
-                Register[] savedRegisters = getResult().getFrameMapBuilder().getRegisterConfig().getAllocatableRegisters().toArray();
+                Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray();
                 save = emitSaveAllRegisters(savedRegisters, true);
             }
         }
@@ -567,28 +566,29 @@
     @Override
     public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getValueKind(LIRKind.class);
-        assert inputKind.getPlatformKind() == AMD64Kind.QWORD;
+        LIRKindTool lirKindTool = getLIRKindTool();
+        assert inputKind.getPlatformKind() == lirKindTool.getObjectKind().getPlatformKind();
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(AMD64Kind.DWORD));
-            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+            Variable result = newVariable(lirKindTool.getNarrowOopKind());
+            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
+            Variable result = newVariable(lirKindTool.getNarrowPointerKind());
             AllocatableValue base = Value.ILLEGAL;
             OptionValues options = getResult().getLIR().getOptions();
             if (encoding.hasBase() || GeneratePIC.getValue(options)) {
                 if (GeneratePIC.getValue(options)) {
-                    Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+                    Variable baseAddress = newVariable(lirKindTool.getWordKind());
                     AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
                     append(move);
                     base = baseAddress;
                 } else {
-                    base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+                    base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+            append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
             return result;
         }
     }
@@ -596,35 +596,37 @@
     @Override
     public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getValueKind(LIRKind.class);
-        assert inputKind.getPlatformKind() == AMD64Kind.DWORD;
+        LIRKindTool lirKindTool = getLIRKindTool();
+        assert inputKind.getPlatformKind() == lirKindTool.getNarrowOopKind().getPlatformKind();
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(AMD64Kind.QWORD));
-            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
+            Variable result = newVariable(lirKindTool.getObjectKind());
+            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
+            LIRKind uncompressedKind = lirKindTool.getWordKind();
+            Variable result = newVariable(uncompressedKind);
             AllocatableValue base = Value.ILLEGAL;
             OptionValues options = getResult().getLIR().getOptions();
             if (encoding.hasBase() || GeneratePIC.getValue(options)) {
                 if (GeneratePIC.getValue(options)) {
-                    Variable baseAddress = newVariable(LIRKind.value(AMD64Kind.QWORD));
+                    Variable baseAddress = newVariable(uncompressedKind);
                     AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
                     append(move);
                     base = baseAddress;
                 } else {
-                    base = emitLoadConstant(LIRKind.value(AMD64Kind.QWORD), JavaConstant.forLong(encoding.getBase()));
+                    base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
                 }
             }
-            append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
+            append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
             return result;
         }
     }
 
     @Override
     public void emitNullCheck(Value address, LIRFrameState state) {
-        if (address.getValueKind().getPlatformKind() == AMD64Kind.DWORD) {
+        if (address.getValueKind().getPlatformKind() == getLIRKindTool().getNarrowOopKind().getPlatformKind()) {
             CompressEncoding encoding = config.getOopEncoding();
             Value uncompressed;
             if (encoding.getShift() <= 3) {
@@ -635,9 +637,9 @@
                 uncompressed = emitUncompress(address, encoding, false);
             }
             append(new AMD64Move.NullCheckOp(asAddressValue(uncompressed), state));
-        } else {
-            super.emitNullCheck(address, state);
+            return;
         }
+        super.emitNullCheck(address, state);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRKindTool.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,39 @@
+/*
+ * 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.amd64;
+
+import jdk.vm.ci.amd64.AMD64Kind;
+import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
+import org.graalvm.compiler.core.common.LIRKind;
+
+public class AMD64HotSpotLIRKindTool extends AMD64LIRKindTool {
+    @Override
+    public LIRKind getNarrowOopKind() {
+        return LIRKind.reference(AMD64Kind.DWORD);
+    }
+
+    @Override
+    public LIRKind getNarrowPointerKind() {
+        return LIRKind.value(AMD64Kind.DWORD);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,16 +24,13 @@
 
 import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 import static jdk.vm.ci.code.ValueUtil.asRegister;
 import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
 
-import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
-import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.debug.GraalError;
@@ -41,10 +38,8 @@
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
 import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
-import org.graalvm.compiler.lir.amd64.AMD64Move;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 
-import jdk.vm.ci.amd64.AMD64Kind;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
@@ -180,91 +175,6 @@
         }
     }
 
-    public static final class CompressPointer extends AMD64LIRInstruction {
-        public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
-
-        private final CompressEncoding encoding;
-        private final boolean nonNull;
-
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG}) protected AllocatableValue input;
-        @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
-        public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
-            super(TYPE);
-            this.result = result;
-            this.input = input;
-            this.baseRegister = baseRegister;
-            this.encoding = encoding;
-            this.nonNull = nonNull;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            AMD64Move.move(AMD64Kind.QWORD, crb, masm, result, input);
-
-            Register resReg = asRegister(result);
-            if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
-                Register baseReg = asRegister(baseRegister);
-                if (!nonNull) {
-                    masm.testq(resReg, resReg);
-                    masm.cmovq(ConditionFlag.Equal, resReg, baseReg);
-                }
-                masm.subq(resReg, baseReg);
-            }
-
-            if (encoding.hasShift()) {
-                masm.shrq(resReg, encoding.getShift());
-            }
-        }
-    }
-
-    public static final class UncompressPointer extends AMD64LIRInstruction {
-        public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
-
-        private final CompressEncoding encoding;
-        private final boolean nonNull;
-
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG}) protected AllocatableValue input;
-        @Alive({REG, ILLEGAL}) protected AllocatableValue baseRegister;
-
-        public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull) {
-            super(TYPE);
-            this.result = result;
-            this.input = input;
-            this.baseRegister = baseRegister;
-            this.encoding = encoding;
-            this.nonNull = nonNull;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            AMD64Move.move(AMD64Kind.DWORD, crb, masm, result, input);
-
-            Register resReg = asRegister(result);
-            if (encoding.getShift() != 0) {
-                masm.shlq(resReg, encoding.getShift());
-            }
-
-            if (encoding.hasBase() || GeneratePIC.getValue(crb.getOptions())) {
-                if (nonNull) {
-                    masm.addq(resReg, asRegister(baseRegister));
-                } else {
-                    if (!encoding.hasShift()) {
-                        // if encoding.shift != 0, the flags are already set by the shlq
-                        masm.testq(resReg, resReg);
-                    }
-
-                    Label done = new Label();
-                    masm.jccb(ConditionFlag.Equal, done);
-                    masm.addq(resReg, asRegister(baseRegister));
-                    masm.bind(done);
-                }
-            }
-        }
-    }
-
     public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
         CompressEncoding encoding = config.getKlassEncoding();
         masm.movl(register, address);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -189,8 +189,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new AMD64BreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java	Thu Nov 16 12:15:55 2017 +0000
@@ -113,8 +113,7 @@
                 } else {
                     register = asRegister(result);
                 }
-                int bytes = result.getPlatformKind().getSizeInBytes();
-                loadFromConstantTable(crb, masm, bytes, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
+                int bytes = loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, register, SPARCDelayedControlTransfer.DUMMY);
                 if (isStack) {
                     masm.st(register, (SPARCAddress) crb.asAddress(result), bytes);
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -162,8 +162,7 @@
             sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
         }
 
-        Value[] parameters = visitInvokeArguments(gen.getResult().getFrameMapBuilder().getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen),
-                        node.arguments());
+        Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
         append(new SPARCBreakpointOp(parameters));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -77,8 +77,7 @@
                 boolean canUseShortBranch = masm.hasFeature(CPUFeature.CBCOND) && SPARCControlFlow.isShortBranch(masm, cbCondPosition, hint, target);
 
                 Register scratchRegister = asRegister(scratch);
-                final int byteCount = constant.isCompressed() ? 4 : 8;
-                loadFromConstantTable(crb, masm, byteCount, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
+                loadFromConstantTable(crb, masm, asRegister(constantTableBase), constant, scratchRegister, SPARCDelayedControlTransfer.DUMMY);
 
                 if (canUseShortBranch) {
                     CBCOND.emit(masm, conditionFlag, conditionCode == CC.Xcc, keyRegister, scratchRegister, target);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Tests {@link ArrayCopySnippets#checkcastArraycopyWork}.
+     * Tests {@link ArrayCopySnippets#arraycopyCheckcastSnippet}.
      */
     @Test
     public void testArrayStoreException() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompilationWrapperTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -122,7 +122,7 @@
      * Tests compilation requested by Truffle.
      */
     @Test
-    public void testTruffleCompilation() throws IOException, InterruptedException {
+    public void testTruffleCompilation1() throws IOException, InterruptedException {
         testHelper(Collections.emptyList(),
                         Arrays.asList(
                                         "-Dgraal.CompilationFailureAction=ExitVM",
@@ -130,6 +130,22 @@
                         "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
     }
 
+    /**
+     * Tests that TruffleCompilationExceptionsAreFatal works as expected.
+     */
+    @Test
+    public void testTruffleCompilation2() throws IOException, InterruptedException {
+        Probe[] probes = {
+                        new Probe("Exiting VM due to TruffleCompilationExceptionsAreFatal=true", 1),
+        };
+        testHelper(Arrays.asList(probes),
+                        Arrays.asList(
+                                        "-Dgraal.CompilationFailureAction=Silent",
+                                        "-Dgraal.TruffleCompilationExceptionsAreFatal=true",
+                                        "-Dgraal.CrashAt=root test1"),
+                        "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
+    }
+
     private static final boolean VERBOSE = Boolean.getBoolean(CompilationWrapperTest.class.getSimpleName() + ".verbose");
 
     private static void testHelper(List<Probe> initialProbes, List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException {
@@ -149,14 +165,17 @@
         }
 
         List<Probe> probes = new ArrayList<>(initialProbes);
-        Probe diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
-        probes.add(diagnosticProbe);
-        probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
-            @Override
-            String test() {
-                return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
-            }
-        });
+        Probe diagnosticProbe = null;
+        if (!extraVmArgs.contains("-Dgraal.TruffleCompilationExceptionsAreFatal=true")) {
+            diagnosticProbe = new Probe("Graal diagnostic output saved in ", 1);
+            probes.add(diagnosticProbe);
+            probes.add(new Probe("Forced crash after compiling", Integer.MAX_VALUE) {
+                @Override
+                String test() {
+                    return actualOccurrences > 0 ? null : "expected at least 1 occurrence";
+                }
+            });
+        }
 
         for (String line : proc.output) {
             for (Probe probe : probes) {
@@ -171,38 +190,42 @@
                 Assert.fail(String.format("Did not find expected occurences of '%s' in output of command: %s%n%s", probe.substring, error, proc));
             }
         }
+        if (diagnosticProbe != null) {
+            String line = diagnosticProbe.lastMatchingLine;
+            int substringStart = line.indexOf(diagnosticProbe.substring);
+            int substringLength = diagnosticProbe.substring.length();
+            String diagnosticOutputZip = line.substring(substringStart + substringLength).trim();
 
-        String diagnosticOutputZip = diagnosticProbe.lastMatchingLine.substring(diagnosticProbe.substring.length()).trim();
-
-        List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
+            List<String> dumpPathEntries = Arrays.asList(dumpPath.list());
 
-        File zip = new File(diagnosticOutputZip).getAbsoluteFile();
-        Assert.assertTrue(zip.toString(), zip.exists());
-        Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
-        try {
-            int bgv = 0;
-            int cfg = 0;
-            ZipFile dd = new ZipFile(diagnosticOutputZip);
-            List<String> entries = new ArrayList<>();
-            for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
-                ZipEntry ze = e.nextElement();
-                String name = ze.getName();
-                entries.add(name);
-                if (name.endsWith(".bgv")) {
-                    bgv++;
-                } else if (name.endsWith(".cfg")) {
-                    cfg++;
+            File zip = new File(diagnosticOutputZip).getAbsoluteFile();
+            Assert.assertTrue(zip.toString(), zip.exists());
+            Assert.assertTrue(zip + " not in " + dumpPathEntries, dumpPathEntries.contains(zip.getName()));
+            try {
+                int bgv = 0;
+                int cfg = 0;
+                ZipFile dd = new ZipFile(diagnosticOutputZip);
+                List<String> entries = new ArrayList<>();
+                for (Enumeration<? extends ZipEntry> e = dd.entries(); e.hasMoreElements();) {
+                    ZipEntry ze = e.nextElement();
+                    String name = ze.getName();
+                    entries.add(name);
+                    if (name.endsWith(".bgv")) {
+                        bgv++;
+                    } else if (name.endsWith(".cfg")) {
+                        cfg++;
+                    }
                 }
-            }
-            if (bgv == 0) {
-                Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+                if (bgv == 0) {
+                    Assert.fail(String.format("Expected at least one .bgv file in %s: %s%n%s", diagnosticOutputZip, entries, proc));
+                }
+                if (cfg == 0) {
+                    Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
+                }
+            } finally {
+                zip.delete();
+                dumpPath.delete();
             }
-            if (cfg == 0) {
-                Assert.fail(String.format("Expected at least one .cfg file in %s: %s", diagnosticOutputZip, entries));
-            }
-        } finally {
-            zip.delete();
-            dumpPath.delete();
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ExplicitExceptionTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,23 +22,44 @@
  */
 package org.graalvm.compiler.hotspot.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assume;
+import org.junit.Test;
 
 import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.TriState;
 
 public class ExplicitExceptionTest extends GraalCompilerTest {
 
     private int expectedForeignCallCount;
 
+    /**
+     * Determines if profiling info for {@code method} indicates an exception was thrown somewhere
+     * in the method. In the case of the {@code -Xcomp} VM option, interpreter execution can be
+     * skipped altogether and other execution engines (e.g., C1) may not record seen exceptions in a
+     * method profile.
+     */
+    private static boolean exceptionWasSeen(ResolvedJavaMethod method) {
+        ProfilingInfo profilingInfo = method.getProfilingInfo();
+        if (profilingInfo != null) {
+            for (int i = 0; i < profilingInfo.getCodeSize(); i++) {
+                if (profilingInfo.getExceptionSeen(i) == TriState.TRUE) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
         InstalledCode installedCode = super.getCode(method, graph, forceCompile, installAsDefault, options);
+        Assume.assumeTrue(exceptionWasSeen(method));
         assertDeepEquals(expectedForeignCallCount, lastCompiledGraph.getNodes().filter(ForeignCallNode.class).count());
         return installedCode;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRLockTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,11 +24,13 @@
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.MonitorInfo;
+import java.lang.management.RuntimeMXBean;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.phases.HighTier;
@@ -44,6 +46,7 @@
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import org.junit.Assume;
+import org.junit.BeforeClass;
 
 /**
  * Test on-stack-replacement with locks.
@@ -51,13 +54,28 @@
 public class GraalOSRLockTest extends GraalOSRTestBase {
 
     private static boolean TestInSeparateThread = false;
+    private static final String COMPILE_ONLY_FLAG = "-Xcomp";
 
-    public GraalOSRLockTest() {
+    @BeforeClass
+    public static void checkVMArguments() {
         try {
             Class.forName("java.lang.management.ManagementFactory");
         } catch (ClassNotFoundException ex) {
             Assume.assumeNoException("cannot check for monitors without java.management JDK9 module", ex);
         }
+        /*
+         * Note: The -Xcomp execution mode of the VM will stop most of the OSR test cases from
+         * working as every method is compiled at level3 (followed by level4 on the second
+         * invocation). The tests in this class are written in a way that they expect a method to be
+         * executed at the invocation BCI with the interpreter and then perform an OSR to an
+         * installed nmethod at a given BCI.
+         *
+         */
+        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+        List<String> arguments = runtimeMxBean.getInputArguments();
+        for (String arg : arguments) {
+            Assume.assumeFalse(arg.equals(COMPILE_ONLY_FLAG));
+        }
     }
 
     // testing only
@@ -438,7 +456,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -449,11 +467,11 @@
         ReturnValue ret = ReturnValue.FAILURE;
         synchronized (lock) {
             synchronized (lock1) {
-                for (int i = 1; i < limit; i++) {
+                for (int i = 1; i < 10 * limit; i++) {
                     GraalDirectives.blackhole(i);
-                    if (i % 1001 == 0) {
+                    if (i % 33 == 0) {
                         ret = ReturnValue.SUCCESS;
-                        if (GraalDirectives.inCompiledCode() && i + 33 > (limit)) {
+                        if (GraalDirectives.inCompiledCode() && i + 33 > (10 * limit)) {
                             GraalDirectives.blackhole(ret);
                             System.gc();
                         }
@@ -462,7 +480,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code already hereeeeee");
             } else {
                 // lock 1 must be free
                 if (isMonitorLockHeld(lock1)) {
@@ -519,7 +537,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -543,7 +561,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -568,7 +586,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
@@ -646,7 +664,7 @@
         synchronized (monitor) {
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
         }
         return ret;
@@ -670,7 +688,7 @@
             }
             GraalDirectives.controlFlowAnchor();
             if (!GraalDirectives.inCompiledCode()) {
-                throw new Error("Must part of compiled code");
+                throw new Error("Must be part of compiled code");
             }
             return ret;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -35,7 +35,9 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.hotspot.CompilationTask;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.java.BciBlockMapping;
 import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -76,6 +78,13 @@
         HotSpotCompilationRequest request = new HotSpotCompilationRequest((HotSpotResolvedJavaMethod) method, bci, jvmciEnv);
         HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
         CompilationTask task = new CompilationTask(runtime, compiler, request, true, true, debug.getOptions());
+        if (method instanceof HotSpotResolvedJavaMethod) {
+            HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
+            GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
+            if (((HotSpotResolvedJavaMethod) method).hasCodeAtLevel(bci, config.compilationLevelFullOptimization)) {
+                return;
+            }
+        }
         HotSpotCompilationRequestResult result = task.runCompilation(debug);
         if (result.getFailure() != null) {
             throw new GraalError(result.getFailureMessage());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,7 +37,6 @@
 import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
 import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopyNode;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
@@ -629,12 +628,6 @@
         System.arraycopy(a, 0, b, 0, a.length);
     }
 
-    @Test
-    public void test61() {
-        GraphPredicate checkForUnsafeArrayCopy = graph -> graph.getNodes().filter(UnsafeArrayCopyNode.class).count() > 0 ? 1 : 0;
-        testPredicate("test13Snippet", checkForUnsafeArrayCopy, new int[]{});
-    }
-
     private interface GraphPredicate {
         int apply(StructuredGraph graph);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -280,14 +280,19 @@
         }
         if (offset == -1) {
             try {
-                offset = getFieldOffset(name, Integer.class, "OopHandle");
+                offset = getFieldOffset(name, Integer.class, "jobject");
                 isHandle = true;
             } catch (JVMCIError e) {
-
+                try {
+                    // JDK-8186777
+                    offset = getFieldOffset(name, Integer.class, "OopHandle");
+                    isHandle = true;
+                } catch (JVMCIError e2) {
+                }
             }
         }
         if (offset == -1) {
-            throw new JVMCIError("cannot get offset of field " + name + " with type oop or OopHandle");
+            throw new JVMCIError("cannot get offset of field " + name + " with type oop, jobject or OopHandle");
         }
         classMirrorOffset = offset;
         classMirrorIsHandle = isHandle;
@@ -648,6 +653,8 @@
     public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**");
     public final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, isJDK8 ? "HeapWord**" : "HeapWord* volatile*");
 
+    public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false);
+
     public final long inlineCacheMissStub = getFieldValue("CompilerToVM::Data::SharedRuntime_ic_miss_stub", Long.class, "address");
     public final long handleWrongMethodStub = getFieldValue("CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", Long.class, "address");
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Thu Nov 16 12:15:55 2017 +0000
@@ -266,6 +266,8 @@
         unsafeArraycopyStub(HotSpotBackend.UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size);
     }
 
+    public static final ForeignCallDescriptor GENERIC_ARRAYCOPY = new ForeignCallDescriptor("generic_arraycopy", int.class, Word.class, int.class, Word.class, int.class, int.class);
+
     @NodeIntrinsic(ForeignCallNode.class)
     private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -284,7 +284,7 @@
 
     public Object mbean() {
         if (graalRuntime instanceof HotSpotGraalRuntime) {
-            return ((HotSpotGraalRuntime)graalRuntime).mbean();
+            return ((HotSpotGraalRuntime) graalRuntime).getMBean();
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -26,6 +26,8 @@
 import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
 
 import java.io.PrintStream;
+import java.util.Map;
+import java.util.Collections;
 
 import org.graalvm.compiler.debug.MethodFilter;
 import org.graalvm.compiler.options.Option;
@@ -190,4 +192,11 @@
         }
         return level;
     }
+
+    public Map<String, Object> mbeans() {
+        HotSpotGraalCompiler compiler = createCompiler(HotSpotJVMCIRuntime.runtime());
+        String name = "org.graalvm.compiler.hotspot:type=Options";
+        Object bean = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMBean();
+        return Collections.singletonMap(name, bean);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalMBean.java	Thu Nov 16 12:15:55 2017 +0000
@@ -283,10 +283,8 @@
     @Override
     public javax.management.MBeanInfo getMBeanInfo() {
         List<javax.management.MBeanAttributeInfo> attrs = new ArrayList<>();
-        if (registered != null) {
-            for (OptionDescriptor descr : allOptionDescriptors()) {
-                attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
-            }
+        for (OptionDescriptor descr : allOptionDescriptors()) {
+            attrs.add(new javax.management.MBeanAttributeInfo(descr.getName(), descr.getType().getName(), descr.getHelp(), true, true, false));
         }
         javax.management.MBeanOperationInfo[] ops = {
                         new javax.management.MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new javax.management.MBeanParameterInfo[]{
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Thu Nov 16 12:15:55 2017 +0000
@@ -317,7 +317,7 @@
         return compilationProblemsPerAction;
     }
 
-    final Object mbean() {
+    Object getMBean() {
         return mBean;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Nov 16 12:15:55 2017 +0000
@@ -28,8 +28,8 @@
 import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace;
 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_KLASS_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_LOCATION;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_MIRROR_HANDLE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.COMPRESSED_HUB_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.DISPLACED_MARK_WORD_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_LOCATION;
@@ -41,6 +41,7 @@
 import java.lang.ref.Reference;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
@@ -90,10 +91,8 @@
 import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets;
 import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
 import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySlowPathNode;
+import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyWithSlowPathNode;
 import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopySnippets;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.ArrayCopyUnrollNode;
-import org.graalvm.compiler.hotspot.replacements.arraycopy.UnsafeArrayCopySnippets;
 import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -193,7 +192,7 @@
 
     public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
                     HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
-        super(metaAccess, foreignCalls, target);
+        super(metaAccess, foreignCalls, target, runtime.getVMConfig().useCompressedOops);
         this.runtime = runtime;
         this.registers = registers;
         this.constantReflection = constantReflection;
@@ -216,7 +215,6 @@
         hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target);
         resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target);
         profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target);
-        providers.getReplacements().registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(options, factories, providers, target));
     }
 
     public MonitorSnippets.Templates getMonitorSnippets() {
@@ -315,10 +313,8 @@
             }
         } else if (n instanceof ArrayCopyNode) {
             arraycopySnippets.lower((ArrayCopyNode) n, tool);
-        } else if (n instanceof ArrayCopySlowPathNode) {
-            arraycopySnippets.lower((ArrayCopySlowPathNode) n, tool);
-        } else if (n instanceof ArrayCopyUnrollNode) {
-            arraycopySnippets.lower((ArrayCopyUnrollNode) n, tool);
+        } else if (n instanceof ArrayCopyWithSlowPathNode) {
+            arraycopySnippets.lower((ArrayCopyWithSlowPathNode) n, tool);
         } else if (n instanceof G1PreWriteBarrier) {
             writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
         } else if (n instanceof G1PostWriteBarrier) {
@@ -495,20 +491,18 @@
         }
     }
 
-    @Override
-    protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return HotSpotNarrowOopStamp.compressed((ObjectStamp) stamp, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.loadStamp(stamp, kind, compressible);
+    private CompressEncoding getOopEncoding() {
+        return runtime.getVMConfig().getOopEncoding();
     }
 
     @Override
-    protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return new HotSpotCompressionNode(CompressionOp.Uncompress, value, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.implicitLoadConvert(kind, value, compressible);
+    protected Stamp loadCompressedStamp(ObjectStamp stamp) {
+        return HotSpotNarrowOopStamp.compressed(stamp, getOopEncoding());
+    }
+
+    @Override
+    protected ValueNode newCompressionNode(CompressionOp op, ValueNode value) {
+        return new HotSpotCompressionNode(op, value, getOopEncoding());
     }
 
     @Override
@@ -519,14 +513,6 @@
     }
 
     @Override
-    protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
-        if (kind == JavaKind.Object && compressible && runtime.getVMConfig().useCompressedOops) {
-            return new HotSpotCompressionNode(CompressionOp.Compress, value, runtime.getVMConfig().getOopEncoding());
-        }
-        return super.implicitStoreConvert(kind, value, compressible);
-    }
-
-    @Override
     protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) {
         /*
          * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass
@@ -800,4 +786,9 @@
     public int arrayLengthOffset() {
         return runtime.getVMConfig().arrayOopDescLengthOffset();
     }
+
+    @Override
+    protected final JavaKind getStorageKind(ResolvedJavaField field) {
+        return field.getJavaKind();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Nov 16 12:15:55 2017 +0000
@@ -39,6 +39,7 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
@@ -68,6 +69,7 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ForeignCallPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
@@ -316,8 +318,8 @@
     private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
         ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
         int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
-        ValueNode scaledIndex = b.add(new LeftShiftNode(index, b.add(ConstantNode.forInt(shift))));
-        ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forInt(config.constantPoolSize))));
+        ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
+        ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
         AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
         boolean notCompressible = false;
         ValueNode elementValue = WordOperationPlugin.readOp(b, elementKind, elementAddress, NamedLocationIdentity.getArrayLocation(elementKind), BarrierType.NONE, notCompressible);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,6 +34,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER;
+import static org.graalvm.compiler.hotspot.HotSpotBackend.GENERIC_ARRAYCOPY;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.IC_MISS_HANDLER;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.INVOCATION_EVENT;
@@ -85,7 +86,6 @@
 import static org.graalvm.compiler.hotspot.stubs.NewInstanceStub.NEW_INSTANCE_C;
 import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
 import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
-import static org.graalvm.compiler.nodes.NamedLocationIdentity.any;
 import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
 import static org.graalvm.compiler.replacements.Log.LOG_OBJECT;
 import static org.graalvm.compiler.replacements.Log.LOG_PRIMITIVE;
@@ -97,6 +97,7 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
+import static org.graalvm.word.LocationIdentity.any;
 
 import java.util.EnumMap;
 
@@ -213,7 +214,7 @@
         // c_rarg4 - oop ckval (super_klass)
         // return: 0 = success, n = number of copied elements xor'd with -1.
         ForeignCallDescriptor desc = new ForeignCallDescriptor(name, int.class, Word.class, Word.class, Word.class, Word.class, Word.class);
-        LocationIdentity killed = NamedLocationIdentity.getArrayLocation(JavaKind.Object);
+        LocationIdentity killed = NamedLocationIdentity.any();
         registerForeignCall(desc, routine, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, killed);
         checkcastArraycopyDescriptors[uninit ? 1 : 0] = desc;
     }
@@ -333,6 +334,7 @@
         registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit);
         registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy);
 
+        registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
         registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any());
 
         if (c.useMultiplyToLenIntrinsic()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveDynamicConstantNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -28,6 +28,7 @@
 import org.graalvm.word.LocationIdentity;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -35,7 +36,7 @@
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 
-@NodeInfo(cycles = CYCLES_4, size = SIZE_16)
+@NodeInfo(cycles = CYCLES_4, size = SIZE_16, allowedUsageTypes = {InputType.Memory})
 public class ResolveDynamicConstantNode extends DeoptimizingFixedWithNextNode implements Lowerable, MemoryCheckpoint.Single {
     public static final NodeClass<ResolveDynamicConstantNode> TYPE = NodeClass.create(ResolveDynamicConstantNode.class);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileBranchNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -71,6 +71,15 @@
         return branchCondition != null;
     }
 
+    @Override
+    protected boolean canBeMergedWith(ProfileNode p) {
+        if (p instanceof ProfileBranchNode) {
+            ProfileBranchNode that = (ProfileBranchNode) p;
+            return this.method.equals(that.method) && this.bci == that.bci;
+        }
+        return false;
+    }
+
     /**
      * Gathers all the {@link ProfileBranchNode}s that are inputs to the
      * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileInvokeNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -37,6 +37,15 @@
         super(TYPE, method, freqLog, probabilityLog);
     }
 
+    @Override
+    protected boolean canBeMergedWith(ProfileNode p) {
+        if (p instanceof ProfileInvokeNode) {
+            ProfileInvokeNode that = (ProfileInvokeNode) p;
+            return this.method.equals(that.method);
+        }
+        return false;
+    }
+
     /**
      * Gathers all the {@link ProfileInvokeNode}s that are inputs to the
      * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -24,11 +24,17 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
+import static org.graalvm.compiler.nodes.util.GraphUtil.removeFixedWithUnusedInputs;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
+import org.graalvm.compiler.graph.spi.Simplifiable;
+import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.AbstractMergeNode;
+import org.graalvm.compiler.nodes.ControlSplitNode;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -41,7 +47,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 @NodeInfo(cycles = CYCLES_IGNORED, cyclesRationale = "profiling should be ignored", size = SIZE_IGNORED, sizeRationale = "profiling should be ignored")
-public class ProfileNode extends DeoptimizingFixedWithNextNode implements Lowerable {
+public abstract class ProfileNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable {
     public static class Options {
         @Option(help = "Control probabilistic profiling on AMD64", type = OptionType.Expert)//
         public static final OptionKey<Boolean> ProbabilisticProfiling = new OptionKey<>(true);
@@ -54,19 +60,21 @@
     // Only used if ProbabilisticProfiling == true and may be ignored by lowerer.
     @OptionalInput protected ValueNode random;
 
-    // logarithm base 2 of the profile probability
+    // Logarithm base 2 of the profile probability.
     protected int probabilityLog;
 
+    // Step value to add to the profile counter.
+    protected int step;
+
     protected ProfileNode(NodeClass<? extends DeoptimizingFixedWithNextNode> c, ResolvedJavaMethod method, int probabilityLog) {
         super(c, StampFactory.forVoid());
         this.method = method;
         this.probabilityLog = probabilityLog;
+        this.step = 1;
     }
 
     public ProfileNode(ResolvedJavaMethod method, int probabilityLog) {
-        super(TYPE, StampFactory.forVoid());
-        this.method = method;
-        this.probabilityLog = probabilityLog;
+        this(TYPE, method, probabilityLog);
     }
 
     @Override
@@ -92,6 +100,14 @@
         this.random = r;
     }
 
+    public int getStep() {
+        return step;
+    }
+
+    public void setStep(int s) {
+        step = s;
+    }
+
     /**
      * Get the logarithm base 2 of the profile probability.
      */
@@ -106,4 +122,25 @@
     public static NodeIterable<ProfileNode> getProfileNodes(StructuredGraph graph) {
         return graph.getNodes().filter(ProfileNode.class);
     }
+
+    protected abstract boolean canBeMergedWith(ProfileNode p);
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        for (Node p = predecessor(); p != null; p = p.predecessor()) {
+            // Terminate search when we hit a control split or merge.
+            if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) {
+                break;
+            }
+            if (p instanceof ProfileNode) {
+                ProfileNode that = (ProfileNode) p;
+                if (this.canBeMergedWith(that)) {
+                    that.setStep(this.getStep() + that.getStep());
+                    removeFixedWithUnusedInputs(this);
+                    tool.addToWorkList(that);
+                    break;
+                }
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/profiling/ProfileWithNotificationNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -28,7 +28,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 @NodeInfo
-public class ProfileWithNotificationNode extends ProfileNode {
+public abstract class ProfileWithNotificationNode extends ProfileNode {
     public static final NodeClass<ProfileWithNotificationNode> TYPE = NodeClass.create(ProfileWithNotificationNode.class);
 
     protected int freqLog;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,10 +22,16 @@
  */
 package org.graalvm.compiler.hotspot.phases;
 
+import static jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
 import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
 
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.cfg.Loop;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
@@ -37,13 +43,15 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
-import org.graalvm.compiler.nodes.AbstractLocalNode;
 import org.graalvm.compiler.nodes.EntryMarkerNode;
 import org.graalvm.compiler.nodes.EntryProxyNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StartNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -53,6 +61,7 @@
 import org.graalvm.compiler.nodes.extended.OSRMonitorEnterNode;
 import org.graalvm.compiler.nodes.extended.OSRStartNode;
 import org.graalvm.compiler.nodes.java.AccessMonitorNode;
+import org.graalvm.compiler.nodes.java.InstanceOfNode;
 import org.graalvm.compiler.nodes.java.MonitorEnterNode;
 import org.graalvm.compiler.nodes.java.MonitorExitNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -172,15 +181,32 @@
             if (value instanceof EntryProxyNode) {
                 EntryProxyNode proxy = (EntryProxyNode) value;
                 /*
-                 * we need to drop the stamp since the types we see during OSR may be too precise
-                 * (if a branch was not parsed for example).
+                 * We need to drop the stamp since the types we see during OSR may be too precise
+                 * (if a branch was not parsed for example). In cases when this is possible, we
+                 * insert a guard and narrow the OSRLocal stamp at its usages.
                  */
-                Stamp s = proxy.stamp().unrestricted();
-                AbstractLocalNode osrLocal = null;
+                Stamp narrowedStamp = proxy.value().stamp();
+                Stamp unrestrictedStamp = proxy.stamp().unrestricted();
+                ValueNode osrLocal;
                 if (i >= localsSize) {
-                    osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, s));
+                    osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));
                 } else {
-                    osrLocal = graph.addOrUnique(new OSRLocalNode(i, s));
+                    osrLocal = graph.addOrUnique(new OSRLocalNode(i, unrestrictedStamp));
+                }
+                // Speculate on the OSRLocal stamps that could be more precise.
+                OSRLocalSpeculationReason reason = new OSRLocalSpeculationReason(osrState.bci, narrowedStamp, i);
+                if (graph.getSpeculationLog().maySpeculate(reason) && osrLocal instanceof OSRLocalNode && value.getStackKind().equals(JavaKind.Object) && !narrowedStamp.isUnrestricted()) {
+                    // Add guard.
+                    LogicNode check = graph.addOrUniqueWithInputs(InstanceOfNode.createHelper((ObjectStamp) narrowedStamp, osrLocal, null, null));
+                    JavaConstant constant = graph.getSpeculationLog().speculate(reason);
+                    FixedGuardNode guard = graph.add(new FixedGuardNode(check, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, constant, false));
+                    graph.addAfterFixed(osrStart, guard);
+
+                    // Replace with a more specific type at usages.
+                    // We know that we are at the root,
+                    // so we need to replace the proxy in the state.
+                    proxy.replaceAtMatchingUsages(osrLocal, n -> n == osrState);
+                    osrLocal = graph.addOrUnique(new PiNode(osrLocal, narrowedStamp, guard));
                 }
                 proxy.replaceAndDelete(osrLocal);
             } else {
@@ -268,4 +294,30 @@
     public float codeSizeIncrease() {
         return 5.0f;
     }
+
+    private static class OSRLocalSpeculationReason implements SpeculationReason {
+        private int bci;
+        private Stamp speculatedStamp;
+        private int localIndex;
+
+        OSRLocalSpeculationReason(int bci, Stamp speculatedStamp, int localIndex) {
+            this.bci = bci;
+            this.speculatedStamp = speculatedStamp;
+            this.localIndex = localIndex;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof OSRLocalSpeculationReason) {
+                OSRLocalSpeculationReason that = (OSRLocalSpeculationReason) obj;
+                return this.bci == that.bci && this.speculatedStamp.equals(that.speculatedStamp) && this.localIndex == that.localIndex;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return (bci << 16) ^ speculatedStamp.hashCode() ^ localIndex;
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Nov 16 12:15:55 2017 +0000
@@ -670,6 +670,11 @@
     }
 
     @Fold
+    public static boolean useCMSIncrementalMode(@InjectedParameter GraalHotSpotVMConfig config) {
+        return config.cmsIncrementalMode;
+    }
+
+    @Fold
     public static boolean useCompressedOops(@InjectedParameter GraalHotSpotVMConfig config) {
         return config.useCompressedOops;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HubGetClassNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -71,7 +71,7 @@
             return null;
         } else {
             MetaAccessProvider metaAccess = tool.getMetaAccess();
-            if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(graph().getOptions())) {
+            if (metaAccess != null && hub.isConstant() && !GraalOptions.ImmutableCode.getValue(tool.getOptions())) {
                 ResolvedJavaType exactType = tool.getConstantReflection().asJavaType(hub.asConstant());
                 if (exactType != null) {
                     return ConstantNode.forConstant(tool.getConstantReflection().asJavaClass(exactType), metaAccess);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/IdentityHashCodeNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -67,7 +67,7 @@
         if (object.isConstant()) {
             assert object.stamp() instanceof AbstractObjectStamp;
             JavaConstant c = (JavaConstant) object.asConstant();
-            if (ImmutableCode.getValue(getOptions())) {
+            if (ImmutableCode.getValue(tool.getOptions())) {
                 return this;
             }
             JavaConstant identityHashCode = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySlowPathNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2015, 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.code.BytecodeFrame;
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.word.KlassPointer;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public final class ArrayCopySlowPathNode extends BasicArrayCopyNode {
-
-    public static final NodeClass<ArrayCopySlowPathNode> TYPE = NodeClass.create(ArrayCopySlowPathNode.class);
-
-    private final SnippetTemplate.SnippetInfo snippet;
-
-    /**
-     * Extra context for the slow path snippet.
-     */
-    private final Object argument;
-
-    /**
-     * AOT compilation requires klass constants to be exposed after the first lowering to be handled
-     * automatically. Lowering for {@link ArrayCopySlowPathNode}, with snippet ==
-     * {@link ArrayCopySnippets#arraycopyPredictedObjectWork}, requires a klass of Object[]. For
-     * other snippets {@link #predictedKlass} is a null constant.
-     */
-    @Input protected ValueNode predictedKlass;
-
-    public ArrayCopySlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode predictedKlass, JavaKind elementKind,
-                    SnippetTemplate.SnippetInfo snippet, Object argument) {
-        super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
-        assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
-        this.snippet = snippet;
-        this.argument = argument;
-        this.predictedKlass = predictedKlass;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer predictedKlass,
-                    @ConstantNodeParameter JavaKind elementKind, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet, @ConstantNodeParameter Object argument);
-
-    public SnippetTemplate.SnippetInfo getSnippet() {
-        return snippet;
-    }
-
-    public Object getArgument() {
-        return argument;
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    public void setBci(int bci) {
-        this.bci = bci;
-    }
-
-    public ValueNode getPredictedKlass() {
-        return predictedKlass;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopySnippets.java	Thu Nov 16 12:15:55 2017 +0000
@@ -28,11 +28,12 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayClassElementOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypePrimitiveInPlace;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHub;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.superCheckOffsetOffset;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
 
@@ -47,10 +48,8 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
 import org.graalvm.compiler.hotspot.word.KlassPointer;
 import org.graalvm.compiler.nodes.CallTargetNode;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.InvokeNode;
@@ -65,8 +64,10 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.ReplacementsUtil;
 import org.graalvm.compiler.replacements.SnippetCounter;
 import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetIntegerHistogram;
 import org.graalvm.compiler.replacements.SnippetTemplate;
 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
@@ -79,16 +80,208 @@
 import org.graalvm.word.WordFactory;
 
 import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
 public class ArrayCopySnippets implements Snippets {
 
+    private enum ArrayCopyTypeCheck {
+        UNDEFINED_ARRAY_TYPE_CHECK,
+        // we know that both objects are arrays and have the same type
+        NO_ARRAY_TYPE_CHECK,
+        // can be used when we know that one of the objects is a primitive array
+        HUB_BASED_ARRAY_TYPE_CHECK,
+        // must be used when we don't have sufficient information to use one of the others
+        LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
+    }
+
+    @Snippet
+    public static void arraycopyZeroLengthSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        counters.zeroLengthStaticCounter.inc();
+    }
+
+    @Snippet
+    public static void arraycopyExactSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter elementKindCounter, @ConstantParameter SnippetCounter elementKindCopiedCounter,
+                    @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        elementKindCounter.inc();
+        elementKindCopiedCounter.add(length);
+        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyUnrolledSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter JavaKind elementKind, @ConstantParameter int unrolledLength, @ConstantParameter Counters counters) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        unrolledArraycopyWork(nonNullSrc, srcPos, nonNullDest, destPos, unrolledLength, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyCheckcastSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck,
+                    @ConstantParameter Counters counters, @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyGenericSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter ArrayCopyTypeCheck arrayTypeCheck, @ConstantParameter Counters counters,
+                    @ConstantParameter SnippetInfo workSnippet, @ConstantParameter JavaKind elementKind) {
+        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
+        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
+        checkArrayTypes(nonNullSrc, nonNullDest, arrayTypeCheck);
+        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
+        incrementLengthCounter(length, counters);
+
+        ArrayCopyWithSlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, workSnippet, elementKind);
+    }
+
+    @Snippet
+    public static void arraycopyNativeSnippet(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        // all checks are done in the native method, so no need to emit additional checks here
+        incrementLengthCounter(length, counters);
+        counters.systemArraycopyCounter.inc();
+        counters.systemArraycopyCopiedCounter.add(length);
+
+        System.arraycopy(src, srcPos, dest, destPos, length);
+    }
+
+    @Fold
+    static LocationIdentity getArrayLocation(JavaKind kind) {
+        return NamedLocationIdentity.getArrayLocation(kind);
+    }
+
+    private static void unrolledArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, JavaKind elementKind) {
+        int scale = arrayIndexScale(elementKind);
+        int arrayBaseOffset = arrayBaseOffset(elementKind);
+        LocationIdentity arrayLocation = getArrayLocation(elementKind);
+
+        long sourceOffset = arrayBaseOffset + (long) srcPos * scale;
+        long destOffset = arrayBaseOffset + (long) destPos * scale;
+        long position = 0;
+        long delta = scale;
+        if (probability(NOT_FREQUENT_PROBABILITY, nonNullSrc == nonNullDest && srcPos < destPos)) {
+            // bad aliased case so we need to copy the array from back to front
+            position = (long) (length - 1) * scale;
+            delta = -delta;
+        }
+
+        // the length was already checked before - we can emit unconditional instructions
+        ExplodeLoopNode.explodeLoop();
+        for (int iteration = 0; iteration < length; iteration++) {
+            Object value = RawLoadNode.load(nonNullSrc, sourceOffset + position, elementKind, arrayLocation);
+            RawStoreNode.storeObject(nonNullDest, destOffset + position, value, elementKind, arrayLocation, false);
+            position += delta;
+        }
+    }
+
+    @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+    public static void checkcastArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        if (probability(FREQUENT_PROBABILITY, length > 0)) {
+            Object nonNullSrc = PiNode.asNonNullObject(src);
+            Object nonNullDest = PiNode.asNonNullObject(dest);
+            KlassPointer srcKlass = loadHub(nonNullSrc);
+            KlassPointer destKlass = loadHub(nonNullDest);
+            if (probability(LIKELY_PROBABILITY, srcKlass == destKlass)) {
+                // no storecheck required.
+                counters.objectCheckcastSameTypeCounter.inc();
+                counters.objectCheckcastSameTypeCopiedCounter.add(length);
+                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
+            } else {
+                KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
+                Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
+
+                counters.objectCheckcastDifferentTypeCounter.inc();
+                counters.objectCheckcastDifferentTypeCopiedCounter.add(length);
+
+                int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
+                if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+                    /*
+                     * the stub doesn't throw the ArrayStoreException, but returns the number of
+                     * copied elements (xor'd with -1).
+                     */
+                    copiedElements ^= -1;
+                    System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
+                }
+            }
+        }
+    }
+
+    @Snippet(allowPartialIntrinsicArgumentMismatch = true)
+    public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
+        if (probability(FREQUENT_PROBABILITY, length > 0)) {
+            counters.genericArraycopyDifferentTypeCounter.inc();
+            counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
+            int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
+            if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
+                /*
+                 * the stub doesn't throw the ArrayStoreException, but returns the number of copied
+                 * elements (xor'd with -1).
+                 */
+                copiedElements ^= -1;
+                System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
+            }
+        }
+    }
+
+    private static void incrementLengthCounter(int length, Counters counters) {
+        counters.lengthHistogram.inc(length);
+    }
+
+    private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
+        if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, destPos < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, length < 0) ||
+                        probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) ||
+                        probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
+            counters.checkAIOOBECounter.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+        }
+        counters.checkSuccessCounter.inc();
+    }
+
+    private static void checkArrayTypes(Object nonNullSrc, Object nonNullDest, ArrayCopyTypeCheck arrayTypeCheck) {
+        if (arrayTypeCheck == ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK) {
+            // nothing to do
+        } else if (arrayTypeCheck == ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK) {
+            KlassPointer srcHub = loadHub(nonNullSrc);
+            KlassPointer destHub = loadHub(nonNullDest);
+            if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
+                DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+            }
+        } else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
+            KlassPointer srcHub = loadHub(nonNullSrc);
+            KlassPointer destHub = loadHub(nonNullDest);
+            checkArrayType(srcHub);
+            checkArrayType(destHub);
+        } else {
+            ReplacementsUtil.staticAssert(false, "unknown array type check");
+        }
+    }
+
     private static int checkArrayType(KlassPointer nonNullHub) {
         int layoutHelper = readLayoutHelper(nonNullHub);
         if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
@@ -97,528 +290,228 @@
         return layoutHelper;
     }
 
-    private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) {
-        if (probability(SLOW_PATH_PROBABILITY, srcPos < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, destPos < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, length < 0)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        if (probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) {
-            counters.checkAIOOBECounter.inc();
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        counters.checkSuccessCounter.inc();
-    }
-
-    @Snippet
-    public static void arraycopyZeroLengthIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        checkArrayType(srcHub);
-        checkArrayType(destHub);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counters.zeroLengthStaticCounter.inc();
-    }
-
-    @Snippet
-    public static void arraycopyExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind, @ConstantParameter SnippetCounter counter,
-                    @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counter.inc();
-        copiedCounter.add(length);
-        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-    }
-
-    /**
-     * This intrinsic is useful for the case where we know something statically about one of the
-     * inputs but not the other.
-     */
-    @Snippet
-    public static void arraycopyPredictedExactIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        if (probability(SLOW_PATH_PROBABILITY, srcHub != destHub)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
-        }
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        counter.inc();
-        copiedCounter.add(length);
-        ArrayCopyCallNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, elementKind);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-    }
-
-    @Snippet
-    public static void arraycopyPredictedObjectWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, KlassPointer objectArrayKlass,
-                    @ConstantParameter SnippetCounter counter, @ConstantParameter SnippetCounter copiedCounter, @ConstantParameter Counters counters) {
-        if (length > 0) {
-            KlassPointer srcHub = loadHub(PiNode.asNonNullObject(nonNullSrc));
-            KlassPointer destHub = loadHub(PiNode.asNonNullObject(nonNullDest));
-            if (probability(FAST_PATH_PROBABILITY, srcHub == destHub || destHub == objectArrayKlass)) {
-                counter.inc();
-                copiedCounter.add(length);
-                counters.predictedObjectArrayCopyFastPathCounter.inc();
-                counters.predictedObjectArrayCopyFastPathCopiedCounter.add(length);
-                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            } else {
-                counters.predictedObjectArrayCopySlowPathCounter.inc();
-                counters.predictedObjectArrayCopySlowPathCopiedCounter.add(length);
-                System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            }
-        }
-    }
-
-    /**
-     * This is the basic template for the full arraycopy checks, including a check that the
-     * underlying type is really an array type.
-     */
-    @Snippet
-    public static void arraycopySlowPathIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, KlassPointer predictedKlass, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter SnippetInfo slowPath, @ConstantParameter Object slowPathArgument, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        checkArrayType(srcHub);
-        checkArrayType(destHub);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-        ArrayCopySlowPathNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, predictedKlass, elementKind, slowPath, slowPathArgument);
-    }
-
-    /**
-     * Snippet for unrolled arraycopy.
-     */
-    @Snippet
-    public static void arraycopyUnrolledIntrinsic(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter int unrolledLength, @ConstantParameter JavaKind elementKind,
-                    @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-        if (length == 0) {
-            counters.zeroLengthDynamicCounter.inc();
-        } else {
-            counters.nonZeroLengthDynamicCounter.inc();
-            counters.nonZeroLengthDynamicCopiedCounter.add(length);
-        }
-        ArrayCopyUnrollNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, unrolledLength, elementKind);
-    }
-
-    @Snippet
-    public static void checkcastArraycopyWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantParameter Counters counters) {
-        if (length > 0) {
-            KlassPointer destKlass = loadHub(nonNullDest);
-            KlassPointer srcKlass = loadHub(nonNullSrc);
-            if (probability(SLOW_PATH_PROBABILITY, srcKlass == destKlass)) {
-                // no storecheck required.
-                counters.objectCheckcastSameTypeCounter.inc();
-                counters.objectCheckcastSameTypeCopiedCounter.add(length);
-                ArrayCopyCallNode.arraycopyObjectKillsAny(nonNullSrc, srcPos, nonNullDest, destPos, length);
-            } else {
-                KlassPointer destElemKlass = destKlass.readKlassPointer(arrayClassElementOffset(INJECTED_VMCONFIG), OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION);
-                Word superCheckOffset = WordFactory.signed(destElemKlass.readInt(superCheckOffsetOffset(INJECTED_VMCONFIG), KLASS_SUPER_CHECK_OFFSET_LOCATION));
-                counters.objectCheckcastCounter.inc();
-                counters.objectCheckcastCopiedCounter.add(length);
-                int copiedElements = CheckcastArrayCopyCallNode.checkcastArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, superCheckOffset, destElemKlass, false);
-                if (copiedElements != 0) {
-                    /*
-                     * the checkcast stub doesn't throw the ArrayStoreException, but returns the
-                     * number of copied elements (xor'd with -1).
-                     */
-                    copiedElements ^= -1;
-                    System.arraycopy(nonNullSrc, srcPos + copiedElements, nonNullDest, destPos + copiedElements, length - copiedElements);
-                }
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopyGeneric(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
-        Object nonNullSrc = GraalDirectives.guardingNonNull(src);
-        Object nonNullDest = GraalDirectives.guardingNonNull(dest);
-        KlassPointer srcHub = loadHub(nonNullSrc);
-        KlassPointer destHub = loadHub(nonNullDest);
-        if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
-            int layoutHelper = checkArrayType(srcHub);
-            final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace(INJECTED_VMCONFIG)) == 0);
-            checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length, counters);
-            if (probability(FAST_PATH_PROBABILITY, isObjectArray)) {
-                counters.genericObjectExactCallCounter.inc();
-                counters.genericObjectExactCallCopiedCounter.add(length);
-                ArrayCopyCallNode.disjointArraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, JavaKind.Object);
-            } else {
-                counters.genericPrimitiveCallCounter.inc();
-                counters.genericPrimitiveCallCopiedCounter.add(length);
-                UnsafeArrayCopyNode.arraycopyPrimitive(nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper);
-            }
-        } else {
-            counters.systemArraycopyCounter.inc();
-            counters.systemArraycopyCopiedCounter.add(length);
-            System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
-        }
-    }
-
-    @Fold
-    static LocationIdentity getArrayLocation(JavaKind kind) {
-        return NamedLocationIdentity.getArrayLocation(kind);
-    }
-
-    @Snippet
-    public static void arraycopyUnrolledWork(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, @ConstantParameter int length, @ConstantParameter JavaKind elementKind) {
-        final int scale = arrayIndexScale(elementKind);
-        int arrayBaseOffset = arrayBaseOffset(elementKind);
-        LocationIdentity arrayLocation = getArrayLocation(elementKind);
-        if (nonNullSrc == nonNullDest && srcPos < destPos) { // bad aliased case
-            long start = (long) (length - 1) * scale;
-            long i = start;
-            ExplodeLoopNode.explodeLoop();
-            for (int iteration = 0; iteration < length; iteration++) {
-                if (i >= 0) {
-                    Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
-                    RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
-                    i -= scale;
-                }
-            }
-        } else {
-            long end = (long) length * scale;
-            long i = 0;
-            ExplodeLoopNode.explodeLoop();
-            for (int iteration = 0; iteration < length; iteration++) {
-                if (i < end) {
-                    Object a = RawLoadNode.load(nonNullSrc, arrayBaseOffset + i + (long) srcPos * scale, elementKind, arrayLocation);
-                    RawStoreNode.storeObject(nonNullDest, arrayBaseOffset + i + (long) destPos * scale, a, elementKind, arrayLocation, false);
-                    i += scale;
-                }
-            }
-        }
-    }
-
     static class Counters {
         final SnippetCounter checkSuccessCounter;
         final SnippetCounter checkAIOOBECounter;
 
-        final SnippetCounter objectCheckcastCounter;
-        final SnippetCounter objectCheckcastSameTypeCounter;
-        final SnippetCounter predictedObjectArrayCopySlowPathCounter;
-        final SnippetCounter predictedObjectArrayCopyFastPathCounter;
+        final SnippetCounter zeroLengthStaticCounter;
+        final SnippetIntegerHistogram lengthHistogram;
 
-        final SnippetCounter genericPrimitiveCallCounter;
-        final SnippetCounter genericObjectExactCallCounter;
         final SnippetCounter systemArraycopyCounter;
-
-        final SnippetCounter zeroLengthStaticCounter;
-        final SnippetCounter zeroLengthDynamicCounter;
-        final SnippetCounter nonZeroLengthDynamicCounter;
-
-        final SnippetCounter nonZeroLengthDynamicCopiedCounter;
-        final SnippetCounter genericPrimitiveCallCopiedCounter;
-        final SnippetCounter genericObjectExactCallCopiedCounter;
         final SnippetCounter systemArraycopyCopiedCounter;
 
-        final SnippetCounter objectCheckcastCopiedCounter;
+        final SnippetCounter genericArraycopyDifferentTypeCopiedCounter;
+        final SnippetCounter genericArraycopyDifferentTypeCounter;
+
         final SnippetCounter objectCheckcastSameTypeCopiedCounter;
-        final SnippetCounter predictedObjectArrayCopySlowPathCopiedCounter;
-        final SnippetCounter predictedObjectArrayCopyFastPathCopiedCounter;
+        final SnippetCounter objectCheckcastSameTypeCounter;
+        final SnippetCounter objectCheckcastDifferentTypeCopiedCounter;
+        final SnippetCounter objectCheckcastDifferentTypeCounter;
 
         final EnumMap<JavaKind, SnippetCounter> arraycopyCallCounters = new EnumMap<>(JavaKind.class);
-        final EnumMap<JavaKind, SnippetCounter> arraycopyCounters = new EnumMap<>(JavaKind.class);
-
         final EnumMap<JavaKind, SnippetCounter> arraycopyCallCopiedCounters = new EnumMap<>(JavaKind.class);
-        final EnumMap<JavaKind, SnippetCounter> arraycopyCopiedCounters = new EnumMap<>(JavaKind.class);
 
         Counters(SnippetCounter.Group.Factory factory) {
             final Group checkCounters = factory.createSnippetCounterGroup("System.arraycopy checkInputs");
-            final Group counters = factory.createSnippetCounterGroup("System.arraycopy");
-            final Group copiedCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
-            final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy 0-length checks");
+            final Group callCounters = factory.createSnippetCounterGroup("System.arraycopy calls");
+            final Group copiedElementsCounters = factory.createSnippetCounterGroup("System.arraycopy copied elements");
+            final Group lengthCounters = factory.createSnippetCounterGroup("System.arraycopy with 0-length");
 
             checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess");
             checkAIOOBECounter = new SnippetCounter(checkCounters, "checkAIOOBE", "checkAIOOBE");
 
-            objectCheckcastCounter = new SnippetCounter(counters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
-            objectCheckcastSameTypeCounter = new SnippetCounter(counters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
-            predictedObjectArrayCopySlowPathCounter = new SnippetCounter(counters, "Object[]{slow-path}", "used System.arraycopy slow path for predicted Object[] arrays");
-            predictedObjectArrayCopyFastPathCounter = new SnippetCounter(counters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
-            genericPrimitiveCallCounter = new SnippetCounter(counters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
-            genericObjectExactCallCounter = new SnippetCounter(counters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
-            systemArraycopyCounter = new SnippetCounter(counters, "genericObject", "call to System.arraycopy");
+            zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-length copy static", "calls where the length is statically 0");
+            lengthHistogram = new SnippetIntegerHistogram(lengthCounters, 2, "length", "length");
 
-            zeroLengthStaticCounter = new SnippetCounter(lengthCounters, "0-lengthcopy static", "arraycopy where the length is statically 0");
-            zeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "0-lengthcopy dynamically", "arraycopy where the length is dynamically 0");
-            nonZeroLengthDynamicCounter = new SnippetCounter(lengthCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
+            systemArraycopyCounter = new SnippetCounter(callCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+            systemArraycopyCopiedCounter = new SnippetCounter(copiedElementsCounters, "native System.arraycopy", "JNI-based System.arraycopy call");
+
+            genericArraycopyDifferentTypeCounter = new SnippetCounter(callCounters, "generic[] stub", "generic arraycopy stub");
+            genericArraycopyDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "generic[] stub", "generic arraycopy stub");
 
-            nonZeroLengthDynamicCopiedCounter = new SnippetCounter(copiedCounters, "non-0-lengthcopy dynamically", "arraycopy where the length is dynamically not zero");
-            genericPrimitiveCallCopiedCounter = new SnippetCounter(copiedCounters, "genericPrimitive", "generic arraycopy snippet for primitive arrays");
-            genericObjectExactCallCopiedCounter = new SnippetCounter(copiedCounters, "genericObjectExact", "generic arraycopy snippet for special object arrays");
-            systemArraycopyCopiedCounter = new SnippetCounter(copiedCounters, "genericObject", "call to System.arraycopy");
+            objectCheckcastSameTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+            objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (same-type)", "checkcast object[] stub but src.klass == dest.klass Object[] arrays");
+            objectCheckcastDifferentTypeCounter = new SnippetCounter(callCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
+            objectCheckcastDifferentTypeCopiedCounter = new SnippetCounter(copiedElementsCounters, "checkcast object[] (store-check)", "checkcast object[] stub with store check");
 
-            objectCheckcastCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{non-exact}", "arraycopy for non-exact Object[] arrays");
-            objectCheckcastSameTypeCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{same-type}", "arraycopy call for src.klass == dest.klass Object[] arrays");
-            predictedObjectArrayCopySlowPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{slow-path}",
-                            "used System.arraycopy slow path for predicted Object[] arrays");
-            predictedObjectArrayCopyFastPathCopiedCounter = new SnippetCounter(copiedCounters, "Object[]{fast-path}", "used oop_arraycopy for predicted Object[] arrays");
-            createArraycopyCounter(JavaKind.Byte, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Boolean, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Char, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Short, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Int, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Long, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Float, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Double, counters, copiedCounters);
-            createArraycopyCounter(JavaKind.Object, counters, copiedCounters);
+            createArraycopyCounter(JavaKind.Byte, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Boolean, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Char, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Short, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Int, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Long, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Float, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Double, callCounters, copiedElementsCounters);
+            createArraycopyCounter(JavaKind.Object, callCounters, copiedElementsCounters);
         }
 
         void createArraycopyCounter(JavaKind kind, Group counters, Group copiedCounters) {
-            arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
-            arraycopyCounters.put(kind, new SnippetCounter(counters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
-
-            arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{stub}", "arraycopy call for " + kind + "[] arrays"));
-            arraycopyCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[]{inline}", "inline arraycopy for " + kind + "[] arrays"));
+            arraycopyCallCounters.put(kind, new SnippetCounter(counters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
+            arraycopyCallCopiedCounters.put(kind, new SnippetCounter(copiedCounters, kind + "[] stub", "arraycopy call for " + kind + "[] arrays"));
         }
     }
 
     public static class Templates extends SnippetTemplate.AbstractTemplates {
+        private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGenericSnippet");
+        private final SnippetInfo arraycopyUnrolledSnippet = snippet("arraycopyUnrolledSnippet");
+        private final SnippetInfo arraycopyExactSnippet = snippet("arraycopyExactSnippet");
+        private final SnippetInfo arraycopyZeroLengthSnippet = snippet("arraycopyZeroLengthSnippet");
+        private final SnippetInfo arraycopyCheckcastSnippet = snippet("arraycopyCheckcastSnippet");
+        private final SnippetInfo arraycopyNativeSnippet = snippet("arraycopyNativeSnippet");
+
+        private final SnippetInfo checkcastArraycopyWithSlowPathWork = snippet("checkcastArraycopyWithSlowPathWork");
+        private final SnippetInfo genericArraycopyWithSlowPathWork = snippet("genericArraycopyWithSlowPathWork");
+
+        private ResolvedJavaMethod originalArraycopy;
+        private final Counters counters;
 
         public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, HotSpotProviders providers, TargetDescription target) {
             super(options, factories, providers, providers.getSnippetReflection(), target);
             this.counters = new Counters(factory);
         }
 
-        private ResolvedJavaMethod originalArraycopy() throws GraalError {
-            if (originalArraycopy == null) {
-                Method method;
-                try {
-                    method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
-                } catch (NoSuchMethodException | SecurityException e) {
-                    throw new GraalError(e);
-                }
-                originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
-            }
-            return originalArraycopy;
-        }
-
-        private ResolvedJavaMethod originalArraycopy;
-
-        private final SnippetInfo checkcastArraycopyWorkSnippet = snippet("checkcastArraycopyWork");
-        private final SnippetInfo arraycopyGenericSnippet = snippet("arraycopyGeneric");
-
-        private final SnippetInfo arraycopySlowPathIntrinsicSnippet = snippet("arraycopySlowPathIntrinsic");
-        private final SnippetInfo arraycopyUnrolledIntrinsicSnippet = snippet("arraycopyUnrolledIntrinsic");
-        private final SnippetInfo arraycopyExactIntrinsicSnippet = snippet("arraycopyExactIntrinsic");
-        private final SnippetInfo arraycopyZeroLengthIntrinsicSnippet = snippet("arraycopyZeroLengthIntrinsic");
-        private final SnippetInfo arraycopyPredictedExactIntrinsicSnippet = snippet("arraycopyPredictedExactIntrinsic");
-        private final SnippetInfo arraycopyPredictedObjectWorkSnippet = snippet("arraycopyPredictedObjectWork");
-
-        private final SnippetInfo arraycopyUnrolledWorkSnippet = snippet("arraycopyUnrolledWork");
-
-        private final Counters counters;
-
         protected SnippetInfo snippet(String methodName) {
             SnippetInfo info = snippet(ArrayCopySnippets.class, methodName, LocationIdentity.any());
             info.setOriginalMethod(originalArraycopy());
             return info;
         }
 
-        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
-            return selectComponentKind(arraycopy, true);
-        }
+        public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
+            JavaKind elementKind = selectComponentKind(arraycopy);
+            SnippetInfo snippetInfo;
+            ArrayCopyTypeCheck arrayTypeCheck;
 
-        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy, boolean exact) {
             ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
             ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+            if (!canBeArray(srcType) || !canBeArray(destType)) {
+                // at least one of the objects is definitely not an array - use the native call
+                // right away as the copying will fail anyways
+                snippetInfo = arraycopyNativeSnippet;
+                arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+            } else {
+                ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
+                ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
 
-            if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
-                if (!exact) {
-                    JavaKind component = getComponentKind(srcType);
-                    if (component != null) {
-                        return component;
+                if (arraycopy.isExact()) {
+                    // there is a sufficient type match - we don't need any additional type checks
+                    snippetInfo = arraycopyExactSnippet;
+                    arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+                } else if (srcComponentType == null && destComponentType == null) {
+                    // we don't know anything about the types - use the generic copying
+                    snippetInfo = arraycopyGenericSnippet;
+                    arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                } else if (srcComponentType != null && destComponentType != null) {
+                    if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
+                        // it depends on the array content if the copy succeeds - we need
+                        // a type check for every store
+                        snippetInfo = arraycopyCheckcastSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
+                    } else {
+                        // one object is an object array, the other one is a primitive array.
+                        // this copy will always fail - use the native call right away
+                        assert !srcComponentType.equals(destComponentType) : "must be handled by arraycopy.isExact()";
+                        snippetInfo = arraycopyNativeSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
                     }
-                    return getComponentKind(destType);
-                }
-                return null;
-            }
-            if (exact) {
-                if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
-                    return null;
-                }
-                if (!arraycopy.isExact()) {
-                    return null;
+                } else {
+                    ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
+                    if (nonNullComponentType.isPrimitive()) {
+                        // one involved object is a primitive array - we can safely assume that we
+                        // are copying primitive arrays
+                        snippetInfo = arraycopyExactSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
+                        elementKind = nonNullComponentType.getJavaKind();
+                    } else {
+                        // one involved object is an object array - we can safely assume that we are
+                        // copying object arrays that might require a store check
+                        snippetInfo = arraycopyCheckcastSnippet;
+                        arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
+                    }
                 }
             }
-            return srcType.getComponentType().getJavaKind();
-        }
 
-        private static JavaKind getComponentKind(ResolvedJavaType type) {
-            if (type != null && type.isArray()) {
-                return type.getComponentType().getJavaKind();
-            }
-            return null;
-        }
-
-        private static boolean shouldUnroll(ValueNode length) {
-            return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
-        }
-
-        public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
-            JavaKind componentKind = selectComponentKind(arraycopy);
-            SnippetInfo snippetInfo = null;
-            SnippetInfo slowPathSnippetInfo = null;
-            Object slowPathArgument = null;
-
+            // a few special cases that are easier to handle when all other variables already have a
+            // value
             if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
-                snippetInfo = arraycopyZeroLengthIntrinsicSnippet;
-            } else if (arraycopy.isExact()) {
-                snippetInfo = arraycopyExactIntrinsicSnippet;
-                if (shouldUnroll(arraycopy.getLength())) {
-                    snippetInfo = arraycopyUnrolledIntrinsicSnippet;
-                }
-            } else {
-                if (componentKind == JavaKind.Object) {
-                    ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
-                    ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
-                    ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
-                    ResolvedJavaType destComponentType = destType == null ? null : destType.getComponentType();
-                    if (srcComponentType != null && destComponentType != null && !srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
-                        snippetInfo = arraycopySlowPathIntrinsicSnippet;
-                        slowPathSnippetInfo = checkcastArraycopyWorkSnippet;
-                        slowPathArgument = LocationIdentity.any();
-                        /*
-                         * Because this snippet has to use Sysytem.arraycopy as a slow path, we must
-                         * pretend to kill any() so clear the componentKind.
-                         */
-                        componentKind = null;
-                    }
-                }
-                if (componentKind == null && snippetInfo == null) {
-                    JavaKind predictedKind = selectComponentKind(arraycopy, false);
-                    if (predictedKind != null) {
-                        /*
-                         * At least one array is of a known type requiring no store checks, so
-                         * assume the other is of the same type. Generally this is working around
-                         * deficiencies in our propagation of type information.
-                         */
-                        componentKind = predictedKind;
-                        if (predictedKind == JavaKind.Object) {
-                            snippetInfo = arraycopySlowPathIntrinsicSnippet;
-                            slowPathSnippetInfo = arraycopyPredictedObjectWorkSnippet;
-                            slowPathArgument = predictedKind;
-                            componentKind = null;
-                        } else {
-                            snippetInfo = arraycopyPredictedExactIntrinsicSnippet;
-                        }
-                    }
-                }
-                if (snippetInfo == null) {
-                    snippetInfo = arraycopyGenericSnippet;
-                }
+                snippetInfo = arraycopyZeroLengthSnippet;
+            } else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
+                snippetInfo = arraycopyUnrolledSnippet;
             }
+
+            // create the snippet
             Arguments args = new Arguments(snippetInfo, arraycopy.graph().getGuardsStage(), tool.getLoweringStage());
             args.add("src", arraycopy.getSource());
             args.add("srcPos", arraycopy.getSourcePosition());
             args.add("dest", arraycopy.getDestination());
             args.add("destPos", arraycopy.getDestinationPosition());
             args.add("length", arraycopy.getLength());
-            if (snippetInfo == arraycopyUnrolledIntrinsicSnippet) {
+            if (snippetInfo != arraycopyNativeSnippet) {
+                assert arrayTypeCheck != ArrayCopyTypeCheck.UNDEFINED_ARRAY_TYPE_CHECK;
+                args.addConst("arrayTypeCheck", arrayTypeCheck);
+            }
+            if (snippetInfo == arraycopyUnrolledSnippet) {
+                args.addConst("elementKind", elementKind != null ? elementKind : JavaKind.Illegal);
                 args.addConst("unrolledLength", arraycopy.getLength().asJavaConstant().asInt());
-                args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
-            } else if (snippetInfo == arraycopySlowPathIntrinsicSnippet) {
-                ValueNode predictedKlass = null;
-                if (slowPathArgument == arraycopyPredictedObjectWorkSnippet) {
-                    HotSpotResolvedObjectType arrayClass = (HotSpotResolvedObjectType) tool.getMetaAccess().lookupJavaType(Object[].class);
-                    predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), arrayClass.klass(), tool.getMetaAccess(), arraycopy.graph());
-                } else {
-                    predictedKlass = ConstantNode.forConstant(KlassPointerStamp.klassAlwaysNull(), JavaConstant.NULL_POINTER, tool.getMetaAccess(), arraycopy.graph());
-                }
-                args.add("predictedKlass", predictedKlass);
-                args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
-                args.addConst("slowPath", slowPathSnippetInfo);
-                assert slowPathArgument != null;
-                args.addConst("slowPathArgument", slowPathArgument);
-            } else if (snippetInfo == arraycopyExactIntrinsicSnippet || snippetInfo == arraycopyPredictedExactIntrinsicSnippet) {
-                assert componentKind != null;
-                args.addConst("elementKind", componentKind);
-                args.addConst("counter", counters.arraycopyCallCounters.get(componentKind));
-                args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(componentKind));
+            }
+            if (snippetInfo == arraycopyExactSnippet) {
+                assert elementKind != null;
+                args.addConst("elementKind", elementKind);
+                args.addConst("elementKindCounter", counters.arraycopyCallCounters.get(elementKind));
+                args.addConst("elementKindCopiedCounter", counters.arraycopyCallCopiedCounters.get(elementKind));
+            }
+            args.addConst("counters", counters);
+            if (snippetInfo == arraycopyCheckcastSnippet) {
+                args.addConst("workSnippet", checkcastArraycopyWithSlowPathWork);
+                args.addConst("elementKind", JavaKind.Illegal);
+            }
+            if (snippetInfo == arraycopyGenericSnippet) {
+                args.addConst("workSnippet", genericArraycopyWithSlowPathWork);
+                args.addConst("elementKind", JavaKind.Illegal);
             }
+
+            instantiate(args, arraycopy);
+        }
+
+        public void lower(ArrayCopyWithSlowPathNode arraycopy, LoweringTool tool) {
+            StructuredGraph graph = arraycopy.graph();
+            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
+                // if an arraycopy contains a slow path, we can't lower it right away
+                return;
+            }
+
+            SnippetInfo snippetInfo = arraycopy.getSnippet();
+            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
+            args.add("src", arraycopy.getSource());
+            args.add("srcPos", arraycopy.getSourcePosition());
+            args.add("dest", arraycopy.getDestination());
+            args.add("destPos", arraycopy.getDestinationPosition());
+            args.add("length", arraycopy.getLength());
             args.addConst("counters", counters);
             instantiate(args, arraycopy);
         }
 
-        public void lower(ArrayCopySlowPathNode arraycopy, LoweringTool tool) {
-            StructuredGraph graph = arraycopy.graph();
-            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
-                // Can't be lowered yet
-                return;
-            }
-            SnippetInfo snippetInfo = arraycopy.getSnippet();
-            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
-            args.add("nonNullSrc", arraycopy.getSource());
-            args.add("srcPos", arraycopy.getSourcePosition());
-            args.add("nonNullDest", arraycopy.getDestination());
-            args.add("destPos", arraycopy.getDestinationPosition());
-            if (snippetInfo == arraycopyUnrolledWorkSnippet) {
-                args.addConst("length", ((Integer) arraycopy.getArgument()).intValue());
-                args.addConst("elementKind", arraycopy.getElementKind());
-            } else {
-                args.add("length", arraycopy.getLength());
-            }
-            if (snippetInfo == arraycopyPredictedObjectWorkSnippet) {
-                args.add("objectArrayKlass", arraycopy.getPredictedKlass());
-                args.addConst("counter", counters.arraycopyCallCounters.get(JavaKind.Object));
-                args.addConst("copiedCounter", counters.arraycopyCallCopiedCounters.get(JavaKind.Object));
-                args.addConst("counters", counters);
-            }
-            instantiate(args, arraycopy);
+        private static boolean canBeArray(ResolvedJavaType type) {
+            return type == null || type.isJavaLangObject() || type.isArray();
         }
 
-        public void lower(ArrayCopyUnrollNode arraycopy, LoweringTool tool) {
-            StructuredGraph graph = arraycopy.graph();
-            if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
-                // Can't be lowered yet
-                return;
+        public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
+            ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
+            ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
+
+            if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
+                return null;
             }
-            SnippetInfo snippetInfo = arraycopyUnrolledWorkSnippet;
-            Arguments args = new Arguments(snippetInfo, graph.getGuardsStage(), tool.getLoweringStage());
-            args.add("nonNullSrc", arraycopy.getSource());
-            args.add("srcPos", arraycopy.getSourcePosition());
-            args.add("nonNullDest", arraycopy.getDestination());
-            args.add("destPos", arraycopy.getDestinationPosition());
-            args.addConst("length", arraycopy.getUnrollLength());
-            args.addConst("elementKind", arraycopy.getElementKind());
-            template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), arraycopy, SnippetTemplate.DEFAULT_REPLACER, args);
+            if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
+                return null;
+            }
+            if (!arraycopy.isExact()) {
+                return null;
+            }
+            return srcType.getComponentType().getJavaKind();
+        }
+
+        private static boolean shouldUnroll(ValueNode length) {
+            return length.isConstant() && length.asJavaConstant().asInt() <= 8 && length.asJavaConstant().asInt() != 0;
         }
 
         /**
@@ -650,8 +543,8 @@
                         newInvoke.setStateAfter(arraycopy.stateAfter());
                     }
                     graph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
-                } else if (originalNode instanceof ArrayCopySlowPathNode) {
-                    ArrayCopySlowPathNode slowPath = (ArrayCopySlowPathNode) replacements.get(originalNode);
+                } else if (originalNode instanceof ArrayCopyWithSlowPathNode) {
+                    ArrayCopyWithSlowPathNode slowPath = (ArrayCopyWithSlowPathNode) replacements.get(originalNode);
                     assert arraycopy.stateAfter() != null : arraycopy;
                     assert slowPath.stateAfter() == arraycopy.stateAfter();
                     slowPath.setBci(arraycopy.getBci());
@@ -659,5 +552,18 @@
             }
             GraphUtil.killCFG(arraycopy);
         }
+
+        private ResolvedJavaMethod originalArraycopy() throws GraalError {
+            if (originalArraycopy == null) {
+                Method method;
+                try {
+                    method = System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
+                } catch (NoSuchMethodException | SecurityException e) {
+                    throw new GraalError(e);
+                }
+                originalArraycopy = providers.getMetaAccess().lookupJavaMethod(method);
+            }
+            return originalArraycopy;
+        }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyUnrollNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2015, 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import jdk.vm.ci.meta.JavaKind;
-
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.word.LocationIdentity;
-
-@NodeInfo(allowedUsageTypes = InputType.Memory)
-public class ArrayCopyUnrollNode extends ArrayRangeWriteNode implements MemoryCheckpoint.Single, Lowerable, MemoryAccess {
-
-    public static final NodeClass<ArrayCopyUnrollNode> TYPE = NodeClass.create(ArrayCopyUnrollNode.class);
-
-    @Input protected ValueNode src;
-    @Input protected ValueNode srcPos;
-    @Input protected ValueNode dest;
-    @Input protected ValueNode destPos;
-    @Input protected ValueNode length;
-
-    private JavaKind elementKind;
-
-    private int unrolledLength;
-
-    @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
-
-    public ArrayCopyUnrollNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, int unrolledLength, JavaKind elementKind) {
-        super(TYPE, StampFactory.forKind(JavaKind.Void));
-        this.src = src;
-        this.srcPos = srcPos;
-        this.dest = dest;
-        this.destPos = destPos;
-        this.length = length;
-        this.unrolledLength = unrolledLength;
-        assert elementKind != null && elementKind != JavaKind.Illegal;
-        this.elementKind = elementKind;
-    }
-
-    public ValueNode getSource() {
-        return src;
-    }
-
-    public ValueNode getSourcePosition() {
-        return srcPos;
-    }
-
-    public ValueNode getDestination() {
-        return dest;
-    }
-
-    public ValueNode getDestinationPosition() {
-        return destPos;
-    }
-
-    @Override
-    public ValueNode getLength() {
-        return length;
-    }
-
-    @Override
-    public ValueNode getArray() {
-        return dest;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return destPos;
-    }
-
-    @Override
-    public boolean isObjectArray() {
-        return elementKind == JavaKind.Object;
-    }
-
-    @Override
-    public boolean isInitialization() {
-        return false;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter int unrolledLength,
-                    @ConstantNodeParameter JavaKind elementKind);
-
-    public int getUnrollLength() {
-        return unrolledLength;
-    }
-
-    public JavaKind getElementKind() {
-        return elementKind;
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getLowerer().lower(this, tool);
-    }
-
-    @Override
-    public MemoryNode getLastLocationAccess() {
-        return lastLocationAccess;
-    }
-
-    @Override
-    public void setLastLocationAccess(MemoryNode lla) {
-        updateUsagesInterface(lastLocationAccess, lla);
-        lastLocationAccess = lla;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/ArrayCopyWithSlowPathNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.graalvm.compiler.replacements.SnippetTemplate;
+import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
+
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = InputType.Memory)
+public final class ArrayCopyWithSlowPathNode extends BasicArrayCopyNode {
+
+    public static final NodeClass<ArrayCopyWithSlowPathNode> TYPE = NodeClass.create(ArrayCopyWithSlowPathNode.class);
+
+    private final SnippetTemplate.SnippetInfo snippet;
+
+    public ArrayCopyWithSlowPathNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, SnippetTemplate.SnippetInfo snippet, JavaKind elementKind) {
+        super(TYPE, src, srcPos, dest, destPos, length, elementKind, BytecodeFrame.INVALID_FRAMESTATE_BCI);
+        assert StampTool.isPointerNonNull(src) && StampTool.isPointerNonNull(dest) : "must have been null checked";
+        this.snippet = snippet;
+    }
+
+    @NodeIntrinsic
+    public static native void arraycopy(Object nonNullSrc, int srcPos, Object nonNullDest, int destPos, int length, @ConstantNodeParameter SnippetTemplate.SnippetInfo snippet,
+                    @ConstantNodeParameter JavaKind elementKind);
+
+    public SnippetTemplate.SnippetInfo getSnippet() {
+        return snippet;
+    }
+
+    public void setBci(int bci) {
+        this.bci = bci;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,12 +23,13 @@
 //JaCoCo Exclude
 package org.graalvm.compiler.hotspot.replacements.arraycopy;
 
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
 
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@@ -114,8 +115,9 @@
         graph().addBeforeFixed(this, basePtr);
 
         int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
-        ValueNode scaledIndex = graph().unique(new LeftShiftNode(pos, ConstantNode.forInt(shift, graph())));
-        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forInt(getArrayBaseOffset(JavaKind.Object), graph())));
+        ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
+        ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
         return graph().unique(new OffsetAddressNode(basePtr, offset));
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/GenericArrayCopyCallNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+//JaCoCo Exclude
+package org.graalvm.compiler.hotspot.replacements.arraycopy;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.word.LocationIdentity;
+
+import jdk.vm.ci.meta.JavaKind;
+
+@NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Value}, cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN)
+public final class GenericArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
+
+    public static final NodeClass<GenericArrayCopyCallNode> TYPE = NodeClass.create(GenericArrayCopyCallNode.class);
+    @Input ValueNode src;
+    @Input ValueNode srcPos;
+    @Input ValueNode dest;
+    @Input ValueNode destPos;
+    @Input ValueNode length;
+
+    protected final HotSpotGraalRuntimeProvider runtime;
+
+    protected GenericArrayCopyCallNode(@InjectedNodeParameter HotSpotGraalRuntimeProvider runtime, ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length) {
+        super(TYPE, StampFactory.forKind(JavaKind.Int));
+        this.src = src;
+        this.srcPos = srcPos;
+        this.dest = dest;
+        this.destPos = destPos;
+        this.length = length;
+        this.runtime = runtime;
+    }
+
+    public ValueNode getSource() {
+        return src;
+    }
+
+    public ValueNode getSourcePosition() {
+        return srcPos;
+    }
+
+    public ValueNode getDestination() {
+        return dest;
+    }
+
+    public ValueNode getDestinationPosition() {
+        return destPos;
+    }
+
+    public ValueNode getLength() {
+        return length;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
+            StructuredGraph graph = graph();
+            ValueNode srcAddr = objectAddress(getSource());
+            ValueNode destAddr = objectAddress(getDestination());
+            ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), HotSpotBackend.GENERIC_ARRAYCOPY, srcAddr, srcPos, destAddr, destPos, length));
+            call.setStateAfter(stateAfter());
+            graph.replaceFixedWithFixed(this, call);
+        }
+    }
+
+    private ValueNode objectAddress(ValueNode obj) {
+        GetObjectAddressNode result = graph().add(new GetObjectAddressNode(obj));
+        graph().addBeforeFixed(this, result);
+        return result;
+    }
+
+    private ValueNode wordValue(ValueNode value) {
+        if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
+            return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
+        }
+        return value;
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        return LocationIdentity.any();
+    }
+
+    @NodeIntrinsic
+    public static native int genericArraycopy(Object src, int srcPos, Object dest, int destPos, int length);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopyNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode;
-import org.graalvm.compiler.nodes.memory.MemoryAccess;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.memory.MemoryNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.word.LocationIdentity;
-
-import jdk.vm.ci.meta.JavaKind;
-
-@NodeInfo(allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_256, size = SIZE_64)
-public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single, MemoryAccess {
-
-    public static final NodeClass<UnsafeArrayCopyNode> TYPE = NodeClass.create(UnsafeArrayCopyNode.class);
-    @Input ValueNode src;
-    @Input ValueNode srcPos;
-    @Input ValueNode dest;
-    @Input ValueNode destPos;
-    @Input ValueNode length;
-    @OptionalInput ValueNode layoutHelper;
-
-    @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess;
-
-    protected JavaKind elementKind;
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, JavaKind elementKind) {
-        super(TYPE, StampFactory.forVoid());
-        assert layoutHelper == null || elementKind == null;
-        this.src = src;
-        this.srcPos = srcPos;
-        this.dest = dest;
-        this.destPos = destPos;
-        this.length = length;
-        this.layoutHelper = layoutHelper;
-        this.elementKind = elementKind;
-    }
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, JavaKind elementKind) {
-        this(src, srcPos, dest, destPos, length, null, elementKind);
-    }
-
-    public UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) {
-        this(src, srcPos, dest, destPos, length, layoutHelper, null);
-    }
-
-    @Override
-    public ValueNode getArray() {
-        return dest;
-    }
-
-    @Override
-    public ValueNode getIndex() {
-        return destPos;
-    }
-
-    @Override
-    public ValueNode getLength() {
-        return length;
-    }
-
-    @Override
-    public boolean isObjectArray() {
-        return elementKind == JavaKind.Object;
-    }
-
-    @Override
-    public boolean isInitialization() {
-        return false;
-    }
-
-    public JavaKind getElementKind() {
-        return elementKind;
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
-            UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class);
-            templates.lower(this, tool);
-        }
-    }
-
-    public void addSnippetArguments(Arguments args) {
-        args.add("src", src);
-        args.add("srcPos", srcPos);
-        args.add("dest", dest);
-        args.add("destPos", destPos);
-        args.add("length", length);
-        if (layoutHelper != null) {
-            args.add("layoutHelper", layoutHelper);
-        }
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        if (elementKind != null) {
-            return NamedLocationIdentity.getArrayLocation(elementKind);
-        }
-        return any();
-    }
-
-    @Override
-    public MemoryNode getLastLocationAccess() {
-        return lastLocationAccess;
-    }
-
-    @Override
-    public void setLastLocationAccess(MemoryNode lla) {
-        updateUsagesInterface(lastLocationAccess, lla);
-        lastLocationAccess = lla;
-    }
-
-    @NodeIntrinsic
-    public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter JavaKind elementKind);
-
-    @NodeIntrinsic
-    public static native void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.graalvm.compiler.hotspot.replacements.arraycopy;
-
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayIndexScale;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperHeaderSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeMask;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.runtime;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
-import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
-import static org.graalvm.word.LocationIdentity.any;
-
-import org.graalvm.compiler.api.replacements.Fold;
-import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.core.common.NumUtil;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.extended.RawLoadNode;
-import org.graalvm.compiler.nodes.extended.RawStoreNode;
-import org.graalvm.compiler.nodes.extended.UnsafeCopyNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.replacements.SnippetTemplate;
-import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
-import org.graalvm.compiler.replacements.Snippets;
-import org.graalvm.compiler.word.ObjectAccess;
-import org.graalvm.word.LocationIdentity;
-import org.graalvm.word.UnsignedWord;
-import org.graalvm.word.WordFactory;
-
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.JavaKind;
-
-/**
- * As opposed to {@link ArrayCopySnippets}, these Snippets do <b>not</b> perform store checks.
- */
-public class UnsafeArrayCopySnippets implements Snippets {
-
-    private static final boolean supportsUnalignedMemoryAccess = runtime().getHostJVMCIBackend().getTarget().arch.supportsUnalignedMemoryAccess();
-
-    private static final JavaKind VECTOR_KIND = JavaKind.Long;
-    private static final long VECTOR_SIZE = getArrayIndexScale(VECTOR_KIND);
-
-    private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, JavaKind baseKind, LocationIdentity locationIdentity) {
-        int arrayBaseOffset = arrayBaseOffset(baseKind);
-        int elementSize = arrayIndexScale(baseKind);
-        long byteLength = (long) length * elementSize;
-        long srcOffset = (long) srcPos * elementSize;
-        long destOffset = (long) destPos * elementSize;
-
-        long preLoopBytes;
-        long mainLoopBytes;
-        long postLoopBytes;
-
-        // We can easily vectorize the loop if both offsets have the same alignment.
-        if (byteLength >= VECTOR_SIZE && (srcOffset % VECTOR_SIZE) == (destOffset % VECTOR_SIZE)) {
-            preLoopBytes = NumUtil.roundUp(arrayBaseOffset + srcOffset, VECTOR_SIZE) - (arrayBaseOffset + srcOffset);
-            postLoopBytes = (byteLength - preLoopBytes) % VECTOR_SIZE;
-            mainLoopBytes = byteLength - preLoopBytes - postLoopBytes;
-        } else {
-            // Does the architecture support unaligned memory accesses?
-            if (supportsUnalignedMemoryAccess) {
-                preLoopBytes = byteLength % VECTOR_SIZE;
-                mainLoopBytes = byteLength - preLoopBytes;
-                postLoopBytes = 0;
-            } else {
-                // No. Let's do element-wise copying.
-                preLoopBytes = byteLength;
-                mainLoopBytes = 0;
-                postLoopBytes = 0;
-            }
-        }
-
-        if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) {
-            // bad aliased case
-            srcOffset += byteLength;
-            destOffset += byteLength;
-
-            // Post-loop
-            for (long i = 0; i < postLoopBytes; i += elementSize) {
-                srcOffset -= elementSize;
-                destOffset -= elementSize;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-            }
-            // Main-loop
-            for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
-                srcOffset -= VECTOR_SIZE;
-                destOffset -= VECTOR_SIZE;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
-            }
-            // Pre-loop
-            for (long i = 0; i < preLoopBytes; i += elementSize) {
-                srcOffset -= elementSize;
-                destOffset -= elementSize;
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-            }
-        } else {
-            // Pre-loop
-            for (long i = 0; i < preLoopBytes; i += elementSize) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-                srcOffset += elementSize;
-                destOffset += elementSize;
-            }
-            // Main-loop
-            for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, VECTOR_KIND, locationIdentity);
-                srcOffset += VECTOR_SIZE;
-                destOffset += VECTOR_SIZE;
-            }
-            // Post-loop
-            for (long i = 0; i < postLoopBytes; i += elementSize) {
-                UnsafeCopyNode.copy(src, arrayBaseOffset + srcOffset, dest, arrayBaseOffset + destOffset, baseKind, locationIdentity);
-                srcOffset += elementSize;
-                destOffset += elementSize;
-            }
-        }
-    }
-
-    @Fold
-    static LocationIdentity getArrayLocation(JavaKind kind) {
-        return NamedLocationIdentity.getArrayLocation(kind);
-    }
-
-    @Snippet
-    public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Byte;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyBoolean(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Boolean;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyChar(char[] src, int srcPos, char[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Char;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyShort(short[] src, int srcPos, short[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Short;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyInt(int[] src, int srcPos, int[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Int;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyFloat(float[] src, int srcPos, float[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Float;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyLong(long[] src, int srcPos, long[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Long;
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    @Snippet
-    public static void arraycopyDouble(double[] src, int srcPos, double[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Double;
-        /*
-         * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values to be
-         * copied atomically, but not long values. For example, on Intel 32-bit this code is not
-         * atomic as long as the vector kind remains Kind.Long.
-         */
-        vectorizedCopy(src, srcPos, dest, destPos, length, kind, getArrayLocation(kind));
-    }
-
-    /**
-     * For this kind, Object, we want to avoid write barriers between writes, but instead have them
-     * at the end of the snippet. This is done by using {@link RawStoreNode}, and rely on
-     * {@link WriteBarrierAdditionPhase} to put write barriers after the {@link UnsafeArrayCopyNode}
-     * with kind Object.
-     */
-    @Snippet
-    public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
-        JavaKind kind = JavaKind.Object;
-        final int scale = arrayIndexScale(kind);
-        int arrayBaseOffset = arrayBaseOffset(kind);
-        LocationIdentity arrayLocation = getArrayLocation(kind);
-        if (src == dest && srcPos < destPos) { // bad aliased case
-            long start = (long) (length - 1) * scale;
-            for (long i = start; i >= 0; i -= scale) {
-                Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
-                RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
-            }
-        } else {
-            long end = (long) length * scale;
-            for (long i = 0; i < end; i += scale) {
-                Object a = RawLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation);
-                RawStoreNode.storeObject(dest, arrayBaseOffset + i + (long) destPos * scale, a, kind, getArrayLocation(kind), false);
-            }
-        }
-    }
-
-    @Snippet
-    public static void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) {
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
-        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
-
-        UnsignedWord vectorSize = WordFactory.unsigned(VECTOR_SIZE);
-        UnsignedWord srcOffset = WordFactory.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
-        UnsignedWord destOffset = WordFactory.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
-        UnsignedWord destStart = destOffset;
-        UnsignedWord destEnd = destOffset.add(WordFactory.unsigned(length).shiftLeft(log2ElementSize));
-
-        UnsignedWord destVectorEnd = null;
-        UnsignedWord nonVectorBytes = null;
-        UnsignedWord sizeInBytes = WordFactory.unsigned(length).shiftLeft(log2ElementSize);
-        if (supportsUnalignedMemoryAccess) {
-            nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize);
-            destVectorEnd = destEnd;
-        } else {
-            boolean inPhase = srcOffset.and((int) VECTOR_SIZE - 1).equal(destOffset.and((int) VECTOR_SIZE - 1));
-            boolean hasAtLeastOneVector = sizeInBytes.aboveOrEqual(vectorSize);
-            // We must have at least one full vector, otherwise we must copy each byte separately
-            if (hasAtLeastOneVector && inPhase) { // If in phase, we can vectorize
-                nonVectorBytes = vectorSize.subtract(destStart.unsignedRemainder(vectorSize));
-            } else { // fallback is byte-wise
-                nonVectorBytes = sizeInBytes;
-            }
-            destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize));
-        }
-
-        UnsignedWord destNonVectorEnd = destStart.add(nonVectorBytes);
-        while (destOffset.belowThan(destNonVectorEnd)) {
-            ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
-            destOffset = destOffset.add(1);
-            srcOffset = srcOffset.add(1);
-        }
-        // Unsigned destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(8));
-        while (destOffset.belowThan(destVectorEnd)) {
-            ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, any()), any());
-            destOffset = destOffset.add(wordSize());
-            srcOffset = srcOffset.add(wordSize());
-        }
-        // Do the last bytes each when it is required to have absolute alignment.
-        while (!supportsUnalignedMemoryAccess && destOffset.belowThan(destEnd)) {
-            ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
-            destOffset = destOffset.add(1);
-            srcOffset = srcOffset.add(1);
-        }
-    }
-
-    public static class Templates extends AbstractTemplates {
-
-        private final SnippetInfo[] arraycopySnippets;
-        private final SnippetInfo genericPrimitiveSnippet;
-
-        public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, TargetDescription target) {
-            super(options, factories, providers, providers.getSnippetReflection(), target);
-
-            arraycopySnippets = new SnippetInfo[JavaKind.values().length];
-            arraycopySnippets[JavaKind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
-            arraycopySnippets[JavaKind.Byte.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyByte");
-            arraycopySnippets[JavaKind.Short.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyShort");
-            arraycopySnippets[JavaKind.Char.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyChar");
-            arraycopySnippets[JavaKind.Int.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyInt");
-            arraycopySnippets[JavaKind.Long.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyLong");
-            arraycopySnippets[JavaKind.Float.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyFloat");
-            arraycopySnippets[JavaKind.Double.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyDouble");
-            arraycopySnippets[JavaKind.Object.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyObject");
-
-            genericPrimitiveSnippet = snippet(UnsafeArrayCopySnippets.class, "arraycopyPrimitive");
-        }
-
-        public void lower(UnsafeArrayCopyNode node, LoweringTool tool) {
-            JavaKind elementKind = node.getElementKind();
-            SnippetInfo snippet;
-            if (elementKind == null) {
-                // primitive array of unknown kind
-                snippet = genericPrimitiveSnippet;
-            } else {
-                snippet = arraycopySnippets[elementKind.ordinal()];
-                assert snippet != null : "arraycopy snippet for " + elementKind.name() + " not found";
-            }
-
-            Arguments args = new Arguments(snippet, node.graph().getGuardsStage(), tool.getLoweringStage());
-            node.addSnippetArguments(args);
-
-            SnippetTemplate template = template(node.getDebug(), args);
-            template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args);
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProbabilisticProfileSnippets.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.TargetDescription;
 
 public class ProbabilisticProfileSnippets implements Snippets {
@@ -64,22 +65,22 @@
     }
 
     @Snippet
-    public static int notificationMask(int freqLog, int probLog) {
-        int probabilityMask = (1 << probLog) - 1;
+    public static int notificationMask(int freqLog, int probLog, int stepLog) {
         int frequencyMask = (1 << freqLog) - 1;
-        return frequencyMask & ~probabilityMask;
+        int stepMask = (1 << (stepLog + probLog)) - 1;
+        return frequencyMask & ~stepMask;
     }
 
     @NodeIntrinsic(ForeignCallNode.class)
     public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
 
     @Snippet
-    public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
+    public static void profileMethodEntryWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog) {
         if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
-            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
             counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
             if (freqLog >= 0) {
-                int mask = notificationMask(freqLog, probLog);
+                int mask = notificationMask(freqLog, probLog, stepLog);
                 if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                     methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
                 }
@@ -91,11 +92,12 @@
     public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
 
     @Snippet
-    public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci, int targetBci) {
+    public static void profileBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog, @ConstantParameter int probLog, int bci,
+                    int targetBci) {
         if (probability(1.0 / (1 << probLog), shouldProfile(probLog, random))) {
-            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + (config(INJECTED_VMCONFIG).invocationCounterIncrement << probLog);
+            int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + ((config(INJECTED_VMCONFIG).invocationCounterIncrement * step) << probLog);
             counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
-            int mask = notificationMask(freqLog, probLog);
+            int mask = notificationMask(freqLog, probLog, stepLog);
             if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                 methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
             }
@@ -103,10 +105,11 @@
     }
 
     @Snippet
-    public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, @ConstantParameter int freqLog, @ConstantParameter int probLog, boolean branchCondition,
+    public static void profileConditionalBackedgeWithProbability(MethodCountersPointer counters, int random, int step, int stepLog, @ConstantParameter int freqLog,
+                    @ConstantParameter int probLog, boolean branchCondition,
                     int bci, int targetBci) {
         if (branchCondition) {
-            profileBackedgeWithProbability(counters, random, freqLog, probLog, bci, targetBci);
+            profileBackedgeWithProbability(counters, random, step, stepLog, freqLog, probLog, bci, targetBci);
         }
     }
 
@@ -124,6 +127,8 @@
 
             StructuredGraph graph = profileNode.graph();
             LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+            ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+            ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
 
             if (profileNode instanceof ProfileBranchNode) {
                 // Backedge event
@@ -132,8 +137,11 @@
                 Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
                 ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
                 ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
+
                 args.add("counters", counters);
                 args.add("random", profileBranchNode.getRandom());
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
                 args.addConst("probLog", profileBranchNode.getProbabilityLog());
                 if (profileBranchNode.hasCondition()) {
@@ -148,8 +156,11 @@
                 ProfileInvokeNode profileInvokeNode = (ProfileInvokeNode) profileNode;
                 // Method invocation event
                 Arguments args = new Arguments(profileMethodEntryWithProbability, graph.getGuardsStage(), tool.getLoweringStage());
+
                 args.add("counters", counters);
                 args.add("random", profileInvokeNode.getRandom());
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
                 args.addConst("probLog", profileInvokeNode.getProbabilityLog());
                 SnippetTemplate template = template(graph.getDebug(), args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/profiling/ProfileSnippets.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
 import org.graalvm.compiler.replacements.Snippets;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.TargetDescription;
 
 public class ProfileSnippets implements Snippets {
@@ -61,12 +62,19 @@
     public static native void methodInvocationEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters);
 
     @Snippet
-    public static void profileMethodEntry(MethodCountersPointer counters, @ConstantParameter int freqLog) {
-        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+    protected static int notificationMask(int freqLog, int stepLog) {
+        int stepMask = (1 << stepLog) - 1;
+        int frequencyMask = (1 << freqLog) - 1;
+        return frequencyMask & ~stepMask;
+    }
+
+    @Snippet
+    public static void profileMethodEntry(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog) {
+        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).invocationCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
         counters.writeInt(config(INJECTED_VMCONFIG).invocationCounterOffset, counterValue);
         if (freqLog >= 0) {
-            final int frequencyMask = (1 << freqLog) - 1;
-            if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+            final int mask = notificationMask(freqLog, stepLog);
+            if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
                 methodInvocationEvent(HotSpotBackend.INVOCATION_EVENT, counters);
             }
         }
@@ -76,19 +84,19 @@
     public static native void methodBackedgeEvent(@ConstantNodeParameter ForeignCallDescriptor descriptor, MethodCountersPointer counters, int bci, int targetBci);
 
     @Snippet
-    public static void profileBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, int bci, int targetBci) {
-        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement;
+    public static void profileBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, int bci, int targetBci) {
+        int counterValue = counters.readInt(config(INJECTED_VMCONFIG).backedgeCounterOffset) + config(INJECTED_VMCONFIG).invocationCounterIncrement * step;
         counters.writeInt(config(INJECTED_VMCONFIG).backedgeCounterOffset, counterValue);
-        final int frequencyMask = (1 << freqLog) - 1;
-        if (probability(SLOW_PATH_PROBABILITY, (counterValue & (frequencyMask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
+        final int mask = notificationMask(freqLog, stepLog);
+        if (probability(SLOW_PATH_PROBABILITY, (counterValue & (mask << config(INJECTED_VMCONFIG).invocationCounterShift)) == 0)) {
             methodBackedgeEvent(HotSpotBackend.BACKEDGE_EVENT, counters, bci, targetBci);
         }
     }
 
     @Snippet
-    public static void profileConditionalBackedge(MethodCountersPointer counters, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
+    public static void profileConditionalBackedge(MethodCountersPointer counters, int step, int stepLog, @ConstantParameter int freqLog, boolean branchCondition, int bci, int targetBci) {
         if (branchCondition) {
-            profileBackedge(counters, freqLog, bci, targetBci);
+            profileBackedge(counters, step, stepLog, freqLog, bci, targetBci);
         }
     }
 
@@ -104,6 +112,8 @@
         public void lower(ProfileNode profileNode, LoweringTool tool) {
             StructuredGraph graph = profileNode.graph();
             LoadMethodCountersNode counters = graph.unique(new LoadMethodCountersNode(profileNode.getProfiledMethod()));
+            ConstantNode step = ConstantNode.forInt(profileNode.getStep(), graph);
+            ConstantNode stepLog = ConstantNode.forInt(CodeUtil.log2(profileNode.getStep()), graph);
 
             if (profileNode instanceof ProfileBranchNode) {
                 // Backedge event
@@ -113,6 +123,8 @@
                 ConstantNode bci = ConstantNode.forInt(profileBranchNode.bci(), graph);
                 ConstantNode targetBci = ConstantNode.forInt(profileBranchNode.targetBci(), graph);
                 args.add("counters", counters);
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileBranchNode.getNotificationFreqLog());
                 if (profileBranchNode.hasCondition()) {
                     args.add("branchCondition", profileBranchNode.branchCondition());
@@ -127,6 +139,8 @@
                 // Method invocation event
                 Arguments args = new Arguments(profileMethodEntry, graph.getGuardsStage(), tool.getLoweringStage());
                 args.add("counters", counters);
+                args.add("step", step);
+                args.add("stepLog", stepLog);
                 args.addConst("freqLog", profileInvokeNode.getNotificationFreqLog());
                 SnippetTemplate template = template(graph.getDebug(), args);
                 template.instantiate(providers.getMetaAccess(), profileNode, DEFAULT_REPLACER, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,6 +33,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.formatArray;
@@ -122,7 +123,7 @@
         // check that array length is small enough for fast path.
         Word thread = registerAsWord(threadRegister);
         boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
-        if (inlineContiguousAllocationSupported && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
+        if (inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG) && length >= 0 && length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) {
             Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
             if (memory.notEqual(0)) {
                 if (logging(options)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java	Thu Nov 16 12:15:55 2017 +0000
@@ -53,6 +53,7 @@
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabRefillWasteLimitOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabSlowAllocationsOffset;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabStats;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useG1GC;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useTLAB;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
@@ -147,7 +148,7 @@
          */
         Word thread = registerAsWord(threadRegister);
         boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported();
-        if (!forceSlowPath(options) && inlineContiguousAllocationSupported) {
+        if (!forceSlowPath(options) && inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG)) {
             if (isInstanceKlassFullyInitialized(hub)) {
                 int sizeInBytes = readLayoutHelper(hub);
                 Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Thu Nov 16 12:15:55 2017 +0000
@@ -342,7 +342,7 @@
 import org.graalvm.compiler.nodes.calc.AndNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
@@ -374,7 +374,6 @@
 import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
 import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -383,6 +382,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin;
 import org.graalvm.compiler.nodes.java.ArrayLengthNode;
@@ -435,6 +435,7 @@
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Signature;
 import jdk.vm.ci.meta.TriState;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -1036,7 +1037,7 @@
         deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
-    private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
+    private AbstractBeginNode handleException(ValueNode exceptionObject, int bci, boolean deoptimizeOnly) {
         assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
         debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
 
@@ -1058,8 +1059,12 @@
         this.controlFlowSplit = true;
         FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState);
 
-        createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
-
+        if (deoptimizeOnly) {
+            DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
+            dispatchBegin.setNext(BeginNode.begin(deoptimizeNode));
+        } else {
+            createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
+        }
         return dispatchBegin;
     }
 
@@ -1111,7 +1116,7 @@
     }
 
     protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
-        return DivNode.create(x, y);
+        return FloatDivNode.create(x, y);
     }
 
     protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
@@ -1215,7 +1220,7 @@
         ValueNode exception = frameState.pop(JavaKind.Object);
         FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
         ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
-        lastInstr.setNext(handleException(nonNullException, bci()));
+        lastInstr.setNext(handleException(nonNullException, bci(), false));
     }
 
     protected LogicNode createInstanceOf(TypeReference type, ValueNode object) {
@@ -1275,12 +1280,12 @@
         }
         BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
         AbstractBeginNode falseSucc = graph.add(new BeginNode());
-        ValueNode nonNullReceiver = graph.addOrUnique(PiNode.create(receiver, objectNonNull(), falseSucc));
+        ValueNode nonNullReceiver = graph.addOrUniqueWithInputs(PiNode.create(receiver, objectNonNull(), falseSucc));
         append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(receiver)), exception, falseSucc, SLOW_PATH_PROBABILITY));
         lastInstr = falseSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
-        exception.setNext(handleException(exception, bci()));
+        exception.setNext(handleException(exception, bci(), false));
         EXPLICIT_EXCEPTIONS.increment(debug);
         return nonNullReceiver;
     }
@@ -1292,7 +1297,7 @@
         lastInstr = trueSucc;
 
         exception.setStateAfter(createFrameState(bci(), exception));
-        exception.setNext(handleException(exception, bci()));
+        exception.setNext(handleException(exception, bci(), false));
     }
 
     protected ValueNode genArrayLength(ValueNode x) {
@@ -1532,8 +1537,8 @@
     @Override
     public void handleReplacedInvoke(CallTargetNode callTarget, JavaKind resultType) {
         BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
-        boolean withExceptionEdge = intrinsicCallSiteParser == null ? !omitInvokeExceptionEdge(null) : !intrinsicCallSiteParser.omitInvokeExceptionEdge(null);
-        createNonInlinedInvoke(withExceptionEdge, bci(), callTarget, resultType);
+        ExceptionEdgeAction exceptionEdgeAction = intrinsicCallSiteParser == null ? getActionForInvokeExceptionEdge(null) : intrinsicCallSiteParser.getActionForInvokeExceptionEdge(null);
+        createNonInlinedInvoke(exceptionEdgeAction, bci(), callTarget, resultType);
     }
 
     protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
@@ -1603,7 +1608,7 @@
 
         int invokeBci = bci();
         JavaTypeProfile profile = getProfileForInvoke(invokeKind);
-        boolean withExceptionEdge = !omitInvokeExceptionEdge(inlineInfo);
+        ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
         boolean partialIntrinsicExit = false;
         if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
             partialIntrinsicExit = true;
@@ -1614,7 +1619,7 @@
                 // must use the same context as the call to the intrinsic.
                 invokeBci = intrinsicCallSiteParser.bci();
                 profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
-                withExceptionEdge = !intrinsicCallSiteParser.omitInvokeExceptionEdge(inlineInfo);
+                edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
             } else {
                 // We are parsing the intrinsic for the root compilation or for inlining,
                 // This call is a partial intrinsic exit, and we do not have profile information
@@ -1624,7 +1629,7 @@
                 assert intrinsicContext.isPostParseInlined();
                 invokeBci = BytecodeFrame.UNKNOWN_BCI;
                 profile = null;
-                withExceptionEdge = graph.method().getAnnotation(Snippet.class) == null;
+                edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
             }
 
             if (originalMethod.isStatic()) {
@@ -1637,10 +1642,10 @@
             Signature sig = originalMethod.getSignature();
             returnType = sig.getReturnType(method.getDeclaringClass());
             resultType = sig.getReturnKind();
-            assert checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
+            assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
             targetMethod = originalMethod;
         }
-        Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
+        Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
         if (partialIntrinsicExit) {
             // This invoke must never be later inlined as it might select the intrinsic graph.
             // Until there is a mechanism to guarantee that any late inlining will not select
@@ -1698,14 +1703,14 @@
         } else {
             for (int i = 0; i < recursiveArgs.length; i++) {
                 ValueNode arg = GraphUtil.unproxify(recursiveArgs[i]);
-                assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s", i,
-                                ParameterNode.class.getSimpleName(), i, arg);
+                assert arg instanceof ParameterNode && ((ParameterNode) arg).index() == i : String.format("argument %d of call denoting partial intrinsic exit should be a %s with index %d, not %s",
+                                i, ParameterNode.class.getSimpleName(), i, arg);
             }
         }
         return true;
     }
 
-    protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
+    protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, ValueNode[] invokeArgs, ResolvedJavaMethod targetMethod,
                     InvokeKind invokeKind, JavaKind resultType, JavaType returnType, JavaTypeProfile profile) {
 
         StampPair returnStamp = graphBuilderConfig.getPlugins().getOverridingStamp(this, returnType, false);
@@ -1714,7 +1719,7 @@
         }
 
         MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, targetMethod, invokeArgs, returnStamp, profile));
-        Invoke invoke = createNonInlinedInvoke(withExceptionEdge, invokeBci, callTarget, resultType);
+        Invoke invoke = createNonInlinedInvoke(exceptionEdge, invokeBci, callTarget, resultType);
 
         for (InlineInvokePlugin plugin : graphBuilderConfig.getPlugins().getInlineInvokePlugins()) {
             plugin.notifyNotInlined(this, targetMethod, invoke);
@@ -1723,11 +1728,11 @@
         return invoke;
     }
 
-    protected Invoke createNonInlinedInvoke(boolean withExceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
-        if (!withExceptionEdge) {
+    protected Invoke createNonInlinedInvoke(ExceptionEdgeAction exceptionEdge, int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+        if (exceptionEdge == ExceptionEdgeAction.OMIT) {
             return createInvoke(invokeBci, callTarget, resultType);
         } else {
-            Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType);
+            Invoke invoke = createInvokeWithException(invokeBci, callTarget, resultType, exceptionEdge);
             AbstractBeginNode beginNode = graph.add(KillingBeginNode.create(LocationIdentity.any()));
             invoke.setNext(beginNode);
             lastInstr = beginNode;
@@ -1736,20 +1741,29 @@
     }
 
     /**
-     * If the method returns true, the invocation of the given {@link MethodCallTargetNode call
-     * target} does not need an exception edge.
+     * Describes what should be done with the exception edge of an invocation. The edge can be
+     * omitted or included. An included edge can handle the exception or transfer execution to the
+     * interpreter for handling (deoptimize).
      */
-    protected boolean omitInvokeExceptionEdge(InlineInfo lastInlineInfo) {
+    protected enum ExceptionEdgeAction {
+        OMIT,
+        INCLUDE_AND_HANDLE,
+        INCLUDE_AND_DEOPTIMIZE
+    }
+
+    protected ExceptionEdgeAction getActionForInvokeExceptionEdge(InlineInfo lastInlineInfo) {
         if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_NO_EXCEPTION) {
-            return true;
+            return ExceptionEdgeAction.OMIT;
+        } else if (lastInlineInfo == InlineInfo.DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION) {
+            return ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.CheckAll) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.ExplicitOnly) {
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         } else if (graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.OmitAll) {
-            return true;
+            return ExceptionEdgeAction.OMIT;
         } else {
             assert graphBuilderConfig.getBytecodeExceptionMode() == BytecodeExceptionMode.Profile;
             // be conservative if information was not recorded (could result in endless
@@ -1759,12 +1773,12 @@
                     if (profilingInfo != null) {
                         TriState exceptionSeen = profilingInfo.getExceptionSeen(bci());
                         if (exceptionSeen == TriState.FALSE) {
-                            return true;
+                            return ExceptionEdgeAction.OMIT;
                         }
                     }
                 }
             }
-            return false;
+            return ExceptionEdgeAction.INCLUDE_AND_HANDLE;
         }
     }
 
@@ -1887,7 +1901,7 @@
                     if (newProfile != profile) {
                         if (newProfile.getTypes().length == 0) {
                             // All profiled types select the intrinsic so
-                            // emit a fixed guard instead of a if-then-else.
+                            // emit a fixed guard instead of an if-then-else.
                             lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
                             return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
                         }
@@ -1966,7 +1980,7 @@
                     }
 
                     lastInstr = intrinsicGuard.nonIntrinsicBranch;
-                    createNonInlinedInvoke(omitInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
+                    createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
 
                     EndNode nonIntrinsicEnd = append(new EndNode());
                     AbstractMergeNode mergeNode = graph.add(new MergeNode());
@@ -2303,7 +2317,7 @@
             if (calleeBeforeUnwindNode != null) {
                 ValueNode calleeUnwindValue = parser.getUnwindValue();
                 assert calleeUnwindValue != null;
-                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
             }
         }
     }
@@ -2319,7 +2333,7 @@
         return invoke;
     }
 
-    protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType) {
+    protected InvokeWithExceptionNode createInvokeWithException(int invokeBci, CallTargetNode callTarget, JavaKind resultType, ExceptionEdgeAction exceptionEdgeAction) {
         if (currentBlock != null && stream.nextBCI() > currentBlock.endBci) {
             /*
              * Clear non-live locals early so that the exception handler entry gets the cleared
@@ -2328,7 +2342,7 @@
             frameState.clearNonLiveLocals(currentBlock, liveness, false);
         }
 
-        AbstractBeginNode exceptionEdge = handleException(null, bci());
+        AbstractBeginNode exceptionEdge = handleException(null, bci(), exceptionEdgeAction == ExceptionEdgeAction.INCLUDE_AND_DEOPTIMIZE);
         InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, invokeBci));
         frameState.pushReturn(resultType, invoke);
         invoke.setStateAfter(createFrameState(stream.nextBCI(), invoke));
@@ -2359,20 +2373,43 @@
             }
         }
 
+        ValueNode realReturnVal = processReturnValue(returnVal, returnKind);
+
         frameState.setRethrowException(false);
         frameState.clearStack();
-        beforeReturn(returnVal, returnKind);
+        beforeReturn(realReturnVal, returnKind);
         if (parent == null) {
-            append(new ReturnNode(returnVal));
+            append(new ReturnNode(realReturnVal));
         } else {
             if (returnDataList == null) {
                 returnDataList = new ArrayList<>();
             }
-            returnDataList.add(new ReturnToCallerData(returnVal, lastInstr));
+            returnDataList.add(new ReturnToCallerData(realReturnVal, lastInstr));
             lastInstr = null;
         }
     }
 
+    private ValueNode processReturnValue(ValueNode value, JavaKind kind) {
+        JavaKind returnKind = method.getSignature().getReturnKind();
+        if (kind != returnKind) {
+            // sub-word integer
+            assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
+            IntegerStamp stamp = (IntegerStamp) value.stamp();
+
+            // the bytecode verifier doesn't check that the value is in the correct range
+            if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
+                ValueNode narrow = append(genNarrow(value, returnKind.getBitCount()));
+                if (returnKind.isUnsigned()) {
+                    return append(genZeroExtend(narrow, 32));
+                } else {
+                    return append(genSignExtend(narrow, 32));
+                }
+            }
+        }
+
+        return value;
+    }
+
     private void beforeReturn(ValueNode x, JavaKind kind) {
         if (graph.method() != null && graph.method().isJavaLangObjectInit()) {
             /*
@@ -2794,6 +2831,8 @@
     }
 
     private void createExceptionDispatch(ExceptionDispatchBlock block) {
+        lastInstr = finishInstruction(lastInstr, frameState);
+
         assert frameState.stackSize() == 1 : frameState;
         if (block.handler.isCatchAll()) {
             assert block.getSuccessorCount() == 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -207,7 +207,7 @@
                 receiver = new ParameterNode(javaIndex, receiverStamp);
             }
 
-            locals[javaIndex] = graph.addOrUnique(receiver);
+            locals[javaIndex] = graph.addOrUniqueWithInputs(receiver);
             javaIndex = 1;
             index = 1;
         }
@@ -241,7 +241,7 @@
                 param = new ParameterNode(index, stamp);
             }
 
-            locals[javaIndex] = graph.addOrUnique(param);
+            locals[javaIndex] = graph.addOrUniqueWithInputs(param);
             javaIndex++;
             if (kind.needsTwoSlots()) {
                 locals[javaIndex] = TWO_SLOT_MARKER;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/ConditionalElimination02.java	Thu Nov 16 12:15:55 2017 +0000
@@ -29,6 +29,9 @@
 import org.junit.Test;
 
 import org.graalvm.compiler.jtt.JTTTest;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 
 public class ConditionalElimination02 extends JTTTest {
 
@@ -59,6 +62,14 @@
         return -1;
     }
 
+    /**
+     * These tests assume all code paths are reachable so disable profile based dead code removal.
+     */
+    @Override
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
+    }
+
     @Test
     public void run0() throws Throwable {
         runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Double04.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of double operations.
+ */
+public class Fold_Double04 extends JTTTest {
+
+    // Contrived check whether both arguments are the same kind of zero
+    public static boolean test(double x, double y) {
+        if (x == 0) {
+            if (1 / x == Double.NEGATIVE_INFINITY) {
+                return 1 / y == Double.NEGATIVE_INFINITY;
+            } else {
+                return 1 / y == Double.POSITIVE_INFINITY;
+            }
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", -0d, -0d);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", -0d, 0d);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 0d, -0d);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 0d, 0d);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/Fold_Float03.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ * Tests constant folding of float operations.
+ */
+public class Fold_Float03 extends JTTTest {
+
+    // Contrived check whether both arguments are the same kind of zero
+    public static boolean test(float x, float y) {
+        if (x == 0) {
+            if (1 / x == Float.NEGATIVE_INFINITY) {
+                return 1 / y == Float.NEGATIVE_INFINITY;
+            } else {
+                return 1 / y == Float.POSITIVE_INFINITY;
+            }
+        }
+        return false;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", -0f, -0f);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", -0f, 0f);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 0f, -0f);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 0f, 0f);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
@@ -132,12 +133,19 @@
         masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset));
 
         // Get array length in bytes.
-        masm.imull(length, asRegister(lengthValue), arrayIndexScale);
+        masm.movl(length, asRegister(lengthValue));
+
+        if (arrayIndexScale > 1) {
+            masm.shll(length, NumUtil.log2Ceil(arrayIndexScale)); // scale length
+        }
+
         masm.movl(result, length); // copy
 
         if (supportsAVX2(crb.target)) {
             emitAVXCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
         } else if (supportsSSE41(crb.target)) {
+            // this code is used for AVX as well because our backend correctly ensures that
+            // VEX-prefixed instructions are emitted if AVX is supported
             emitSSE41Compare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ControlFlow.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,21 +22,21 @@
  */
 package org.graalvm.compiler.lir.amd64;
 
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
 
 import org.graalvm.compiler.asm.Label;
-import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
 import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.code.CompilationResult.JumpTable;
+import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.lir.LIRInstructionClass;
@@ -312,6 +312,42 @@
         }
     }
 
+    @Opcode("SETcc")
+    public static final class CondSetOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<CondSetOp> TYPE = LIRInstructionClass.create(CondSetOp.class);
+        @Def({REG, HINT}) protected Value result;
+        private final ConditionFlag condition;
+
+        public CondSetOp(Variable result, Condition condition) {
+            super(TYPE);
+            this.result = result;
+            this.condition = intCond(condition);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            setcc(masm, result, condition);
+        }
+    }
+
+    @Opcode("SETcc")
+    public static final class FloatCondSetOp extends AMD64LIRInstruction {
+        public static final LIRInstructionClass<FloatCondSetOp> TYPE = LIRInstructionClass.create(FloatCondSetOp.class);
+        @Def({REG, HINT}) protected Value result;
+        private final ConditionFlag condition;
+
+        public FloatCondSetOp(Variable result, Condition condition) {
+            super(TYPE);
+            this.result = result;
+            this.condition = floatCond(condition);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            setcc(masm, result, condition);
+        }
+    }
+
     @Opcode("CMOVE")
     public static final class CondMoveOp extends AMD64LIRInstruction {
         public static final LIRInstructionClass<CondMoveOp> TYPE = LIRInstructionClass.create(CondMoveOp.class);
@@ -418,6 +454,21 @@
         }
     }
 
+    private static void setcc(AMD64MacroAssembler masm, Value result, ConditionFlag cond) {
+        switch ((AMD64Kind) result.getPlatformKind()) {
+            case BYTE:
+            case WORD:
+            case DWORD:
+                masm.setl(cond, asRegister(result));
+                break;
+            case QWORD:
+                masm.setq(cond, asRegister(result));
+                break;
+            default:
+                throw GraalError.shouldNotReachHere();
+        }
+    }
+
     private static ConditionFlag intCond(Condition cond) {
         switch (cond) {
             case EQ:
@@ -464,6 +515,10 @@
         }
     }
 
+    public static boolean trueOnUnordered(Condition condition) {
+        return trueOnUnordered(floatCond(condition));
+    }
+
     private static boolean trueOnUnordered(ConditionFlag condition) {
         switch (condition) {
             case AboveEqual:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,8 +22,11 @@
  */
 package org.graalvm.compiler.lir.amd64;
 
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag.Equal;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
@@ -35,12 +38,16 @@
 import static jdk.vm.ci.code.ValueUtil.isRegister;
 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
 
+import org.graalvm.compiler.asm.Label;
+import org.graalvm.compiler.core.common.CompressEncoding;
+import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.core.common.spi.LIRKindTool;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.lir.LIRFrameState;
@@ -740,4 +747,110 @@
                 throw GraalError.shouldNotReachHere("Unknown result Kind: " + result.getPlatformKind());
         }
     }
+
+    public abstract static class Pointer extends AMD64LIRInstruction {
+        protected final LIRKindTool lirKindTool;
+        protected final CompressEncoding encoding;
+        protected final boolean nonNull;
+
+        @Def({REG, HINT}) private AllocatableValue result;
+        @Use({REG}) private AllocatableValue input;
+        @Alive({REG, ILLEGAL}) private AllocatableValue baseRegister;
+
+        protected Pointer(LIRInstructionClass<? extends Pointer> type, AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull,
+                        LIRKindTool lirKindTool) {
+            super(type);
+            this.result = result;
+            this.input = input;
+            this.baseRegister = baseRegister;
+            this.encoding = encoding;
+            this.nonNull = nonNull;
+            this.lirKindTool = lirKindTool;
+        }
+
+        protected boolean hasBase(CompilationResultBuilder crb) {
+            return GeneratePIC.getValue(crb.getOptions()) || encoding.hasBase();
+        }
+
+        protected final Register getResultRegister() {
+            return asRegister(result);
+        }
+
+        protected final Register getBaseRegister() {
+            return asRegister(baseRegister);
+        }
+
+        protected final int getShift() {
+            return encoding.getShift();
+        }
+
+        protected final void move(LIRKind kind, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            AMD64Move.move((AMD64Kind) kind.getPlatformKind(), crb, masm, result, input);
+        }
+    }
+
+    public static final class CompressPointer extends Pointer {
+        public static final LIRInstructionClass<CompressPointer> TYPE = LIRInstructionClass.create(CompressPointer.class);
+
+        public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+            super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(lirKindTool.getObjectKind(), crb, masm);
+
+            Register resReg = getResultRegister();
+            if (hasBase(crb)) {
+                Register baseReg = getBaseRegister();
+                if (!nonNull) {
+                    masm.testq(resReg, resReg);
+                    masm.cmovq(Equal, resReg, baseReg);
+                }
+                masm.subq(resReg, baseReg);
+            }
+
+            int shift = getShift();
+            if (shift != 0) {
+                masm.shrq(resReg, shift);
+            }
+        }
+    }
+
+    public static final class UncompressPointer extends Pointer {
+        public static final LIRInstructionClass<UncompressPointer> TYPE = LIRInstructionClass.create(UncompressPointer.class);
+
+        public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+            super(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+            move(lirKindTool.getNarrowOopKind(), crb, masm);
+
+            Register resReg = getResultRegister();
+            int shift = getShift();
+            if (shift != 0) {
+                masm.shlq(resReg, shift);
+            }
+
+            if (hasBase(crb)) {
+                Register baseReg = getBaseRegister();
+                if (nonNull) {
+                    masm.addq(resReg, baseReg);
+                    return;
+                }
+
+                if (shift == 0) {
+                    // if encoding.shift != 0, the flags are already set by the shlq
+                    masm.testq(resReg, resReg);
+                }
+
+                Label done = new Label();
+                masm.jccb(Equal, done);
+                masm.addq(resReg, baseReg);
+                masm.bind(done);
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCLoadConstantTableBaseOp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -55,8 +55,8 @@
  * this case absolute addressing (without using the base pointer is used). See also:
  * CodeInstaller::pd_patch_DataSectionReference
  *
- * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, int,
- *      Register, jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
+ * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, Register,
+ *      jdk.vm.ci.meta.Constant, Register, SPARCDelayedControlTransfer)
  */
 public class SPARCLoadConstantTableBaseOp extends SPARCLIRInstruction {
     public static final LIRInstructionClass<SPARCLoadConstantTableBaseOp> TYPE = LIRInstructionClass.create(SPARCLoadConstantTableBaseOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCMove.java	Thu Nov 16 12:15:55 2017 +0000
@@ -53,6 +53,7 @@
 import org.graalvm.compiler.asm.sparc.SPARCAssembler;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler;
 import org.graalvm.compiler.asm.sparc.SPARCMacroAssembler.ScratchRegister;
+import org.graalvm.compiler.code.DataSection.Data;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.type.DataPointerConstant;
 import org.graalvm.compiler.debug.GraalError;
@@ -116,11 +117,11 @@
         public static final LIRInstructionClass<LoadConstantFromTable> TYPE = LIRInstructionClass.create(LoadConstantFromTable.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(1, 8);
 
-        private Constant constant;
+        private JavaConstant constant;
         @Def({REG, STACK}) AllocatableValue result;
         @Use({REG}) private AllocatableValue constantTableBase;
 
-        public LoadConstantFromTable(Constant constant, AllocatableValue constantTableBase, AllocatableValue result) {
+        public LoadConstantFromTable(JavaConstant constant, AllocatableValue constantTableBase, AllocatableValue result) {
             super(TYPE, SIZE);
             this.constant = constant;
             this.result = result;
@@ -134,11 +135,11 @@
             Register baseRegister = asRegister(constantTableBase);
             if (isRegister(result)) {
                 Register resultRegister = asRegister(result);
-                loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, resultRegister, getDelayedControlTransfer());
+                loadFromConstantTable(crb, masm, baseRegister, constant, resultRegister, getDelayedControlTransfer());
             } else if (isStackSlot(result)) {
                 try (ScratchRegister scratch = masm.getScratchRegister()) {
                     Register scratchRegister = scratch.getRegister();
-                    loadFromConstantTable(crb, masm, byteCount, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
+                    loadFromConstantTable(crb, masm, baseRegister, constant, scratchRegister, getDelayedControlTransfer());
                     StackSlot slot = asStackSlot(result);
                     reg2stack(crb, masm, slot, scratchRegister.asValue(), getDelayedControlTransfer());
                 }
@@ -642,7 +643,6 @@
             boolean hasVIS1 = cpuFeatures.contains(CPUFeature.VIS1);
             boolean hasVIS3 = cpuFeatures.contains(CPUFeature.VIS3);
             Register resultRegister = asRegister(result);
-            int byteCount = result.getPlatformKind().getSizeInBytes();
             switch (input.getJavaKind().getStackKind()) {
                 case Int:
                     if (input.isDefaultForKind()) {
@@ -655,7 +655,7 @@
                         if (constantTableBase.equals(g0)) {
                             throw GraalError.shouldNotReachHere();
                         } else {
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -667,7 +667,7 @@
                         delaySlotLir.emitControlTransfer(crb, masm);
                         masm.or(g0, (int) input.asLong(), resultRegister);
                     } else {
-                        loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                        loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                     }
                     break;
                 case Float: {
@@ -683,7 +683,7 @@
                             masm.movwtos(scratch, resultRegister);
                         } else {
                             // First load the address into the scratch register
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -700,7 +700,7 @@
                             delaySlotLir.emitControlTransfer(crb, masm);
                             masm.movxtod(scratch, resultRegister);
                         } else {
-                            loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                            loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                         }
                     }
                     break;
@@ -710,7 +710,7 @@
                         delaySlotLir.emitControlTransfer(crb, masm);
                         masm.clr(resultRegister);
                     } else {
-                        loadFromConstantTable(crb, masm, byteCount, constantTableBase, input, resultRegister, delaySlotLir);
+                        loadFromConstantTable(crb, masm, constantTableBase, input, resultRegister, delaySlotLir);
                     }
                     break;
                 default:
@@ -768,25 +768,30 @@
      * patterns used for small constant sections (<8k) and large constant sections (>=8k). The
      * generated patterns by this method must be understood by
      * CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp).
+     *
+     * @return the number of bytes loaded from the constant table
      */
-    public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, int byteCount, Register constantTableBase, Constant input, Register dest,
+    public static int loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register constantTableBase, Constant input, Register dest,
                     SPARCDelayedControlTransfer delaySlotInstruction) {
         SPARCAddress address;
         ScratchRegister scratch = null;
         try {
+            Data data = crb.createDataItem(input);
+            int size = data.getSize();
             if (masm.isImmediateConstantLoad()) {
                 address = new SPARCAddress(constantTableBase, 0);
                 // Make delayed only, when using immediate constant load.
                 delaySlotInstruction.emitControlTransfer(crb, masm);
-                crb.recordDataReferenceInCode(input, byteCount);
+                crb.recordDataReferenceInCode(data, size);
             } else {
                 scratch = masm.getScratchRegister();
                 Register sr = scratch.getRegister();
-                crb.recordDataReferenceInCode(input, byteCount);
+                crb.recordDataReferenceInCode(data, size);
                 masm.sethix(0, sr, true);
                 address = new SPARCAddress(sr, 0);
             }
-            masm.ld(address, dest, byteCount, false);
+            masm.ld(address, dest, size, false);
+            return size;
         } finally {
             if (scratch != null) {
                 scratch.close();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIRValueUtil.java	Thu Nov 16 12:15:55 2017 +0000
@@ -69,6 +69,16 @@
         return asConstantValue(value).getJavaConstant();
     }
 
+    public static boolean isIntConstant(Value value, long expected) {
+        if (isJavaConstant(value)) {
+            JavaConstant javaConstant = asJavaConstant(value);
+            if (javaConstant != null && javaConstant.getJavaKind().isNumericInteger()) {
+                return javaConstant.asLong() == expected;
+            }
+        }
+        return false;
+    }
+
     public static boolean isStackSlotValue(Value value) {
         assert value != null;
         return value instanceof StackSlot || value instanceof VirtualStackSlot;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/RedundantMoveElimination.java	Thu Nov 16 12:15:55 2017 +0000
@@ -30,6 +30,7 @@
 import java.util.Collections;
 import java.util.EnumSet;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.CounterKey;
@@ -138,8 +139,8 @@
         private void doOptimize(LIR lir) {
             DebugContext debug = lir.getDebug();
             try (Indent indent = debug.logAndIndent("eliminate redundant moves")) {
-
-                callerSaveRegs = frameMap.getRegisterConfig().getCallerSaveRegisters();
+                RegisterConfig registerConfig = frameMap.getRegisterConfig();
+                callerSaveRegs = registerConfig.getCallerSaveRegisters();
 
                 initBlockData(lir);
 
@@ -147,7 +148,7 @@
                 // Unallocatable registers should never be optimized.
                 eligibleRegs = new int[numRegs];
                 Arrays.fill(eligibleRegs, -1);
-                for (Register reg : frameMap.getRegisterConfig().getAllocatableRegisters()) {
+                for (Register reg : registerConfig.getAllocatableRegisters()) {
                     if (reg.number < numRegs) {
                         eligibleRegs[reg.number] = reg.number;
                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/SaveCalleeSaveRegisters.java	Thu Nov 16 12:15:55 2017 +0000
@@ -31,7 +31,6 @@
 import org.graalvm.compiler.lir.LIRInstruction;
 import org.graalvm.compiler.lir.StandardOp;
 import org.graalvm.compiler.lir.Variable;
-import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
@@ -48,8 +47,7 @@
 
     @Override
     protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PreAllocationOptimizationContext context) {
-        FrameMapBuilder frameMapBuilder = lirGenRes.getFrameMapBuilder();
-        RegisterArray calleeSaveRegisters = frameMapBuilder.getCodeCache().getRegisterConfig().getCalleeSaveRegisters();
+        RegisterArray calleeSaveRegisters = lirGenRes.getRegisterConfig().getCalleeSaveRegisters();
         if (calleeSaveRegisters == null || calleeSaveRegisters.size() == 0) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java	Thu Nov 16 12:15:55 2017 +0000
@@ -80,10 +80,10 @@
  */
 public class CompilationResultBuilder {
 
-    // @formatter:off
-    @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
-    // @formatter:on
+    public static class Options {
+        @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug) //
+        public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
+    }
 
     private static class ExceptionInfo {
 
@@ -295,13 +295,24 @@
     public AbstractAddress recordDataReferenceInCode(Constant constant, int alignment) {
         assert constant != null;
         debug.log("Constant reference in code: pos = %d, data = %s", asm.position(), constant);
+        Data data = createDataItem(constant);
+        data.updateAlignment(alignment);
+        return recordDataSectionReference(data);
+    }
+
+    public AbstractAddress recordDataReferenceInCode(Data data, int alignment) {
+        assert data != null;
+        data.updateAlignment(alignment);
+        return recordDataSectionReference(data);
+    }
+
+    public Data createDataItem(Constant constant) {
         Data data = dataCache.get(constant);
         if (data == null) {
             data = dataBuilder.createDataItem(constant);
             dataCache.put(constant, data);
         }
-        data.updateAlignment(alignment);
-        return recordDataSectionReference(data);
+        return data;
     }
 
     public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
@@ -472,7 +483,7 @@
         if (block == null) {
             return;
         }
-        boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || PrintLIRWithAssembly.getValue(getOptions());
+        boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || Options.PrintLIRWithAssembly.getValue(getOptions());
         if (emitComment) {
             blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGenerator.java	Thu Nov 16 12:15:55 2017 +0000
@@ -50,8 +50,19 @@
 
     protected abstract Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags);
 
+    protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
+
     @Override
     public final Variable emitAdd(Value aVal, Value bVal, boolean setFlags) {
+        return emitAddOrSub(aVal, bVal, setFlags, true);
+    }
+
+    @Override
+    public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
+        return emitAddOrSub(aVal, bVal, setFlags, false);
+    }
+
+    private Variable emitAddOrSub(Value aVal, Value bVal, boolean setFlags, boolean isAdd) {
         LIRKind resultKind;
         Value a = aVal;
         Value b = bVal;
@@ -90,47 +101,7 @@
             resultKind = LIRKind.combine(a, b);
         }
 
-        return emitAdd(resultKind, a, b, setFlags);
+        return isAdd ? emitAdd(resultKind, a, b, setFlags) : emitSub(resultKind, a, b, setFlags);
     }
 
-    protected abstract Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags);
-
-    @Override
-    public final Variable emitSub(Value aVal, Value bVal, boolean setFlags) {
-        LIRKind resultKind;
-        Value a = aVal;
-        Value b = bVal;
-
-        if (isNumericInteger(a.getPlatformKind())) {
-            LIRKind aKind = a.getValueKind(LIRKind.class);
-            LIRKind bKind = b.getValueKind(LIRKind.class);
-            assert a.getPlatformKind() == b.getPlatformKind();
-
-            if (aKind.isUnknownReference()) {
-                resultKind = aKind;
-            } else if (bKind.isUnknownReference()) {
-                resultKind = bKind;
-            }
-
-            if (aKind.isValue() && bKind.isValue()) {
-                resultKind = aKind;
-            } else if (bKind.isValue()) {
-                if (aKind.isDerivedReference()) {
-                    resultKind = aKind;
-                } else {
-                    AllocatableValue allocatable = getLIRGen().asAllocatable(a);
-                    resultKind = aKind.makeDerivedReference(allocatable);
-                    a = allocatable;
-                }
-            } else if (aKind.isDerivedReference() && bKind.isDerivedReference() && aKind.getDerivedReferenceBase().equals(bKind.getDerivedReferenceBase())) {
-                resultKind = LIRKind.value(a.getPlatformKind());
-            } else {
-                resultKind = aKind.makeUnknownReference();
-            }
-        } else {
-            resultKind = LIRKind.combine(a, b);
-        }
-
-        return emitSub(resultKind, a, b, setFlags);
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerationResult.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.lir.gen;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
 import org.graalvm.compiler.debug.DebugContext;
@@ -123,6 +124,10 @@
         return frameMap;
     }
 
+    public final RegisterConfig getRegisterConfig() {
+        return frameMapBuilder.getRegisterConfig();
+    }
+
     public LIR getLIR() {
         return lir;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,6 +34,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
@@ -201,8 +202,13 @@
     }
 
     @Override
+    public RegisterConfig getRegisterConfig() {
+        return res.getRegisterConfig();
+    }
+
+    @Override
     public RegisterAttributes attributes(Register register) {
-        return res.getFrameMapBuilder().getRegisterConfig().getAttributesMap()[register.number];
+        return getRegisterConfig().getAttributesMap()[register.number];
     }
 
     @Override
@@ -228,7 +234,7 @@
         if (moveFactory.canInlineConstant(constant)) {
             return new ConstantValue(toRegisterKind(kind), constant);
         } else {
-            return emitLoadConstant(kind, constant);
+            return emitLoadConstant(toRegisterKind(kind), constant);
         }
     }
 
@@ -289,7 +295,7 @@
      */
     @Override
     public AllocatableValue resultOperandFor(JavaKind javaKind, ValueKind<?> valueKind) {
-        Register reg = res.getFrameMapBuilder().getRegisterConfig().getReturnRegister(javaKind);
+        Register reg = getRegisterConfig().getReturnRegister(javaKind);
         assert target().arch.canStoreValue(reg.getRegisterCategory(), valueKind.getPlatformKind()) : reg.getRegisterCategory() + " " + valueKind.getPlatformKind();
         return reg.asValue(valueKind);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.lir.gen;
 
+import jdk.vm.ci.code.RegisterConfig;
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
@@ -109,6 +110,8 @@
 
     LIRGenerationResult getResult();
 
+    RegisterConfig getRegisterConfig();
+
     boolean hasBlockEnd(AbstractBlockBase<?> block);
 
     MoveFactory getMoveFactory();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -214,7 +214,7 @@
             }
         };
         ResolvedJavaMethod method = getResolvedJavaMethod(name);
-        OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.UnrollMaxIterations, 2);
+        OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.Options.UnrollMaxIterations, 2);
         StructuredGraph graph = parse(builder(method, StructuredGraph.AllowAssumptions.YES, id, options), getEagerGraphBuilderSuite());
         try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
             MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/CountedLoopInfo.java	Thu Nov 16 12:15:55 2017 +0000
@@ -83,7 +83,11 @@
             range = add(graph, range, oneDirection);
         }
         // round-away-from-zero divison: (range + stride -/+ 1) / stride
-        ValueNode denominator = add(graph, sub(graph, range, oneDirection), iv.strideNode());
+        ValueNode denominator = range;
+        if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
+            ValueNode subedRanged = sub(graph, range, oneDirection);
+            denominator = add(graph, subedRanged, iv.strideNode());
+        }
         ValueNode div = divBefore(graph, loop.entryPoint(), denominator, iv.strideNode());
 
         if (assumePositive) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/DefaultLoopPolicies.java	Thu Nov 16 12:15:55 2017 +0000
@@ -55,16 +55,19 @@
 import jdk.vm.ci.meta.MetaAccessProvider;
 
 public class DefaultLoopPolicies implements LoopPolicies {
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
+
+    public static class Options {
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchMaxIncrease = new OptionKey<>(500);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> LoopUnswitchTrivial = new OptionKey<>(10);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Double> LoopUnswitchFrequencyBoost = new OptionKey<>(10.0);
 
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(300);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxIterations = new OptionKey<>(600);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactFullUnrollMaxNodes = new OptionKey<>(1200);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> ExactPartialUnrollMaxNodes = new OptionKey<>(200);
 
-    @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+        @Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> UnrollMaxIterations = new OptionKey<>(16);
+    }
 
     @Override
     public boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg, MetaAccessProvider metaAccess) {
@@ -87,10 +90,10 @@
         OptionValues options = loop.entryPoint().getOptions();
         CountedLoopInfo counted = loop.counted();
         long maxTrips = counted.constantMaxTripCount();
-        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue(options) : FullUnrollMaxNodes.getValue(options);
+        int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? Options.ExactFullUnrollMaxNodes.getValue(options) : Options.FullUnrollMaxNodes.getValue(options);
         maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
-        if (maxTrips <= FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
+        if (maxTrips <= Options.FullUnrollMaxIterations.getValue(options) && size * (maxTrips - 1) <= maxNodes) {
             // check whether we're allowed to unroll this loop
             return loop.canDuplicateLoop();
         } else {
@@ -106,7 +109,7 @@
             return false;
         }
         OptionValues options = loop.entryPoint().getOptions();
-        int maxNodes = ExactPartialUnrollMaxNodes.getValue(options);
+        int maxNodes = Options.ExactPartialUnrollMaxNodes.getValue(options);
         maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
         int unrollFactor = loopBegin.getUnrollFactor();
@@ -118,7 +121,7 @@
             }
             loopBegin.setLoopOrigFrequency(loopFrequency);
         }
-        int maxUnroll = UnrollMaxIterations.getValue(options);
+        int maxUnroll = Options.UnrollMaxIterations.getValue(options);
         // Now correct size for the next unroll. UnrollMaxIterations == 1 means perform the
         // pre/main/post transformation but don't actually unroll the main loop.
         size += size;
@@ -190,9 +193,9 @@
         CountingClosure stateNodesCount = new CountingClosure();
         double loopFrequency = loop.loopBegin().loopFrequency();
         OptionValues options = loop.loopBegin().getOptions();
-        int maxDiff = LoopUnswitchTrivial.getValue(options) + (int) (LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
+        int maxDiff = Options.LoopUnswitchTrivial.getValue(options) + (int) (Options.LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
 
-        maxDiff = Math.min(maxDiff, LoopUnswitchMaxIncrease.getValue(options));
+        maxDiff = Math.min(maxDiff, Options.LoopUnswitchMaxIncrease.getValue(options));
         int remainingGraphSpace = MaximumDesiredSize.getValue(options) - graph.getNodeCount();
         maxDiff = Math.min(maxDiff, remainingGraphSpace);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java	Thu Nov 16 12:15:55 2017 +0000
@@ -68,6 +68,10 @@
         this.value = value;
     }
 
+    public boolean isValueKnown() {
+        return this != NodeCycles.CYCLES_UNKNOWN && this != NodeCycles.CYCLES_UNSET;
+    }
+
     public static final int IGNORE_CYCLES_CONTRACT_FACTOR = 0xFFFF;
 
     public static NodeCycles compute(NodeCycles base, int opCount) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -552,4 +552,21 @@
             return result.longValue();
         }
     }
+
+    @Test
+    public void testDiv() {
+        testDiv(32, Integer.MIN_VALUE, Integer.MAX_VALUE);
+        testDiv(64, Long.MIN_VALUE, Long.MAX_VALUE);
+    }
+
+    private static void testDiv(int bits, long min, long max) {
+        BinaryOp<?> div = IntegerStamp.OPS.getDiv();
+        assertEquals(IntegerStamp.create(bits, -50, 50), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, 20, 500), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, -500, -20), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 2, 5)));
+        assertEquals(IntegerStamp.create(bits, min, max), div.foldStamp(IntegerStamp.create(bits, min, max), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, -100, 100), div.foldStamp(IntegerStamp.create(bits, -100, 100), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, 0, 1000), div.foldStamp(IntegerStamp.create(bits, 100, 1000), IntegerStamp.create(bits, 1, max)));
+        assertEquals(IntegerStamp.create(bits, -1000, 0), div.foldStamp(IntegerStamp.create(bits, -1000, -100), IntegerStamp.create(bits, 1, max)));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/PrimitiveStampBoundaryTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.nodes.test;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+
+import org.graalvm.compiler.core.common.calc.FloatConvert;
+import org.graalvm.compiler.core.common.calc.FloatConvertCategory;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.PrimitiveStamp;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.test.GraalTest;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Exercise the various stamp folding operations by generating ranges from a set of boundary values
+ * and then ensuring that the values that produced those ranges are in the resulting stamp.
+ */
+public class PrimitiveStampBoundaryTest extends GraalTest {
+
+    static long[] longBoundaryValues = {Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1,
+                    Long.MAX_VALUE};
+
+    static int[] shiftBoundaryValues = {-128, -1, 0, 1, 4, 8, 16, 31, 63, 128};
+
+    static HashSet<IntegerStamp> shiftStamps;
+    static HashSet<PrimitiveStamp> integerTestStamps;
+    static HashSet<PrimitiveStamp> floatTestStamps;
+
+    static {
+        shiftStamps = new HashSet<>();
+        for (long v1 : shiftBoundaryValues) {
+            for (long v2 : shiftBoundaryValues) {
+                shiftStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+            }
+        }
+
+        integerTestStamps = new HashSet<>();
+        for (long v1 : longBoundaryValues) {
+            for (long v2 : longBoundaryValues) {
+                if (v2 == (int) v2 && v1 == (int) v1) {
+                    integerTestStamps.add(IntegerStamp.create(32, Math.min(v1, v2), Math.max(v1, v2)));
+                }
+                integerTestStamps.add(IntegerStamp.create(64, Math.min(v1, v2), Math.max(v1, v2)));
+            }
+        }
+    }
+
+    static double[] doubleBoundaryValues = {Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.MIN_VALUE,
+                    Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1,
+                    Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE,
+                    Float.MAX_VALUE, Float.POSITIVE_INFINITY, Double.MAX_VALUE, Double.POSITIVE_INFINITY};
+
+    static double[] doubleSpecialValues = {Double.NaN, -0.0, -0.0F, Float.NaN};
+
+    static {
+        floatTestStamps = new HashSet<>();
+
+        for (double d1 : doubleBoundaryValues) {
+            for (double d2 : doubleBoundaryValues) {
+                float f1 = (float) d2;
+                float f2 = (float) d1;
+                if (d2 == f1 && d1 == f2) {
+                    generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), true));
+                    generateFloatingStamps(new FloatStamp(32, Math.min(f2, f1), Math.max(f2, f1), false));
+                }
+                generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), true));
+                generateFloatingStamps(new FloatStamp(64, Math.min(d1, d2), Math.max(d1, d2), false));
+            }
+        }
+    }
+
+    private static void generateFloatingStamps(FloatStamp floatStamp) {
+        floatTestStamps.add(floatStamp);
+        for (double d : doubleSpecialValues) {
+            FloatStamp newStamp = (FloatStamp) floatStamp.meet(floatStampForConstant(d, floatStamp.getBits()));
+            if (!newStamp.isUnrestricted()) {
+                floatTestStamps.add(newStamp);
+            }
+        }
+    }
+
+    @Test
+    public void testConvertBoundaryValues() {
+        testConvertBoundaryValues(IntegerStamp.OPS.getSignExtend(), 32, 64, integerTestStamps);
+        testConvertBoundaryValues(IntegerStamp.OPS.getZeroExtend(), 32, 64, integerTestStamps);
+        testConvertBoundaryValues(IntegerStamp.OPS.getNarrow(), 64, 32, integerTestStamps);
+    }
+
+    private static void testConvertBoundaryValues(IntegerConvertOp<?> op, int inputBits, int resultBits, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp stamp : stamps) {
+            if (inputBits == stamp.getBits()) {
+                Stamp lower = boundaryStamp(stamp, false);
+                Stamp upper = boundaryStamp(stamp, true);
+                checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), lower);
+                checkConvertOperation(op, inputBits, resultBits, op.foldStamp(inputBits, resultBits, stamp), upper);
+            }
+        }
+    }
+
+    private static void checkConvertOperation(IntegerConvertOp<?> op, int inputBits, int resultBits, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(inputBits, resultBits, v1stamp);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+
+    @Test
+    public void testFloatConvertBoundaryValues() {
+        for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+            ArithmeticOpTable.FloatConvertOp floatConvert = IntegerStamp.OPS.getFloatConvert(op);
+            if (floatConvert == null) {
+                continue;
+            }
+            assert op.getCategory() == FloatConvertCategory.IntegerToFloatingPoint : op;
+            testConvertBoundaryValues(floatConvert, op.getInputBits(), integerTestStamps);
+        }
+        for (FloatConvert op : EnumSet.allOf(FloatConvert.class)) {
+            ArithmeticOpTable.FloatConvertOp floatConvert = FloatStamp.OPS.getFloatConvert(op);
+            if (floatConvert == null) {
+                continue;
+            }
+            assert op.getCategory() == FloatConvertCategory.FloatingPointToInteger || op.getCategory() == FloatConvertCategory.FloatingPointToFloatingPoint : op;
+            testConvertBoundaryValues(floatConvert, op.getInputBits(), floatTestStamps);
+        }
+    }
+
+    private static void testConvertBoundaryValues(ArithmeticOpTable.FloatConvertOp op, int bits, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp stamp : stamps) {
+            if (bits == stamp.getBits()) {
+                Stamp lower = boundaryStamp(stamp, false);
+                Stamp upper = boundaryStamp(stamp, true);
+                checkConvertOperation(op, op.foldStamp(stamp), lower);
+                checkConvertOperation(op, op.foldStamp(stamp), upper);
+            }
+        }
+    }
+
+    private static void checkConvertOperation(ArithmeticOpTable.FloatConvertOp op, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(v1stamp);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+
+    @Test
+    public void testShiftBoundaryValues() {
+        for (ShiftOp<?> op : IntegerStamp.OPS.getShiftOps()) {
+            testShiftBoundaryValues(op, integerTestStamps, shiftStamps);
+        }
+    }
+
+    private static void testShiftBoundaryValues(ShiftOp<?> shiftOp, HashSet<PrimitiveStamp> stamps, HashSet<IntegerStamp> shifts) {
+        for (PrimitiveStamp testStamp : stamps) {
+            if (testStamp instanceof IntegerStamp) {
+                IntegerStamp stamp = (IntegerStamp) testStamp;
+                for (IntegerStamp shiftStamp : shifts) {
+                    IntegerStamp foldedStamp = (IntegerStamp) shiftOp.foldStamp(stamp, shiftStamp);
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.lowerBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.lowerBound(), shiftStamp.upperBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.lowerBound());
+                    checkShiftOperation(stamp.getBits(), shiftOp, foldedStamp, stamp.upperBound(), shiftStamp.upperBound());
+                }
+            }
+        }
+    }
+
+    private static void checkShiftOperation(int bits, ShiftOp<?> op, IntegerStamp result, long v1, long v2) {
+        IntegerStamp v1stamp = IntegerStamp.create(bits, v1, v1);
+        IntegerStamp v2stamp = IntegerStamp.create(32, v2, v2);
+        IntegerStamp folded = (IntegerStamp) op.foldStamp(v1stamp, v2stamp);
+        Constant constant = op.foldConstant(JavaConstant.forPrimitiveInt(bits, v1), (int) v2);
+        assertTrue(constant != null);
+        assertTrue(folded.asConstant() != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+    }
+
+    private static void checkBinaryOperation(ArithmeticOpTable.BinaryOp<?> op, Stamp result, Stamp v1stamp, Stamp v2stamp) {
+        Stamp folded = op.foldStamp(v1stamp, v2stamp);
+        Constant constant = op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+        if (constant != null) {
+            Constant constant2 = folded.asConstant();
+            if (constant2 == null && v1stamp instanceof FloatStamp) {
+                JavaConstant c = (JavaConstant) constant;
+                assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+                                (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+            } else {
+                assertTrue(constant2 != null, "should constant fold %s %s %s %s", op, v1stamp, v2stamp, folded);
+                if (!constant.equals(constant2)) {
+                    op.foldConstant(v1stamp.asConstant(), v2stamp.asConstant());
+                    op.foldStamp(v1stamp, v2stamp);
+                }
+                assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s %s", op, v1stamp, v2stamp, constant, constant2);
+            }
+            assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s %s", op, v1stamp, v2stamp, folded, result, result.meet(folded));
+        }
+    }
+
+    @Test
+    public void testBinaryBoundaryValues() {
+        for (BinaryOp<?> op : IntegerStamp.OPS.getBinaryOps()) {
+            if (op != null) {
+                testBinaryBoundaryValues(op, integerTestStamps);
+            }
+        }
+        for (BinaryOp<?> op : FloatStamp.OPS.getBinaryOps()) {
+            if (op != null) {
+                testBinaryBoundaryValues(op, floatTestStamps);
+            }
+        }
+    }
+
+    private static Stamp boundaryStamp(Stamp v1, boolean upper) {
+        if (v1 instanceof IntegerStamp) {
+            IntegerStamp istamp = (IntegerStamp) v1;
+            long bound = upper ? istamp.upperBound() : istamp.lowerBound();
+            return IntegerStamp.create(istamp.getBits(), bound, bound);
+        } else if (v1 instanceof FloatStamp) {
+            FloatStamp floatStamp = (FloatStamp) v1;
+            double bound = upper ? floatStamp.upperBound() : floatStamp.lowerBound();
+            int bits = floatStamp.getBits();
+            return floatStampForConstant(bound, bits);
+        } else {
+            throw new InternalError("unexpected stamp type " + v1);
+        }
+    }
+
+    private static FloatStamp floatStampForConstant(double bound, int bits) {
+        if (bits == 32) {
+            float fbound = (float) bound;
+            return new FloatStamp(bits, fbound, fbound, !Float.isNaN(fbound));
+        } else {
+            return new FloatStamp(bits, bound, bound, !Double.isNaN(bound));
+        }
+    }
+
+    private static void testBinaryBoundaryValues(ArithmeticOpTable.BinaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp v1 : stamps) {
+            for (PrimitiveStamp v2 : stamps) {
+                if (v1.getBits() == v2.getBits() && v1.getClass() == v2.getClass()) {
+                    Stamp result = op.foldStamp(v1, v2);
+                    Stamp v1lower = boundaryStamp(v1, false);
+                    Stamp v1upper = boundaryStamp(v1, true);
+                    Stamp v2lower = boundaryStamp(v2, false);
+                    Stamp v2upper = boundaryStamp(v2, true);
+                    checkBinaryOperation(op, result, v1lower, v2lower);
+                    checkBinaryOperation(op, result, v1lower, v2upper);
+                    checkBinaryOperation(op, result, v1upper, v2lower);
+                    checkBinaryOperation(op, result, v1upper, v2upper);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testUnaryBoundaryValues() {
+        for (ArithmeticOpTable.UnaryOp<?> op : IntegerStamp.OPS.getUnaryOps()) {
+            if (op != null) {
+                testUnaryBoundaryValues(op, integerTestStamps);
+            }
+        }
+        for (ArithmeticOpTable.UnaryOp<?> op : FloatStamp.OPS.getUnaryOps()) {
+            if (op != null) {
+                testUnaryBoundaryValues(op, floatTestStamps);
+            }
+        }
+    }
+
+    private static void testUnaryBoundaryValues(ArithmeticOpTable.UnaryOp<?> op, HashSet<PrimitiveStamp> stamps) {
+        for (PrimitiveStamp v1 : stamps) {
+            Stamp result = op.foldStamp(v1);
+            checkUnaryOperation(op, result, boundaryStamp(v1, false));
+            checkUnaryOperation(op, result, boundaryStamp(v1, true));
+        }
+    }
+
+    private static void checkUnaryOperation(ArithmeticOpTable.UnaryOp<?> op, Stamp result, Stamp v1stamp) {
+        Stamp folded = op.foldStamp(v1stamp);
+        Constant v1constant = v1stamp.asConstant();
+        if (v1constant != null) {
+            Constant constant = op.foldConstant(v1constant);
+            if (constant != null) {
+                Constant constant2 = folded.asConstant();
+                if (constant2 == null && v1stamp instanceof FloatStamp) {
+                    JavaConstant c = (JavaConstant) constant;
+                    assertTrue((c.getJavaKind() == JavaKind.Double && Double.isNaN(c.asDouble())) ||
+                                    (c.getJavaKind() == JavaKind.Float && Float.isNaN(c.asFloat())));
+                } else {
+                    assertTrue(constant2 != null, "should constant fold %s %s %s", op, v1stamp, folded);
+                    assertTrue(constant.equals(constant2), "should produce same constant %s %s %s %s", op, v1stamp, constant, constant2);
+                }
+            }
+        } else {
+            assert v1stamp instanceof FloatStamp;
+        }
+        assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/CompressionNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -122,9 +122,9 @@
                 // We always want uncompressed constants
                 return this;
             }
-            int stableDimension = ((ConstantNode) forValue).getStableDimension();
-            boolean isDefaultStable = ((ConstantNode) forValue).isDefaultStable();
-            return ConstantNode.forConstant(stamp(), convert(forValue.asConstant(), tool.getConstantReflection()), stableDimension, isDefaultStable, tool.getMetaAccess());
+
+            ConstantNode constant = (ConstantNode) forValue;
+            return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
         } else if (forValue instanceof CompressionNode) {
             CompressionNode other = (CompressionNode) forValue;
             if (op != other.op && encoding.equals(other.encoding)) {
@@ -136,22 +136,22 @@
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        LIRGeneratorTool hsGen = gen.getLIRGeneratorTool();
         boolean nonNull;
-        if (getValue().stamp() instanceof AbstractObjectStamp) {
-            nonNull = StampTool.isPointerNonNull(getValue().stamp());
+        if (value.stamp() instanceof AbstractObjectStamp) {
+            nonNull = StampTool.isPointerNonNull(value.stamp());
         } else {
             // metaspace pointers are never null
             nonNull = true;
         }
 
+        LIRGeneratorTool tool = gen.getLIRGeneratorTool();
         Value result;
         switch (op) {
             case Compress:
-                result = hsGen.emitCompress(gen.operand(getValue()), encoding, nonNull);
+                result = tool.emitCompress(gen.operand(value), encoding, nonNull);
                 break;
             case Uncompress:
-                result = hsGen.emitUncompress(gen.operand(getValue()), encoding, nonNull);
+                result = tool.emitUncompress(gen.operand(value), encoding, nonNull);
                 break;
             default:
                 throw GraalError.shouldNotReachHere();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -54,7 +54,7 @@
 /**
  * The {@code ConstantNode} represents a {@link Constant constant}.
  */
-@NodeInfo(nameTemplate = "C({p#rawvalue})", cycles = CYCLES_0, size = SIZE_1)
+@NodeInfo(nameTemplate = "C({p#rawvalue}) {p#stampKind}", cycles = CYCLES_0, size = SIZE_1)
 public final class ConstantNode extends FloatingNode implements LIRLowerable {
 
     public static final NodeClass<ConstantNode> TYPE = NodeClass.create(ConstantNode.class);
@@ -518,13 +518,14 @@
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> properties = super.getDebugProperties(map);
         properties.put("rawvalue", value.toValueString());
+        properties.put("stampKind", stamp.unrestricted().toString());
         return properties;
     }
 
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ")";
+            return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 
 import java.util.ArrayList;
@@ -74,7 +74,7 @@
  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
  * of a comparison.
  */
-@NodeInfo(cycles = CYCLES_2, size = SIZE_2, sizeRationale = "2 jmps")
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2, sizeRationale = "2 jmps")
 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable {
     public static final NodeClass<IfNode> TYPE = NodeClass.create(IfNode.class);
 
@@ -375,7 +375,7 @@
         }
 
         // Falsify the reference check.
-        setCondition(graph().addOrUnique(LogicConstantNode.contradiction()));
+        setCondition(graph().addOrUniqueWithInputs(LogicConstantNode.contradiction()));
 
         return true;
     }
@@ -726,10 +726,11 @@
 
     protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
         AbstractBeginNode trueBegin = trueSuccessor();
+        LogicNode conditionNode = condition();
         graph().removeSplitPropagate(this, trueBegin);
         tool.addToWorkList(trueBegin);
-        if (condition() != null) {
-            GraphUtil.tryKillUnused(condition());
+        if (conditionNode != null) {
+            GraphUtil.tryKillUnused(conditionNode);
         }
         if (merge.isAlive() && merge.forwardEndCount() > 1) {
             for (FixedNode end : merge.forwardEnds()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -132,12 +132,24 @@
                 }
                 str.append(valueAt(i) == null ? "-" : valueAt(i).toString(Verbosity.Id));
             }
+            String description = valueDescription();
+            if (description.length() > 0) {
+                str.append(", ").append(description);
+            }
             return super.toString(Verbosity.Name) + "(" + str + ")";
         } else {
             return super.toString(verbosity);
         }
     }
 
+    /**
+     * String describing the kind of value this Phi merges. Used by {@link #toString(Verbosity)} and
+     * dumping.
+     */
+    protected String valueDescription() {
+        return "";
+    }
+
     public void addInput(ValueNode x) {
         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
         assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -59,14 +59,14 @@
  *
  * In contrast to a {@link GuardedValueNode}, a {@link PiNode} is useless as soon as the type of its
  * input is as narrow or narrower than the {@link PiNode}'s type. The {@link PiNode}, and therefore
- * also the scheduling restriction enforced by the anchor, will go away.
+ * also the scheduling restriction enforced by the guard, will go away.
  */
 @NodeInfo(cycles = CYCLES_0, size = SIZE_0)
 public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy {
 
     public static final NodeClass<PiNode> TYPE = NodeClass.create(PiNode.class);
     @Input ValueNode object;
-    protected final Stamp piStamp;
+    protected Stamp piStamp;
 
     public ValueNode object() {
         return object;
@@ -84,12 +84,12 @@
         this(object, stamp, null);
     }
 
-    public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        this(TYPE, object, stamp, (GuardingNode) anchor);
+    public PiNode(ValueNode object, Stamp stamp, ValueNode guard) {
+        this(TYPE, object, stamp, (GuardingNode) guard);
     }
 
-    public PiNode(ValueNode object, ValueNode anchor) {
-        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), anchor);
+    public PiNode(ValueNode object, ValueNode guard) {
+        this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
     }
 
     public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
@@ -104,29 +104,29 @@
         return new PiNode(object, stamp);
     }
 
-    public static ValueNode create(ValueNode object, Stamp stamp, ValueNode anchor) {
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+    public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) {
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
         }
-        return new PiNode(object, stamp, anchor);
+        return new PiNode(object, stamp, guard);
     }
 
-    public static ValueNode create(ValueNode object, ValueNode anchor) {
+    public static ValueNode create(ValueNode object, ValueNode guard) {
         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value != null) {
             return value;
         }
-        return new PiNode(object, stamp, anchor);
+        return new PiNode(object, stamp, guard);
     }
 
     @SuppressWarnings("unused")
-    public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode anchor) {
+    public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
-        ValueNode value = canonical(object, stamp, (GuardingNode) anchor);
+        ValueNode value = canonical(object, stamp, (GuardingNode) guard);
         if (value == null) {
-            value = new PiNode(object, stamp, anchor);
+            value = new PiNode(object, stamp, guard);
         }
         b.push(JavaKind.Object, b.append(value));
         return true;
@@ -147,6 +147,11 @@
         return piStamp;
     }
 
+    public void strengthenPiStamp(Stamp newPiStamp) {
+        assert this.piStamp.join(newPiStamp).equals(newPiStamp) : "stamp can only improve";
+        this.piStamp = newPiStamp;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool generator) {
         if (generator.hasOperand(object)) {
@@ -256,17 +261,17 @@
 
     /**
      * Changes the stamp of an object and ensures the newly stamped value is non-null and does not
-     * float above a given anchor.
+     * float above a given guard.
      */
     @NodeIntrinsic
-    public static native Object piCastNonNull(Object object, GuardingNode anchor);
+    public static native Object piCastNonNull(Object object, GuardingNode guard);
 
     /**
      * Changes the stamp of an object and ensures the newly stamped value is non-null and does not
-     * float above a given anchor.
+     * float above a given guard.
      */
     @NodeIntrinsic
-    public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode anchor);
+    public static native Class<?> piCastNonNullClass(Class<?> type, GuardingNode guard);
 
     /**
      * Changes the stamp of an object to represent a given type and to indicate that the object is
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ValuePhiNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,8 @@
  */
 package org.graalvm.compiler.nodes;
 
+import java.util.Map;
+
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
@@ -35,7 +37,7 @@
 /**
  * Value {@link PhiNode}s merge data flow values at control flow merges.
  */
-@NodeInfo(nameTemplate = "Phi({i#values})")
+@NodeInfo(nameTemplate = "Phi({i#values}, {p#valueDescription})")
 public class ValuePhiNode extends PhiNode implements ArrayLengthProvider {
 
     public static final NodeClass<ValuePhiNode> TYPE = NodeClass.create(ValuePhiNode.class);
@@ -113,4 +115,16 @@
         }
         return super.verify();
     }
+
+    @Override
+    protected String valueDescription() {
+        return stamp().unrestricted().toString();
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
+        Map<Object, Object> properties = super.getDebugProperties(map);
+        properties.put("valueDescription", valueDescription());
+        return properties;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -91,7 +91,9 @@
     public static <OP> ConstantNode tryConstantFold(BinaryOp<OP> op, ValueNode forX, ValueNode forY, Stamp stamp) {
         if (forX.isConstant() && forY.isConstant()) {
             Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
-            return ConstantNode.forPrimitive(stamp, ret);
+            if (ret != null) {
+                return ConstantNode.forPrimitive(stamp, ret);
+            }
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ConditionalNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,7 +22,7 @@
  */
 package org.graalvm.compiler.nodes.calc;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 import static org.graalvm.compiler.nodes.calc.CompareNode.createCompareNode;
 
@@ -47,10 +47,10 @@
 import jdk.vm.ci.meta.JavaConstant;
 
 /**
- * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note
- * that these nodes are not built directly from the bytecode but are introduced by canonicalization.
+ * The {@code ConditionalNode} class represents a comparison that yields one of two (eagerly
+ * evaluated) values.
  */
-@NodeInfo(cycles = CYCLES_0, size = SIZE_2)
+@NodeInfo(cycles = CYCLES_1, size = SIZE_2)
 public final class ConditionalNode extends FloatingNode implements Canonicalizable, LIRLowerable {
 
     public static final NodeClass<ConditionalNode> TYPE = NodeClass.create(ConditionalNode.class);
@@ -116,7 +116,6 @@
                     valueStamp = valueStamp.join(bounds);
                 }
             }
-
         }
         return updateStamp(valueStamp);
     }
@@ -145,49 +144,10 @@
     }
 
     public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp) {
-        // this optimizes the case where a value from the range 0 - 1 is mapped to the range 0 - 1
-        if (trueValue.isConstant() && falseValue.isConstant() && trueValue.stamp() instanceof IntegerStamp && falseValue.stamp() instanceof IntegerStamp) {
-            long constTrueValue = trueValue.asJavaConstant().asLong();
-            long constFalseValue = falseValue.asJavaConstant().asLong();
-            if (condition instanceof IntegerEqualsNode) {
-                IntegerEqualsNode equals = (IntegerEqualsNode) condition;
-                if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
-                    IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
-                    if (equalsXStamp.upMask() == 1) {
-                        long equalsY = equals.getY().asJavaConstant().asLong();
-                        if (equalsY == 0) {
-                            if (constTrueValue == 0 && constFalseValue == 1) {
-                                // return x when: x == 0 ? 0 : 1;
-                                return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
-                            } else if (constTrueValue == 1 && constFalseValue == 0) {
-                                // negate a boolean value via xor
-                                return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
-                            }
-                        } else if (equalsY == 1) {
-                            if (constTrueValue == 1 && constFalseValue == 0) {
-                                // return x when: x == 1 ? 1 : 0;
-                                return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
-                            } else if (constTrueValue == 0 && constFalseValue == 1) {
-                                // negate a boolean value via xor
-                                return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
-                            }
-                        }
-                    }
-                }
-            } else if (condition instanceof IntegerTestNode) {
-                // replace IntegerTestNode with AndNode for the following patterns:
-                // (value & 1) == 0 ? 0 : 1
-                // (value & 1) == 1 ? 1 : 0
-                IntegerTestNode integerTestNode = (IntegerTestNode) condition;
-                if (integerTestNode.getY().isConstant()) {
-                    assert integerTestNode.getX().stamp() instanceof IntegerStamp;
-                    long testY = integerTestNode.getY().asJavaConstant().asLong();
-                    if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
-                        return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
-                    }
-                }
-            }
+        if (trueValue == falseValue) {
+            return trueValue;
         }
+
         if (condition instanceof CompareNode && ((CompareNode) condition).isIdentityComparison()) {
             // optimize the pattern (x == y) ? x : y
             CompareNode compare = (CompareNode) condition;
@@ -195,25 +155,87 @@
                 return falseValue;
             }
         }
-        if (trueValue == falseValue) {
-            return trueValue;
-        }
+
+        if (trueValue.stamp() instanceof IntegerStamp) {
+            // check if the conditional is redundant
+            if (condition instanceof IntegerLessThanNode) {
+                IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
+                IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp();
+                IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp();
+                if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
+                    // return "x" for "x < y ? x : y" in case that we know "x <= y"
+                    if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
+                        return trueValue;
+                    }
+                } else if (lessThan.getX() == falseValue && lessThan.getY() == trueValue) {
+                    // return "x" for "x < y ? y : x" in case that we know "x <= y"
+                    if (falseValueStamp.upperBound() <= trueValueStamp.lowerBound()) {
+                        return falseValue;
+                    }
+                }
+            }
 
-        if (condition instanceof IntegerLessThanNode && trueValue.stamp() instanceof IntegerStamp) {
-            /*
-             * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits - 1))))
-             * to avoid the test.
-             */
-            IntegerLessThanNode lt = (IntegerLessThanNode) condition;
-            if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
-                if (falseValue == lt.getX()) {
-                    if (trueValue instanceof AddNode) {
-                        AddNode add = (AddNode) trueValue;
-                        if (add.getX() == falseValue) {
-                            int bits = ((IntegerStamp) trueValue.stamp()).getBits();
-                            ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
-                            ValueNode and = new AndNode(shift, add.getY());
-                            return new AddNode(add.getX(), and);
+            // this optimizes the case where a value from the range 0 - 1 is mapped to the
+            // range 0 - 1
+            if (trueValue.isConstant() && falseValue.isConstant()) {
+                long constTrueValue = trueValue.asJavaConstant().asLong();
+                long constFalseValue = falseValue.asJavaConstant().asLong();
+                if (condition instanceof IntegerEqualsNode) {
+                    IntegerEqualsNode equals = (IntegerEqualsNode) condition;
+                    if (equals.getY().isConstant() && equals.getX().stamp() instanceof IntegerStamp) {
+                        IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp();
+                        if (equalsXStamp.upMask() == 1) {
+                            long equalsY = equals.getY().asJavaConstant().asLong();
+                            if (equalsY == 0) {
+                                if (constTrueValue == 0 && constFalseValue == 1) {
+                                    // return x when: x == 0 ? 0 : 1;
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                } else if (constTrueValue == 1 && constFalseValue == 0) {
+                                    // negate a boolean value via xor
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                }
+                            } else if (equalsY == 1) {
+                                if (constTrueValue == 1 && constFalseValue == 0) {
+                                    // return x when: x == 1 ? 1 : 0;
+                                    return IntegerConvertNode.convertUnsigned(equals.getX(), stamp);
+                                } else if (constTrueValue == 0 && constFalseValue == 1) {
+                                    // negate a boolean value via xor
+                                    return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(), 1)), stamp);
+                                }
+                            }
+                        }
+                    }
+                } else if (condition instanceof IntegerTestNode) {
+                    // replace IntegerTestNode with AndNode for the following patterns:
+                    // (value & 1) == 0 ? 0 : 1
+                    // (value & 1) == 1 ? 1 : 0
+                    IntegerTestNode integerTestNode = (IntegerTestNode) condition;
+                    if (integerTestNode.getY().isConstant()) {
+                        assert integerTestNode.getX().stamp() instanceof IntegerStamp;
+                        long testY = integerTestNode.getY().asJavaConstant().asLong();
+                        if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
+                            return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY()), stamp);
+                        }
+                    }
+                }
+            }
+
+            if (condition instanceof IntegerLessThanNode) {
+                /*
+                 * Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits -
+                 * 1)))) to avoid the test.
+                 */
+                IntegerLessThanNode lt = (IntegerLessThanNode) condition;
+                if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
+                    if (falseValue == lt.getX()) {
+                        if (trueValue instanceof AddNode) {
+                            AddNode add = (AddNode) trueValue;
+                            if (add.getX() == falseValue) {
+                                int bits = ((IntegerStamp) trueValue.stamp()).getBits();
+                                ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
+                                ValueNode and = new AndNode(shift, add.getY());
+                                return new AddNode(add.getX(), and);
+                            }
                         }
                     }
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/DivNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.graalvm.compiler.nodes.calc;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
-
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
-import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
-import org.graalvm.compiler.core.common.type.Stamp;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.graph.spi.CanonicalizerTool;
-import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-
-import jdk.vm.ci.code.CodeUtil;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.PrimitiveConstant;
-
-@NodeInfo(shortName = "/", cycles = CYCLES_32)
-public class DivNode extends BinaryArithmeticNode<Div> {
-
-    public static final NodeClass<DivNode> TYPE = NodeClass.create(DivNode.class);
-
-    public DivNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getDiv, x, y);
-    }
-
-    protected DivNode(NodeClass<? extends DivNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getDiv, x, y);
-    }
-
-    public static ValueNode create(ValueNode x, ValueNode y) {
-        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
-        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
-        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
-        if (tryConstantFold != null) {
-            return tryConstantFold;
-        }
-        return canonical(null, op, x, y);
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode ret = super.canonical(tool, forX, forY);
-        if (ret != this) {
-            return ret;
-        }
-
-        return canonical(this, getOp(forX, forY), forX, forY);
-    }
-
-    private static ValueNode canonical(DivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
-        if (forY.isConstant()) {
-            Constant c = forY.asConstant();
-            if (op.isNeutral(c)) {
-                return forX;
-            }
-            if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
-                long i = ((PrimitiveConstant) c).asLong();
-                boolean signFlip = false;
-                if (i < 0) {
-                    i = -i;
-                    signFlip = true;
-                }
-                ValueNode divResult = null;
-                if (CodeUtil.isPowerOf2(i)) {
-                    divResult = new RightShiftNode(forX, ConstantNode.forInt(CodeUtil.log2(i)));
-                }
-                if (divResult != null) {
-                    if (signFlip) {
-                        return NegateNode.create(divResult);
-                    } else {
-                        return divResult;
-                    }
-                }
-            }
-        }
-        return self != null ? self : new DivNode(forX, forY);
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
-        nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.nodes.calc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_32;
+
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.FloatStamp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Div;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+
+import jdk.vm.ci.meta.Constant;
+
+@NodeInfo(shortName = "/", cycles = CYCLES_32)
+public class FloatDivNode extends BinaryArithmeticNode<Div> {
+
+    public static final NodeClass<FloatDivNode> TYPE = NodeClass.create(FloatDivNode.class);
+
+    public FloatDivNode(ValueNode x, ValueNode y) {
+        this(TYPE, x, y);
+    }
+
+    protected FloatDivNode(NodeClass<? extends FloatDivNode> c, ValueNode x, ValueNode y) {
+        super(c, ArithmeticOpTable::getDiv, x, y);
+        assert stamp instanceof FloatStamp;
+    }
+
+    public static ValueNode create(ValueNode x, ValueNode y) {
+        BinaryOp<Div> op = ArithmeticOpTable.forStamp(x.stamp()).getDiv();
+        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+        if (tryConstantFold != null) {
+            return tryConstantFold;
+        }
+        return canonical(null, op, x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        return canonical(this, getOp(forX, forY), forX, forY);
+    }
+
+    private static ValueNode canonical(FloatDivNode self, BinaryOp<Div> op, ValueNode forX, ValueNode forY) {
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (op.isNeutral(c)) {
+                return forX;
+            }
+        }
+        return self != null ? self : new FloatDivNode(forX, forY);
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
+        nodeValueMap.setResult(this, gen.emitDiv(nodeValueMap.operand(getX()), nodeValueMap.operand(getY()), null));
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -129,7 +129,7 @@
         ValueNode convert = convert(input, stamp, false);
         if (!convert.isAlive()) {
             assert !convert.isDeleted();
-            convert = graph.addOrUnique(convert);
+            convert = graph.addOrUniqueWithInputs(convert);
         }
         return convert;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLessThanNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -52,7 +52,7 @@
 @NodeInfo(shortName = "<")
 public final class IntegerLessThanNode extends IntegerLowerThanNode {
     public static final NodeClass<IntegerLessThanNode> TYPE = NodeClass.create(IntegerLessThanNode.class);
-    public static final LessThanOp OP = new LessThanOp();
+    private static final LessThanOp OP = new LessThanOp();
 
     public IntegerLessThanNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y, OP);
@@ -203,49 +203,52 @@
                 }
             }
 
-            int bits = ((IntegerStamp) forX.stamp()).getBits();
-            assert ((IntegerStamp) forY.stamp()).getBits() == bits;
-            long min = OP.minValue(bits);
-            long xResidue = 0;
-            ValueNode left = null;
-            JavaConstant leftCst = null;
-            if (forX instanceof AddNode) {
-                AddNode xAdd = (AddNode) forX;
-                if (xAdd.getY().isJavaConstant()) {
-                    long xCst = xAdd.getY().asJavaConstant().asLong();
-                    xResidue = xCst - min;
-                    left = xAdd.getX();
+            if (forX.stamp() instanceof IntegerStamp) {
+                assert forY.stamp() instanceof IntegerStamp;
+                int bits = ((IntegerStamp) forX.stamp()).getBits();
+                assert ((IntegerStamp) forY.stamp()).getBits() == bits;
+                long min = OP.minValue(bits);
+                long xResidue = 0;
+                ValueNode left = null;
+                JavaConstant leftCst = null;
+                if (forX instanceof AddNode) {
+                    AddNode xAdd = (AddNode) forX;
+                    if (xAdd.getY().isJavaConstant()) {
+                        long xCst = xAdd.getY().asJavaConstant().asLong();
+                        xResidue = xCst - min;
+                        left = xAdd.getX();
+                    }
+                } else if (forX.isJavaConstant()) {
+                    leftCst = forX.asJavaConstant();
                 }
-            } else if (forX.isJavaConstant()) {
-                leftCst = forX.asJavaConstant();
-            }
-            if (left != null || leftCst != null) {
-                long yResidue = 0;
-                ValueNode right = null;
-                JavaConstant rightCst = null;
-                if (forY instanceof AddNode) {
-                    AddNode yAdd = (AddNode) forY;
-                    if (yAdd.getY().isJavaConstant()) {
-                        long yCst = yAdd.getY().asJavaConstant().asLong();
-                        yResidue = yCst - min;
-                        right = yAdd.getX();
+                if (left != null || leftCst != null) {
+                    long yResidue = 0;
+                    ValueNode right = null;
+                    JavaConstant rightCst = null;
+                    if (forY instanceof AddNode) {
+                        AddNode yAdd = (AddNode) forY;
+                        if (yAdd.getY().isJavaConstant()) {
+                            long yCst = yAdd.getY().asJavaConstant().asLong();
+                            yResidue = yCst - min;
+                            right = yAdd.getX();
+                        }
+                    } else if (forY.isJavaConstant()) {
+                        rightCst = forY.asJavaConstant();
                     }
-                } else if (forY.isJavaConstant()) {
-                    rightCst = forY.asJavaConstant();
-                }
-                if (right != null || rightCst != null) {
-                    if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
-                        if (left == null) {
-                            left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
-                        } else if (xResidue != 0) {
-                            left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                    if (right != null || rightCst != null) {
+                        if ((xResidue == 0 && left != null) || (yResidue == 0 && right != null)) {
+                            if (left == null) {
+                                left = ConstantNode.forIntegerBits(bits, leftCst.asLong() - min);
+                            } else if (xResidue != 0) {
+                                left = AddNode.create(left, ConstantNode.forIntegerBits(bits, xResidue));
+                            }
+                            if (right == null) {
+                                right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
+                            } else if (yResidue != 0) {
+                                right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
+                            }
+                            return new IntegerBelowNode(left, right);
                         }
-                        if (right == null) {
-                            right = ConstantNode.forIntegerBits(bits, rightCst.asLong() - min);
-                        } else if (yResidue != 0) {
-                            right = AddNode.create(right, ConstantNode.forIntegerBits(bits, yResidue));
-                        }
-                        return new IntegerBelowNode(left, right);
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IsNullNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -121,7 +121,8 @@
 
     @Override
     public Stamp getSucceedingStampForValue(boolean negated) {
-        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp();
+        // Ignore any more precise input stamp since canonicalization will skip through PiNodes
+        AbstractPointerStamp pointerStamp = (AbstractPointerStamp) getValue().stamp().unrestricted();
         return negated ? pointerStamp.asNonNull() : pointerStamp.asAlwaysNull();
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -63,29 +63,9 @@
             return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y);
         } else if (forY.isConstant()) {
             long c = forY.asJavaConstant().asLong();
-            if (c == 1) {
-                return forX;
-            }
-            if (c == -1) {
-                return NegateNode.create(forX);
-            }
-            long abs = Math.abs(c);
-            if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
-                ValueNode dividend = forX;
-                IntegerStamp stampX = (IntegerStamp) forX.stamp();
-                int log2 = CodeUtil.log2(abs);
-                // no rounding if dividend is positive or if its low bits are always 0
-                if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
-                    int bits = PrimitiveStamp.getBits(stamp());
-                    RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
-                    UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
-                    dividend = BinaryArithmeticNode.add(dividend, round);
-                }
-                RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
-                if (c < 0) {
-                    return NegateNode.create(shift);
-                }
-                return shift;
+            ValueNode v = canonical(forX, c);
+            if (v != null) {
+                return v;
             }
         }
 
@@ -113,6 +93,34 @@
         return this;
     }
 
+    public static ValueNode canonical(ValueNode forX, long c) {
+        if (c == 1) {
+            return forX;
+        }
+        if (c == -1) {
+            return NegateNode.create(forX);
+        }
+        long abs = Math.abs(c);
+        if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) {
+            ValueNode dividend = forX;
+            IntegerStamp stampX = (IntegerStamp) forX.stamp();
+            int log2 = CodeUtil.log2(abs);
+            // no rounding if dividend is positive or if its low bits are always 0
+            if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
+                int bits = PrimitiveStamp.getBits(forX.stamp());
+                RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
+                UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
+                dividend = BinaryArithmeticNode.add(dividend, round);
+            }
+            RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2));
+            if (c < 0) {
+                return NegateNode.create(shift);
+            }
+            return shift;
+        }
+        return null;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -72,13 +72,14 @@
                 return ConstantNode.forIntegerStamp(stamp(), 0);
             } else if (CodeUtil.isPowerOf2(constY)) {
                 if (xStamp.isPositive()) {
+                    // x & (y - 1)
                     return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
                 } else if (xStamp.isNegative()) {
+                    // -((-x) & (y - 1))
                     return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
                 } else {
-                    return new ConditionalNode(IntegerLessThanNode.create(forX, ConstantNode.forIntegerStamp(forX.stamp(), 0)),
-                                    new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1))),
-                                    new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+                    // x - ((x / y) << log2(y))
+                    return SubNode.create(forX, LeftShiftNode.create(SignedDivNode.canonical(forX, constY), ConstantNode.forInt(CodeUtil.log2(constY))));
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -45,6 +45,11 @@
         return value;
     }
 
+    public void setValue(ValueNode value) {
+        updateUsages(this.value, value);
+        this.value = value;
+    }
+
     /**
      * Creates a new UnaryNode instance.
      *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnpackEndianHalfNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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 org.graalvm.compiler.nodes.calc;
+
+import java.nio.ByteOrder;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * Produces the platform dependent first or second half of a long or double value as an int.
+ */
+@NodeInfo(cycles = NodeCycles.CYCLES_2)
+public final class UnpackEndianHalfNode extends UnaryNode implements Lowerable {
+    public static final NodeClass<UnpackEndianHalfNode> TYPE = NodeClass.create(UnpackEndianHalfNode.class);
+
+    private final boolean firstHalf;
+
+    protected UnpackEndianHalfNode(ValueNode value, boolean firstHalf) {
+        super(TYPE, StampFactory.forKind(JavaKind.Int), value);
+        assert value.getStackKind() == JavaKind.Double || value.getStackKind() == JavaKind.Long : "unexpected kind " + value.getStackKind();
+        this.firstHalf = firstHalf;
+    }
+
+    public static ValueNode create(ValueNode value, boolean firstHalf) {
+        if (value.isConstant() && value.asConstant().isDefaultForKind()) {
+            return ConstantNode.defaultForKind(JavaKind.Int);
+        }
+        return new UnpackEndianHalfNode(value, firstHalf);
+    }
+
+    public boolean isFirstHalf() {
+        return firstHalf;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool, ValueNode forValue) {
+        if (forValue.isConstant() && forValue.asConstant().isDefaultForKind()) {
+            return ConstantNode.defaultForKind(stamp.getStackKind());
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    public void lower(ByteOrder byteOrder) {
+        ValueNode result = value;
+        if (value.getStackKind() == JavaKind.Double) {
+            result = graph().unique(new ReinterpretNode(JavaKind.Long, value));
+        }
+        if ((byteOrder == ByteOrder.BIG_ENDIAN) == firstHalf) {
+            result = graph().unique(new UnsignedRightShiftNode(result, ConstantNode.forInt(32, graph())));
+        }
+        result = IntegerConvertNode.convert(result, StampFactory.forKind(JavaKind.Int), graph());
+        replaceAtUsagesAndDelete(result);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Thu Nov 16 12:15:55 2017 +0000
@@ -592,7 +592,11 @@
             for (Block block : reversePostOrder) {
                 AbstractBeginNode beginNode = block.getBeginNode();
                 if (beginNode instanceof LoopBeginNode) {
-                    Loop<Block> loop = new HIRLoop(block.getLoop(), loops.size(), block);
+                    Loop<Block> parent = block.getLoop();
+                    Loop<Block> loop = new HIRLoop(parent, loops.size(), block);
+                    if (parent != null) {
+                        parent.getChildren().add(loop);
+                    }
                     loops.add(loop);
                     block.setLoop(loop);
                     loop.getBlocks().add(block);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BranchProbabilityNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -82,6 +82,9 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
+        if (!hasUsages()) {
+            return;
+        }
         if (probability.isConstant()) {
             double probabilityValue = probability.asJavaConstant().asDouble();
             if (probabilityValue < 0.0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawLoadNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -79,7 +79,7 @@
         super(TYPE, stamp, object, offset, accessKind, locationIdentity, false);
     }
 
-    public RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
+    protected RawLoadNode(NodeClass<? extends RawLoadNode> c, ValueNode object, ValueNode offset, JavaKind accessKind, LocationIdentity locationIdentity) {
         super(c, StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity, false);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/RawStoreNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -29,7 +29,6 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -39,12 +38,10 @@
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
-import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.word.LocationIdentity;
 
 import jdk.vm.ci.meta.Assumptions;
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaField;
 
@@ -123,41 +120,8 @@
             if (indexValue.isConstant()) {
                 long off = indexValue.asJavaConstant().asLong();
                 int entryIndex = virtual.entryIndexForOffset(off, accessKind());
-                if (entryIndex != -1) {
-                    JavaKind entryKind = virtual.entryKind(entryIndex);
-                    boolean canVirtualize = entryKind == accessKind() || (entryKind == accessKind().getStackKind() && !StampTool.typeOrNull(object()).isArray());
-                    if (!canVirtualize) {
-                        /*
-                         * Special case: If the entryKind is long, allow arbitrary kinds as long as
-                         * a value of the same kind is already there. This can only happen if some
-                         * other node initialized the entry with a value of a different kind. One
-                         * example where this happens is the Truffle NewFrameNode.
-                         */
-                        ValueNode entry = tool.getEntry(virtual, entryIndex);
-                        if (entryKind == JavaKind.Long && entry.getStackKind() == value.getStackKind()) {
-                            canVirtualize = true;
-                        }
-                    }
-                    if (canVirtualize) {
-                        tool.setVirtualEntry(virtual, entryIndex, value(), true);
-                        tool.delete();
-                    } else {
-                        /*
-                         * Special case: Allow storing a single long or double value into two
-                         * consecutive int slots.
-                         */
-                        if ((accessKind() == JavaKind.Long || accessKind() == JavaKind.Double) && entryKind == JavaKind.Int) {
-                            int nextIndex = virtual.entryIndexForOffset(off + 4, entryKind);
-                            if (nextIndex != -1) {
-                                JavaKind nextKind = virtual.entryKind(nextIndex);
-                                if (nextKind == JavaKind.Int) {
-                                    tool.setVirtualEntry(virtual, entryIndex, value(), true);
-                                    tool.setVirtualEntry(virtual, nextIndex, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()), true);
-                                    tool.delete();
-                                }
-                            }
-                        }
-                    }
+                if (entryIndex != -1 && tool.setVirtualEntry(virtual, entryIndex, value(), accessKind(), off)) {
+                    tool.delete();
                 }
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java	Thu Nov 16 12:15:55 2017 +0000
@@ -280,7 +280,7 @@
             ObjectStamp receiverStamp = (ObjectStamp) value.stamp();
             Stamp stamp = receiverStamp.join(objectNonNull());
             FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, NullCheckException, action, true));
-            ValueNode nonNullReceiver = getGraph().addOrUnique(PiNode.create(value, stamp, fixedGuard));
+            ValueNode nonNullReceiver = getGraph().addOrUniqueWithInputs(PiNode.create(value, stamp, fixedGuard));
             // TODO: Propogating the non-null into the frame state would
             // remove subsequent null-checks on the same value. However,
             // it currently causes an assertion failure when merging states.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InlineInvokePlugin.java	Thu Nov 16 12:15:55 2017 +0000
@@ -53,6 +53,12 @@
          */
         public static final InlineInfo DO_NOT_INLINE_NO_EXCEPTION = new InlineInfo(null, null);
 
+        /**
+         * Denotes a call site must not be inlined and the execution should be transferred to
+         * interpreter in case of an exception.
+         */
+        public static final InlineInfo DO_NOT_INLINE_DEOPTIMIZE_ON_EXCEPTION = new InlineInfo(null, null);
+
         private final ResolvedJavaMethod methodToInline;
         private final BytecodeProvider intrinsicBytecodeProvider;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/IntrinsicContext.java	Thu Nov 16 12:15:55 2017 +0000
@@ -66,6 +66,34 @@
      */
     final BytecodeProvider bytecodeProvider;
 
+    final CompilationContext compilationContext;
+
+    final boolean allowPartialIntrinsicArgumentMismatch;
+
+    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
+        this(method, intrinsic, bytecodeProvider, compilationContext, false);
+    }
+
+    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext,
+                    boolean allowPartialIntrinsicArgumentMismatch) {
+        this.method = method;
+        this.intrinsic = intrinsic;
+        this.bytecodeProvider = bytecodeProvider;
+        assert bytecodeProvider != null;
+        this.compilationContext = compilationContext;
+        this.allowPartialIntrinsicArgumentMismatch = allowPartialIntrinsicArgumentMismatch;
+        assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
+    }
+
+    /**
+     * A partial intrinsic exits by (effectively) calling the intrinsified method. Normally, this
+     * call must use exactly the same arguments as the call that is being intrinsified. This allows
+     * to override this behavior.
+     */
+    public boolean allowPartialIntrinsicArgumentMismatch() {
+        return allowPartialIntrinsicArgumentMismatch;
+    }
+
     /**
      * Gets the method being intrinsified.
      */
@@ -96,17 +124,6 @@
         return method.equals(targetMethod) || intrinsic.equals(targetMethod);
     }
 
-    final CompilationContext compilationContext;
-
-    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, BytecodeProvider bytecodeProvider, CompilationContext compilationContext) {
-        this.method = method;
-        this.intrinsic = intrinsic;
-        this.bytecodeProvider = bytecodeProvider;
-        assert bytecodeProvider != null;
-        this.compilationContext = compilationContext;
-        assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
-    }
-
     public boolean isPostParseInlined() {
         return compilationContext.equals(INLINE_AFTER_PARSING);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/InstanceOfNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -49,6 +49,8 @@
 import jdk.vm.ci.meta.JavaTypeProfile;
 import jdk.vm.ci.meta.TriState;
 
+import java.util.Objects;
+
 /**
  * The {@code InstanceOfNode} represents an instanceof test.
  */
@@ -56,7 +58,7 @@
 public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable {
     public static final NodeClass<InstanceOfNode> TYPE = NodeClass.create(InstanceOfNode.class);
 
-    protected final ObjectStamp checkedStamp;
+    private ObjectStamp checkedStamp;
 
     private JavaTypeProfile profile;
     @OptionalInput(Anchor) protected AnchoringNode anchor;
@@ -126,7 +128,9 @@
                 // The check will always succeed, the union of the two stamps is equal to the
                 // checked stamp.
                 return LogicConstantNode.tautology();
-            } else if (checkedStamp.type().equals(meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
+            } else if (checkedStamp.alwaysNull()) {
+                return IsNullNode.create(object);
+            } else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
                 assert checkedStamp.nonNull() != inputStamp.nonNull();
                 // The only difference makes the null-ness of the value => simplify the check.
                 if (checkedStamp.nonNull()) {
@@ -135,8 +139,8 @@
                     return IsNullNode.create(object);
                 }
             }
+            assert checkedStamp.type() != null;
         }
-
         return null;
     }
 
@@ -204,4 +208,13 @@
     public AnchoringNode getAnchor() {
         return anchor;
     }
+
+    public ObjectStamp getCheckedStamp() {
+        return checkedStamp;
+    }
+
+    public void strengthenCheckedStamp(ObjectStamp newCheckedStamp) {
+        assert this.checkedStamp.join(newCheckedStamp).equals(newCheckedStamp) : "stamp can only improve";
+        this.checkedStamp = newCheckedStamp;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,7 +25,6 @@
 import static org.graalvm.compiler.graph.iterators.NodePredicates.isNotA;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 
-import jdk.vm.ci.meta.ConstantReflectionProvider;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
@@ -47,15 +46,16 @@
 import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.DeoptimizationReason;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
-import org.graalvm.compiler.options.OptionValues;
 
 /**
  * The {@code LoadFieldNode} represents a read of a static or instance field.
@@ -150,7 +150,7 @@
     }
 
     public ConstantNode asConstant(CanonicalizerTool tool, JavaConstant constant) {
-        return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, getOptions());
+        return ConstantFoldUtil.tryConstantFold(tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getMetaAccess(), field(), constant, tool.getOptions());
     }
 
     private static PhiNode asPhi(ConstantFieldProvider constantFields, ConstantReflectionProvider constantReflection,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -29,7 +29,6 @@
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -38,7 +37,6 @@
 import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 
-import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.ResolvedJavaField;
 
 /**
@@ -90,15 +88,8 @@
             VirtualInstanceNode virtual = (VirtualInstanceNode) alias;
             int fieldIndex = virtual.fieldIndex(field());
             if (fieldIndex != -1) {
-                ValueNode existing = tool.getEntry((VirtualObjectNode) alias, fieldIndex);
-                if (existing.stamp().isCompatible(value().stamp())) {
-                    tool.setVirtualEntry(virtual, fieldIndex, value(), false);
-                    tool.delete();
-                } else {
-                    // stamp of the value is not compatible with the value in the virtualizer
-                    // can only happen with unsafe two slot writes on one slot fields
-                    assert existing instanceof ConstantNode && ((ConstantNode) existing).asConstant().equals(JavaConstant.forIllegal()) : value.stamp() + " vs " + existing.stamp();
-                }
+                tool.setVirtualEntry(virtual, fieldIndex, value());
+                tool.delete();
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -89,7 +89,7 @@
                 ResolvedJavaType componentType = virtual.type().getComponentType();
                 if (componentType.isPrimitive() || StampTool.isPointerAlwaysNull(value) || componentType.getSuperclass() == null ||
                                 (StampTool.typeReferenceOrNull(value) != null && componentType.isAssignableFrom(StampTool.typeOrNull(value)))) {
-                    tool.setVirtualEntry(virtual, idx, value(), false);
+                    tool.setVirtualEntry(virtual, idx, value());
                     tool.delete();
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/MemoryPhiNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -62,4 +62,9 @@
     public NodeInputList<ValueNode> values() {
         return values;
     }
+
+    @Override
+    protected String valueDescription() {
+        return locationIdentity.toString();
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/OffsetAddressNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.nodes.memory.address;
 
+import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.Node;
@@ -52,6 +53,9 @@
         super(TYPE);
         this.base = base;
         this.offset = offset;
+
+        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64) &&
+                        offset != null && IntegerStamp.getBits(offset.stamp()) == 64 : "both values must have 64 bits";
     }
 
     @Override
@@ -62,6 +66,7 @@
     public void setBase(ValueNode base) {
         updateUsages(this.base, base);
         this.base = base;
+        assert base != null && (base.stamp() instanceof AbstractPointerStamp || IntegerStamp.getBits(base.stamp()) == 64);
     }
 
     public ValueNode getOffset() {
@@ -71,6 +76,7 @@
     public void setOffset(ValueNode offset) {
         updateUsages(this.offset, offset);
         this.offset = offset;
+        assert offset != null && IntegerStamp.getBits(offset.stamp()) == 64;
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/VirtualizerTool.java	Thu Nov 16 12:15:55 2017 +0000
@@ -25,6 +25,7 @@
 import java.util.List;
 
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
@@ -91,9 +92,17 @@
      *
      * @param index the index to be set.
      * @param value the new value for the given index.
-     * @param unsafe if true, then mismatching value {@link JavaKind}s will be accepted.
+     * @param accessKind the kind of the store which might be different than
+     *            {@link VirtualObjectNode#entryKind(int)}.
+     * @return true if the operation was permitted
      */
-    void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, boolean unsafe);
+    boolean setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value, JavaKind accessKind, long offset);
+
+    default void setVirtualEntry(VirtualObjectNode virtualObject, int index, ValueNode value) {
+        if (!setVirtualEntry(virtualObject, index, value, null, 0)) {
+            throw new GraalError("unexpected failure when updating virtual entry");
+        }
+    }
 
     ValueNode getEntry(VirtualObjectNode virtualObject, int index);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Thu Nov 16 12:15:55 2017 +0000
@@ -242,7 +242,7 @@
                 EconomicSet<Node> collectedUnusedNodes = unusedNodes = EconomicSet.create(Equivalence.IDENTITY);
                 nodeEventScope = node.graph().trackNodeEvents(new Graph.NodeEventListener() {
                     @Override
-                    public void event(Graph.NodeEvent e, Node n) {
+                    public void changed(Graph.NodeEvent e, Node n) {
                         if (e == Graph.NodeEvent.ZERO_USAGES && isFloatingNode(n) && !(n instanceof GuardNode)) {
                             collectedUnusedNodes.add(n);
                         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormattable.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * 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.nodes.util;
+
+/**
+ * Performs special formatting of values involving {@link jdk.vm.ci.meta.JavaConstant JavaConstants}
+ * when they are being dumped.
+ */
+public interface JavaConstantFormattable {
+    String format(JavaConstantFormatter formatter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/JavaConstantFormatter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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 org.graalvm.compiler.nodes.util;
+
+import jdk.vm.ci.meta.JavaConstant;
+
+public interface JavaConstantFormatter {
+    String format(JavaConstant constant);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,7 +37,7 @@
 import jdk.vm.ci.meta.ResolvedJavaType;
 import sun.misc.Unsafe;
 
-@NodeInfo(nameTemplate = "VirtualArray {p#componentType/s}[{p#length}]")
+@NodeInfo(nameTemplate = "VirtualArray({p#objectId}) {p#componentType/s}[{p#length}]")
 public class VirtualArrayNode extends VirtualObjectNode implements ArrayLengthProvider {
 
     public static final NodeClass<VirtualArrayNode> TYPE = NodeClass.create(VirtualArrayNode.class);
@@ -76,7 +76,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + " " + componentType.getName() + "[" + length + "]";
+            return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + componentType.getName() + "[" + length + "]";
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualInstanceNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -32,7 +32,7 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(nameTemplate = "VirtualInstance {p#type/s}")
+@NodeInfo(nameTemplate = "VirtualInstance({p#objectId}) {p#type/s}")
 public class VirtualInstanceNode extends VirtualObjectNode {
 
     public static final NodeClass<VirtualInstanceNode> TYPE = NodeClass.create(VirtualInstanceNode.class);
@@ -78,7 +78,7 @@
     @Override
     public String toString(Verbosity verbosity) {
         if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + " " + type.toJavaName(false);
+            return super.toString(Verbosity.Name) + "(" + getObjectId() + ") " + type.toJavaName(false);
         } else {
             return super.toString(verbosity);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options.processor/src/org/graalvm/compiler/options/processor/OptionProcessor.java	Thu Nov 16 12:15:55 2017 +0000
@@ -394,6 +394,9 @@
                     options = new OptionsInfo(topDeclaringType);
                     map.put(topDeclaringType, options);
                 }
+                if (!element.getEnclosingElement().getSimpleName().toString().endsWith("Options")) {
+                    processingEnv.getMessager().printMessage(Kind.ERROR, "Option declaring classes must have a name that ends with 'Options'", element.getEnclosingElement());
+                }
                 processElement(element, options);
             }
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -248,7 +248,7 @@
         /**
          * Tests which may be eliminated because post dominating tests to prove a broader condition.
          */
-        private Deque<PendingTest> pendingTests;
+        private Deque<DeoptimizingGuard> pendingTests;
 
         public Instance(StructuredGraph graph, BlockMap<List<Node>> blockToNodes, PhaseContext context) {
             this.graph = graph;
@@ -555,7 +555,8 @@
                 }
             }
             if (guard instanceof DeoptimizingGuard) {
-                pendingTests.push(new PendingTest(condition, (DeoptimizingGuard) guard));
+                assert ((DeoptimizingGuard) guard).getCondition() == condition;
+                pendingTests.push((DeoptimizingGuard) guard);
             }
             registerCondition(condition, negated, guard);
         }
@@ -628,15 +629,16 @@
         }
 
         protected boolean foldPendingTest(DeoptimizingGuard thisGuard, ValueNode original, Stamp newStamp, GuardRewirer rewireGuardFunction) {
-            for (PendingTest pending : pendingTests) {
+            for (DeoptimizingGuard pendingGuard : pendingTests) {
+                LogicNode pendingCondition = pendingGuard.getCondition();
                 TriState result = TriState.UNKNOWN;
-                if (pending.condition instanceof UnaryOpLogicNode) {
-                    UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pending.condition;
+                if (pendingCondition instanceof UnaryOpLogicNode) {
+                    UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pendingCondition;
                     if (unaryLogicNode.getValue() == original) {
                         result = unaryLogicNode.tryFold(newStamp);
                     }
-                } else if (pending.condition instanceof BinaryOpLogicNode) {
-                    BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pending.condition;
+                } else if (pendingCondition instanceof BinaryOpLogicNode) {
+                    BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pendingCondition;
                     ValueNode x = binaryOpLogicNode.getX();
                     ValueNode y = binaryOpLogicNode.getY();
                     if (x == original) {
@@ -659,7 +661,7 @@
                      */
                     InputFilter v = new InputFilter(original);
                     thisGuard.getCondition().applyInputs(v);
-                    if (v.ok && foldGuard(thisGuard, pending.guard, newStamp, rewireGuardFunction)) {
+                    if (v.ok && foldGuard(thisGuard, pendingGuard, newStamp, rewireGuardFunction)) {
                         return true;
                     }
                 }
@@ -1026,16 +1028,6 @@
         boolean rewire(GuardingNode guard, boolean result, Stamp guardedValueStamp, ValueNode newInput);
     }
 
-    protected static class PendingTest {
-        private final LogicNode condition;
-        private final DeoptimizingGuard guard;
-
-        public PendingTest(LogicNode condition, DeoptimizingGuard guard) {
-            this.condition = condition;
-            this.guard = guard;
-        }
-    }
-
     protected static final class InfoElement {
         private final Stamp stamp;
         private final GuardingNode guard;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -221,7 +221,12 @@
             EconomicMap<ValueNode, Stamp> endMap = endMaps.get(node);
             MapCursor<ValueNode, Stamp> entries = endMap.getEntries();
             while (entries.advance()) {
-                if (registerNewValueStamp(entries.getKey(), entries.getValue())) {
+                ValueNode value = entries.getKey();
+                if (value.isDeleted()) {
+                    // nodes from this map can be deleted when a loop dies
+                    continue;
+                }
+                if (registerNewValueStamp(value, entries.getValue())) {
                     counterBetterMergedStamps.increment(debug);
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -48,7 +48,7 @@
 import org.graalvm.compiler.nodes.VirtualState;
 import org.graalvm.compiler.nodes.calc.BinaryNode;
 import org.graalvm.compiler.nodes.calc.ConvertNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.calc.NotNode;
@@ -162,7 +162,7 @@
             return 2;
         } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
             return 1;
-        } else if (node instanceof IntegerDivRemNode || node instanceof DivNode || node instanceof RemNode) {
+        } else if (node instanceof IntegerDivRemNode || node instanceof FloatDivNode || node instanceof RemNode) {
             return 10;
         } else if (node instanceof MulNode) {
             return 3;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java	Thu Nov 16 12:15:55 2017 +0000
@@ -43,7 +43,6 @@
 import org.graalvm.compiler.phases.graph.FixedNodeProbabilityCache;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 
-import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 /**
@@ -159,11 +158,11 @@
             if (param.usages().isNotEmpty()) {
                 ValueNode arg = args.get(param.index());
                 if (arg.isConstant()) {
-                    Constant constant = arg.asConstant();
+                    ConstantNode constant = (ConstantNode) arg;
                     parameterUsages = trackParameterUsages(param, parameterUsages);
                     // collect param usages before replacing the param
                     param.replaceAtUsagesAndDelete(graph.unique(
-                                    ConstantNode.forConstant(arg.stamp(), constant, ((ConstantNode) arg).getStableDimension(), ((ConstantNode) arg).isDefaultStable(), context.getMetaAccess())));
+                                    ConstantNode.forConstant(arg.stamp(), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
                     // param-node gone, leaving a gap in the sequence given by param.index()
                 } else {
                     Stamp impro = improvedStamp(arg, param);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/HashSetNodeEventListener.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,7 +37,7 @@
  * A simple {@link NodeEventListener} implementation that accumulates event nodes in a
  * {@link HashSet}.
  */
-public class HashSetNodeEventListener implements NodeEventListener {
+public class HashSetNodeEventListener extends NodeEventListener {
 
     private final EconomicSet<Node> nodes;
     private final Set<NodeEvent> filter;
@@ -68,7 +68,7 @@
     }
 
     @Override
-    public void event(NodeEvent e, Node node) {
+    public void changed(NodeEvent e, Node node) {
         if (filter.contains(e)) {
             nodes.add(node);
             if (node instanceof IndirectCanonicalization) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -258,7 +258,7 @@
         return false;
     }
 
-    private final class GraphChangeListener implements NodeEventListener {
+    private final class GraphChangeListener extends NodeEventListener {
         boolean changed;
         private StructuredGraph graph;
         private Mark mark;
@@ -269,7 +269,7 @@
         }
 
         @Override
-        public void event(NodeEvent e, Node node) {
+        public void changed(NodeEvent e, Node node) {
             if (!graph.isNew(mark, node) && node.isAlive()) {
                 if (e == NodeEvent.INPUT_CHANGED || e == NodeEvent.ZERO_USAGES) {
                     changed = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -109,7 +109,7 @@
         if (immutableGraph && Assertions.assertionsEnabled()) {
             return graph.trackNodeEvents(new NodeEventListener() {
                 @Override
-                public void event(NodeEvent e, Node node) {
+                public void changed(NodeEvent e, Node node) {
                     assert false : "graph changed: " + e + " on node " + node;
                 }
             });
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGetOptionsUsage.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,86 @@
+/*
+ * 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.phases.verify;
+
+import java.lang.reflect.MalformedParametersException;
+import java.lang.reflect.Method;
+
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * {@link Node#getOptions()} is unsafe for use during canonicalization so try to verify that it
+ * isn't used when a {@link CanonicalizerTool} is available in the arguments. This is slightly more
+ * general but since there are several canonical methods with varying signatures this covers more
+ * cases.
+ */
+public class VerifyGetOptionsUsage extends VerifyPhase<PhaseContext> {
+    static Method lookupMethod(Class<?> klass, String name) {
+        for (Method m : klass.getDeclaredMethods()) {
+            if (m.getName().equals(name)) {
+                return m;
+            }
+        }
+        throw new InternalError();
+    }
+
+    @Override
+    protected boolean verify(StructuredGraph graph, PhaseContext context) {
+        MetaAccessProvider metaAccess = context.getMetaAccess();
+        ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
+        boolean hasTool = false;
+        try {
+            for (ResolvedJavaMethod.Parameter parameter : graph.method().getParameters()) {
+                if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
+                    hasTool = true;
+                    break;
+                }
+            }
+        } catch (MalformedParametersException e) {
+            // Lambdas sometimes have malformed parameters so ignore this.
+        }
+        if (hasTool) {
+            ResolvedJavaMethod getOptionsMethod = metaAccess.lookupJavaMethod(lookupMethod(Node.class, "getOptions"));
+            for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+                ResolvedJavaMethod callee = t.targetMethod();
+                if (callee.equals(getOptionsMethod)) {
+                    if (hasTool) {
+                        throw new VerificationError("Must use CanonicalizerTool.getOptions() instead of Node.getOptions() in method '%s' of class '%s'.",
+                                        graph.method().getName(), graph.method().getDeclaringClass().getName());
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyGraphAddUsage.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,117 @@
+/*
+ * 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.phases.verify;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.Graph;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.Invoke;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
+import org.graalvm.compiler.nodes.ValueProxyNode;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.spi.LoweringProvider;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.util.EconomicSet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class VerifyGraphAddUsage extends VerifyPhase<PhaseContext> {
+    private static final Method ADD_OR_UNIQUE;
+    private static final Method CONSTRUCTOR_NEW_INSTANCE;
+    private static final EconomicSet<Class<?>> ALLOWED_CLASSES = EconomicSet.create();
+
+    static {
+        try {
+            ADD_OR_UNIQUE = Graph.class.getDeclaredMethod("addOrUnique", Node.class);
+            CONSTRUCTOR_NEW_INSTANCE = Constructor.class.getDeclaredMethod("newInstance", Object[].class);
+        } catch (NoSuchMethodException e) {
+            throw new GraalError(e);
+        }
+
+        ALLOWED_CLASSES.add(Graph.class);
+        ALLOWED_CLASSES.add(LoweringProvider.class);
+    }
+
+    @Override
+    protected boolean verify(StructuredGraph graph, PhaseContext context) {
+        boolean allowed = false;
+        for (Class<?> cls : ALLOWED_CLASSES) {
+            ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
+            if (context.getMetaAccess().lookupJavaType(cls).isAssignableFrom(declaringClass)) {
+                allowed = true;
+            }
+        }
+        if (!allowed) {
+            ResolvedJavaMethod addOrUniqueMethod = context.getMetaAccess().lookupJavaMethod(ADD_OR_UNIQUE);
+            for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+                ResolvedJavaMethod callee = t.targetMethod();
+                if (callee.equals(addOrUniqueMethod)) {
+                    ValueNode nodeArgument = t.arguments().get(1);
+                    EconomicSet<Node> seen = EconomicSet.create();
+                    checkNonFactory(graph, seen, context, nodeArgument);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, PhaseContext context, ValueNode node) {
+        if (seen.contains(node)) {
+            return;
+        }
+        seen.add(node);
+
+        // Check where the value came from recursively, or if it is allowed.
+        if (node instanceof ValuePhiNode) {
+            for (ValueNode input : ((ValuePhiNode) node).values()) {
+                checkNonFactory(graph, seen, context, input);
+            }
+        } else if (node instanceof PiNode) {
+            checkNonFactory(graph, seen, context, ((PiNode) node).object());
+        } else if (node instanceof ParameterNode) {
+            return;
+        } else if (node instanceof ConstantNode) {
+            return;
+        } else if (node instanceof ValueProxyNode) {
+            checkNonFactory(graph, seen, context, ((ValueProxyNode) node).value());
+        } else if (node instanceof Invoke && ((Invoke) node).callTarget().targetMethod().equals(context.getMetaAccess().lookupJavaMethod(CONSTRUCTOR_NEW_INSTANCE))) {
+            return;
+        } else if (!(node instanceof NewInstanceNode)) {
+            // In all other cases, the argument must be a new instance.
+            throw new VerificationError("Must add node '%s' with inputs in method '%s' of class '%s'.",
+                            node, graph.method().getName(), graph.method().getDeclaringClass().getName());
+        }
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BasicIdealGraphPrinter.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) 2011, 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.printer;
-
-import java.io.BufferedOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Elementary, generic generator of Ideal Graph Visualizer input for use in printers for specific
- * data structures.
- */
-class BasicIdealGraphPrinter {
-
-    /**
-     * Edge between two nodes.
-     */
-    protected static class Edge {
-
-        final String from;
-        final int fromIndex;
-        final String to;
-        final int toIndex;
-        final String label;
-
-        public Edge(String from, int fromIndex, String to, int toIndex, String label) {
-            assert (from != null && to != null);
-            this.from = from;
-            this.fromIndex = fromIndex;
-            this.to = to;
-            this.toIndex = toIndex;
-            this.label = label;
-        }
-
-        @Override
-        public int hashCode() {
-            int h = from.hashCode() ^ to.hashCode();
-            h = 3 * h + fromIndex;
-            h = 5 * h + toIndex;
-            if (label != null) {
-                h ^= label.hashCode();
-            }
-            return h;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == this) {
-                return true;
-            }
-            if (obj instanceof Edge) {
-                Edge other = (Edge) obj;
-                return from.equals(other.from) && fromIndex == other.fromIndex && to.equals(other.to) && toIndex == other.toIndex &&
-                                (label == other.label || (label != null && label.equals(other.label)));
-            }
-            return false;
-        }
-    }
-
-    private final PrintStream stream;
-
-    /**
-     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
-     */
-    protected BasicIdealGraphPrinter(OutputStream stream) {
-        try {
-            OutputStream buffered;
-            if (stream instanceof BufferedOutputStream) {
-                buffered = stream;
-            } else {
-                buffered = new BufferedOutputStream(stream, 256 * 1024);
-            }
-            this.stream = new PrintStream(buffered, false, Charset.defaultCharset().name());
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Flushes any buffered output.
-     */
-    protected void flush() {
-        stream.flush();
-    }
-
-    /**
-     * Starts a new graph document.
-     */
-    protected void begin() {
-        stream.println("<graphDocument>");
-    }
-
-    protected void beginGroup() {
-        stream.println("<group>");
-    }
-
-    protected void beginMethod(String name, String shortName, int bci) {
-        stream.printf(" <method name='%s' shortName='%s' bci='%d'>%n", escape(name), escape(shortName), bci);
-    }
-
-    protected void beginBytecodes() {
-        stream.println("  <bytecodes>\n<![CDATA[");
-    }
-
-    protected void printBytecode(int bci, String mnemonic, int[] extra) {
-        stream.print(bci);
-        stream.print(' ');
-        stream.print(mnemonic);
-        if (extra != null) {
-            for (int b : extra) {
-                stream.print(' ');
-                stream.print(b);
-            }
-        }
-        stream.println();
-    }
-
-    protected void endBytecodes() {
-        stream.println("  ]]></bytecodes>");
-    }
-
-    protected void printBytecodes(String disassembly) {
-        beginBytecodes();
-        stream.println(disassembly);
-        endBytecodes();
-    }
-
-    protected void endMethod() {
-        stream.println(" </method>");
-    }
-
-    protected void beginGraph(String title) {
-        stream.printf(" <graph name='%s'>%n", escape(title));
-    }
-
-    protected void beginProperties() {
-        stream.print("<properties>");
-    }
-
-    protected void printProperty(String name, String value) {
-        stream.printf("<p name='%s'>%s</p>", escape(name), escape(value));
-    }
-
-    protected void endProperties() {
-        stream.print("</properties>");
-    }
-
-    protected void printProperties(Map<String, String> properties) {
-        beginProperties();
-        for (Entry<String, String> entry : properties.entrySet()) {
-            printProperty(entry.getKey(), entry.getValue());
-        }
-        endProperties();
-    }
-
-    protected void beginNodes() {
-        stream.println("  <nodes>");
-    }
-
-    protected void beginNode(String id) {
-        stream.printf("   <node id='%s'>", escape(id));
-    }
-
-    protected void endNode() {
-        stream.println("   </node>");
-    }
-
-    protected void printNode(String id, Map<String, String> properties) {
-        beginNode(id);
-        if (properties != null) {
-            printProperties(properties);
-        }
-        endNode();
-    }
-
-    protected void endNodes() {
-        stream.println("  </nodes>");
-    }
-
-    protected void beginEdges() {
-        stream.println("  <edges>");
-    }
-
-    protected void printEdge(Edge edge) {
-        stream.printf("   <edge from='%s' fromIndex='%d' to='%s' toIndex='%d' label='%s' />%n", escape(edge.from), edge.fromIndex, escape(edge.to), edge.toIndex, escape(edge.label));
-    }
-
-    protected void endEdges() {
-        stream.println("  </edges>");
-    }
-
-    protected void beginControlFlow() {
-        stream.println("  <controlFlow>");
-    }
-
-    protected void beginBlock(String name) {
-        stream.printf("   <block name='%s'>%n", escape(name));
-    }
-
-    protected void beginSuccessors() {
-        stream.println("    <successors>");
-    }
-
-    protected void printSuccessor(String name) {
-        stream.printf("     <successor name='%s'/>%n", escape(name));
-    }
-
-    protected void endSuccessors() {
-        stream.println("    </successors>");
-    }
-
-    protected void beginBlockNodes() {
-        stream.println("    <nodes>");
-    }
-
-    protected void printBlockNode(String nodeId) {
-        stream.printf("     <node id='%s'/>%n", escape(nodeId));
-    }
-
-    protected void endBlockNodes() {
-        stream.println("    </nodes>");
-    }
-
-    protected void endBlock() {
-        stream.println("   </block>");
-    }
-
-    protected void endControlFlow() {
-        stream.println("  </controlFlow>");
-    }
-
-    protected void endGraph() {
-        stream.println(" </graph>");
-    }
-
-    /**
-     * Ends the current group.
-     */
-    public void endGroup() {
-        stream.println("</group>");
-    }
-
-    /**
-     * Finishes the graph document and flushes the output stream.
-     */
-    protected void end() {
-        stream.println("</graphDocument>");
-        flush();
-    }
-
-    public void close() {
-        end();
-        stream.close();
-    }
-
-    public boolean isValid() {
-        return !stream.checkError();
-    }
-
-    private static String escape(String s) {
-        StringBuilder str = null;
-        for (int i = 0; i < s.length(); i++) {
-            char c = s.charAt(i);
-            switch (c) {
-                case '&':
-                case '<':
-                case '>':
-                case '"':
-                case '\'':
-                    if (str == null) {
-                        str = new StringBuilder();
-                        str.append(s, 0, i);
-                    }
-                    switch (c) {
-                        case '&':
-                            str.append("&amp;");
-                            break;
-                        case '<':
-                            str.append("&lt;");
-                            break;
-                        case '>':
-                            str.append("&gt;");
-                            break;
-                        case '"':
-                            str.append("&quot;");
-                            break;
-                        case '\'':
-                            str.append("&apos;");
-                            break;
-                        default:
-                            assert false;
-                    }
-                    break;
-                case '\u0000':
-                case '\u0001':
-                case '\u0002':
-                case '\u0003':
-                case '\u0004':
-                case '\u0005':
-                case '\u0006':
-                case '\u0007':
-                case '\u0008':
-                case '\u000b':
-                case '\u000c':
-                case '\u000e':
-                case '\u000f':
-                case '\u0010':
-                case '\u0011':
-                case '\u0012':
-                case '\u0013':
-                case '\u0014':
-                case '\u0015':
-                case '\u0016':
-                case '\u0017':
-                case '\u0018':
-                case '\u0019':
-                case '\u001a':
-                case '\u001b':
-                case '\u001c':
-                case '\u001d':
-                case '\u001e':
-                case '\u001f':
-                    if (str == null) {
-                        str = new StringBuilder();
-                        str.append(s, 0, i);
-                    }
-                    str.append("'0x").append(Integer.toHexString(c));
-                    break;
-                default:
-                    if (str != null) {
-                        str.append(c);
-                    }
-                    break;
-            }
-        }
-        if (str == null) {
-            return s;
-        } else {
-            return str.toString();
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -26,18 +26,17 @@
 import static org.graalvm.compiler.graph.Edges.Type.Successors;
 
 import java.io.IOException;
-import java.nio.channels.WritableByteChannel;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import jdk.vm.ci.meta.ResolvedJavaField;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.graph.CachedGraph;
 import org.graalvm.compiler.graph.Edges;
@@ -46,6 +45,7 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractEndNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -55,15 +55,11 @@
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.ProxyNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.VirtualState;
 import org.graalvm.compiler.nodes.cfg.Block;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.graph.NodeSourcePosition;
-import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormattable;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.graphio.GraphBlocks;
 import org.graalvm.graphio.GraphElements;
@@ -71,6 +67,11 @@
 import org.graalvm.graphio.GraphStructure;
 import org.graalvm.graphio.GraphTypes;
 
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+
 public class BinaryGraphPrinter implements
                 GraphStructure<BinaryGraphPrinter.GraphInfo, Node, NodeClass<?>, Edges>,
                 GraphBlocks<BinaryGraphPrinter.GraphInfo, Block, Node>,
@@ -79,8 +80,8 @@
     private final SnippetReflectionProvider snippetReflection;
     private final GraphOutput<BinaryGraphPrinter.GraphInfo, ResolvedJavaMethod> output;
 
-    public BinaryGraphPrinter(WritableByteChannel channel, SnippetReflectionProvider snippetReflection) throws IOException {
-        this.output = GraphOutput.newBuilder(this).blocks(this).elements(this).types(this).build(channel);
+    public BinaryGraphPrinter(DebugContext ctx, SnippetReflectionProvider snippetReflection) throws IOException {
+        this.output = ctx.buildOutput(GraphOutput.newBuilder(this).protocolVersion(5, 0).blocks(this).elements(this).types(this));
         this.snippetReflection = snippetReflection;
     }
 
@@ -116,17 +117,24 @@
     }
 
     @Override
+    public Node node(Object obj) {
+        return obj instanceof Node ? (Node) obj : null;
+    }
+
+    @Override
     public NodeClass<?> nodeClass(Object obj) {
         if (obj instanceof NodeClass<?>) {
             return (NodeClass<?>) obj;
         }
-        if (obj instanceof Node) {
-            return ((Node) obj).getNodeClass();
-        }
         return null;
     }
 
     @Override
+    public NodeClass<?> classForNode(Node node) {
+        return node.getNodeClass();
+    }
+
+    @Override
     public Object nodeClassType(NodeClass<?> node) {
         return node.getJavaClass();
     }
@@ -257,6 +265,13 @@
             }
             props.put("category", "floating");
         }
+        if (getSnippetReflectionProvider() != null) {
+            for (Map.Entry<String, Object> prop : props.entrySet()) {
+                if (prop.getValue() instanceof JavaConstantFormattable) {
+                    props.put(prop.getKey(), ((JavaConstantFormattable) prop.getValue()).format(this));
+                }
+            }
+        }
     }
 
     private Object getBlockForNode(Node node, NodeMap<Block> nodeToBlocks) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,13 +23,13 @@
 package org.graalvm.compiler.printer;
 
 import static org.graalvm.compiler.debug.DebugOptions.PrintCFG;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.createDumpPath;
 
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -153,8 +153,8 @@
 
         if (cfgPrinter == null) {
             try {
-                Graph graph = debug.contextLookupTopdown(Graph.class);
-                cfgFile = createDumpPath(options, graph, "cfg", false).toFile();
+                Path dumpFile = debug.getDumpPath(".cfg", false);
+                cfgFile = dumpFile.toFile();
                 OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile));
                 cfgPrinter = new CFGPrinter(out);
             } catch (IOException e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CanonicalStringGraphPrinter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -26,7 +26,6 @@
 import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsExcludeVirtuals;
 import static org.graalvm.compiler.debug.DebugOptions.CanonicalGraphStringsRemoveIdentities;
 import static org.graalvm.compiler.debug.DebugOptions.PrintCanonicalGraphStringFlavor;
-import static org.graalvm.compiler.printer.GraalDebugHandlersFactory.sanitizedFileName;
 
 import java.io.BufferedWriter;
 import java.io.FileWriter;
@@ -44,6 +43,7 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.core.common.Fields;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.PathUtilities;
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeMap;
@@ -260,11 +260,11 @@
     private StructuredGraph currentGraph;
     private Path currentDirectory;
 
-    private Path getDirectory(StructuredGraph graph) throws IOException {
+    private Path getDirectory(DebugContext debug, StructuredGraph graph) {
         if (graph == currentGraph) {
             return currentDirectory;
         }
-        currentDirectory = GraalDebugHandlersFactory.createDumpPath(graph.getOptions(), graph, "graph-strings", true);
+        currentDirectory = debug.getDumpPath(".graph-strings", true);
         currentGraph = graph;
         return currentDirectory;
     }
@@ -274,9 +274,9 @@
         if (graph instanceof StructuredGraph) {
             OptionValues options = graph.getOptions();
             StructuredGraph structuredGraph = (StructuredGraph) graph;
-            Path outDirectory = getDirectory(structuredGraph);
+            Path outDirectory = getDirectory(debug, structuredGraph);
             String title = String.format("%03d-%s.txt", id, String.format(format, simplifyClassArgs(args)));
-            Path filePath = outDirectory.resolve(sanitizedFileName(title));
+            Path filePath = outDirectory.resolve(PathUtilities.sanitizeFileName(title));
             try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filePath.toFile())))) {
                 switch (PrintCanonicalGraphStringFlavor.getValue(options)) {
                     case 1:
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraalDebugHandlersFactory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,44 +22,18 @@
  */
 package org.graalvm.compiler.printer;
 
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.PrintBinaryGraphs;
-import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
-import static org.graalvm.compiler.debug.DebugOptions.PrintXmlGraphPort;
-import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.nio.channels.ClosedByInterruptException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.core.common.CompilationIdentifier;
-import org.graalvm.compiler.debug.Assertions;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugDumpHandler;
 import org.graalvm.compiler.debug.DebugHandler;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugOptions;
 import org.graalvm.compiler.debug.TTY;
-import org.graalvm.compiler.debug.PathUtilities;
-import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
@@ -80,17 +54,13 @@
     @Override
     public List<DebugHandler> createHandlers(OptionValues options) {
         List<DebugHandler> handlers = new ArrayList<>();
-        if (DebugOptions.PrintGraphFile.getValue(options)) {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createFilePrinter(graph, options, snippetReflection)));
-        } else {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createNetworkPrinter(graph, options, snippetReflection)));
-        }
+        handlers.add(new GraphPrinterDumpHandler((debug, graph) -> new BinaryGraphPrinter(debug, snippetReflection)));
         if (DebugOptions.PrintCanonicalGraphStrings.getValue(options)) {
-            handlers.add(new GraphPrinterDumpHandler((graph) -> createStringPrinter(snippetReflection)));
+            handlers.add(new GraphPrinterDumpHandler((debug, graph) -> createStringPrinter(snippetReflection)));
         }
         handlers.add(new NodeDumper());
         if (DebugOptions.PrintCFG.getValue(options) || DebugOptions.PrintBackendCFG.getValue(options)) {
-            if (DebugOptions.PrintBinaryGraphs.getValue(options) && DebugOptions.PrintCFG.getValue(options)) {
+            if (DebugOptions.PrintCFG.getValue(options)) {
                 TTY.out.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -Dgraal.PrintCFG=false to disable it");
             }
             handlers.add(new CFGPrinterObserver());
@@ -119,162 +89,4 @@
         return new CanonicalStringGraphPrinter(snippetReflection);
     }
 
-    public static String sanitizedFileName(String n) {
-        /*
-         * First ensure that the name does not contain the directory separator (which would be
-         * considered a valid path).
-         */
-        String name = n.replace(File.separatorChar, '_');
-
-        try {
-            Paths.get(name);
-            return name;
-        } catch (InvalidPathException e) {
-            // fall through
-        }
-        StringBuilder buf = new StringBuilder(name.length());
-        for (int i = 0; i < name.length(); i++) {
-            char c = name.charAt(i);
-            try {
-                Paths.get(String.valueOf(c));
-            } catch (InvalidPathException e) {
-                buf.append('_');
-            }
-            buf.append(c);
-        }
-        return buf.toString();
-    }
-
-    private static GraphPrinter createNetworkPrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
-        String host = PrintGraphHost.getValue(options);
-        int port = PrintBinaryGraphs.getValue(options) ? PrintBinaryGraphPort.getValue(options) : PrintXmlGraphPort.getValue(options);
-        try {
-            GraphPrinter printer;
-            if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
-                printer = new BinaryGraphPrinter(SocketChannel.open(new InetSocketAddress(host, port)), snippetReflection);
-            } else {
-                printer = new IdealGraphPrinter(new Socket(host, port).getOutputStream(), true, snippetReflection);
-            }
-            TTY.println("Connected to the IGV on %s:%d", host, port);
-            return printer;
-        } catch (ClosedByInterruptException | InterruptedIOException e) {
-            /*
-             * Interrupts should not count as errors because they may be caused by a cancelled Graal
-             * compilation. ClosedByInterruptException occurs if the SocketChannel could not be
-             * opened. InterruptedIOException occurs if new Socket(..) was interrupted.
-             */
-            return null;
-        } catch (IOException e) {
-            if (!DebugOptions.PrintGraphFile.hasBeenSet(options)) {
-                return createFilePrinter(graph, options, snippetReflection);
-            } else {
-                throw new IOException(String.format("Could not connect to the IGV on %s:%d", host, port), e);
-            }
-        }
-    }
-
-    private static final AtomicInteger unknownCompilationId = new AtomicInteger();
-
-    /**
-     * Creates a new file or directory for dumping based on a given graph and a file extension.
-     *
-     * @param graph a base path name is derived from {@code graph}
-     * @param extension a suffix which if non-null and non-empty added to the end of the returned
-     *            path separated by a {@code "."}
-     * @param createDirectory specifies if this is a request to create a directory instead of a file
-     * @return the created directory or file
-     * @throws IOException if there was an error creating the directory or file
-     */
-    static Path createDumpPath(OptionValues options, Graph graph, String extension, boolean createDirectory) throws IOException {
-        CompilationIdentifier compilationId = CompilationIdentifier.INVALID_COMPILATION_ID;
-        String id = null;
-        String label = null;
-        if (graph instanceof StructuredGraph) {
-            StructuredGraph sgraph = (StructuredGraph) graph;
-            label = getGraphName(sgraph);
-            compilationId = sgraph.compilationId();
-            if (compilationId == CompilationIdentifier.INVALID_COMPILATION_ID) {
-                id = graph.getClass().getSimpleName() + "-" + sgraph.graphId();
-            } else {
-                id = compilationId.toString(CompilationIdentifier.Verbosity.ID);
-            }
-        } else {
-            label = graph == null ? null : graph.name != null ? graph.name : graph.toString();
-            id = "UnknownCompilation-" + unknownCompilationId.incrementAndGet();
-        }
-        String ext = PathUtilities.formatExtension(extension);
-        Path result = createUnique(DebugOptions.getDumpDirectory(options), id, label, ext, createDirectory);
-        if (ShowDumpFiles.getValue(options) || Assertions.assertionsEnabled()) {
-            TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
-        }
-        return result;
-    }
-
-    /**
-     * A maximum file name length supported by most file systems. There is no platform independent
-     * way to get this in Java.
-     */
-    private static final int MAX_FILE_NAME_LENGTH = 255;
-
-    private static final String ELLIPSIS = "...";
-
-    private static Path createUnique(Path dumpDir, String id, String label, String ext, boolean createDirectory) throws IOException {
-        String timestamp = "";
-        for (;;) {
-            int fileNameLengthWithoutLabel = timestamp.length() + ext.length() + id.length() + "[]".length();
-            int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
-            String fileName;
-            if (labelLengthLimit < ELLIPSIS.length()) {
-                // This means `id` is very long
-                String suffix = timestamp + ext;
-                int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), id.length());
-                fileName = sanitizedFileName(id.substring(0, idLengthLimit) + suffix);
-            } else {
-                if (label == null) {
-                    fileName = sanitizedFileName(id + timestamp + ext);
-                } else {
-                    String adjustedLabel = label;
-                    if (label.length() > labelLengthLimit) {
-                        adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
-                    }
-                    fileName = sanitizedFileName(id + '[' + adjustedLabel + ']' + timestamp + ext);
-                }
-            }
-            Path result = dumpDir.resolve(fileName);
-            try {
-                if (createDirectory) {
-                    return Files.createDirectory(result);
-                } else {
-                    return Files.createFile(result);
-                }
-            } catch (FileAlreadyExistsException e) {
-                timestamp = "_" + Long.toString(System.currentTimeMillis());
-            }
-        }
-    }
-
-    private static String getGraphName(StructuredGraph graph) {
-        if (graph.name != null) {
-            return graph.name;
-        } else if (graph.method() != null) {
-            return graph.method().format("%h.%n(%p)").replace(" ", "");
-        } else {
-            return graph.toString();
-        }
-    }
-
-    private static GraphPrinter createFilePrinter(Graph graph, OptionValues options, SnippetReflectionProvider snippetReflection) throws IOException {
-        Path path = createDumpPath(options, graph, PrintBinaryGraphs.getValue(options) ? "bgv" : "gv.xml", false);
-        try {
-            GraphPrinter printer;
-            if (DebugOptions.PrintBinaryGraphs.getValue(options)) {
-                printer = new BinaryGraphPrinter(FileChannel.open(path, StandardOpenOption.WRITE), snippetReflection);
-            } else {
-                printer = new IdealGraphPrinter(Files.newOutputStream(path), true, snippetReflection);
-            }
-            return printer;
-        } catch (IOException e) {
-            throw new IOException(String.format("Failed to open %s to dump IGV graphs", path), e);
-        }
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.util.JavaConstantFormatter;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.serviceprovider.JDK9Method;
 
@@ -46,7 +47,7 @@
 import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.services.Services;
 
-interface GraphPrinter extends Closeable {
+interface GraphPrinter extends Closeable, JavaConstantFormatter {
 
     /**
      * Starts a new group of graphs with the given name, short name and method byte code index (BCI)
@@ -116,30 +117,44 @@
                 return true;
             }
         }
+        if (c.getClassLoader() == GraphPrinter.class.getClassLoader()) {
+            return true;
+        }
         return false;
     }
 
     /**
+     * Use the real {@link Object#toString()} method for {@link JavaConstant JavaConstants} that are
+     * wrapping trusted types, other just return the results of {@link JavaConstant#toString()}.
+     */
+    @Override
+    default String format(JavaConstant constant) {
+        SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
+        if (snippetReflection != null) {
+            if (constant.getJavaKind() == JavaKind.Object) {
+                Object obj = snippetReflection.asObject(Object.class, constant);
+                if (obj != null) {
+                    return GraphPrinter.constantToString(obj);
+                }
+            }
+        }
+        return constant.toString();
+    }
+
+    /**
      * Sets or updates the {@code "rawvalue"} and {@code "toString"} properties in {@code props} for
      * {@code cn} if it's a boxed Object value and {@code snippetReflection} can access the raw
      * value.
      */
     default void updateStringPropertiesForConstant(Map<Object, Object> props, ConstantNode cn) {
-        SnippetReflectionProvider snippetReflection = getSnippetReflectionProvider();
-        if (snippetReflection != null && cn.getValue() instanceof JavaConstant) {
-            JavaConstant constant = (JavaConstant) cn.getValue();
-            if (constant.getJavaKind() == JavaKind.Object) {
-                Object obj = snippetReflection.asObject(Object.class, constant);
-                if (obj != null) {
-                    String toString = GraphPrinter.constantToString(obj);
-                    String rawvalue = GraphPrinter.truncate(toString);
-                    // Overwrite the value inserted by
-                    // ConstantNode.getDebugProperties()
-                    props.put("rawvalue", rawvalue);
-                    if (!rawvalue.equals(toString)) {
-                        props.put("toString", toString);
-                    }
-                }
+        if (cn.isJavaConstant() && cn.getStackKind().isObject()) {
+            String toString = format(cn.asJavaConstant());
+            String rawvalue = GraphPrinter.truncate(toString);
+            // Overwrite the value inserted by
+            // ConstantNode.getDebugProperties()
+            props.put("rawvalue", rawvalue);
+            if (!rawvalue.equals(toString)) {
+                props.put("toString", toString);
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -52,8 +52,8 @@
 //JaCoCo Exclude
 
 /**
- * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
- * that can be inspected with the Graph Visualizer.
+ * Observes compilation events and uses {@link BinaryGraphPrinter} to generate a graph
+ * representation that can be inspected with the Graph Visualizer.
  */
 public class GraphPrinterDumpHandler implements DebugDumpHandler {
 
@@ -69,7 +69,7 @@
 
     @FunctionalInterface
     public interface GraphPrinterSupplier {
-        GraphPrinter get(Graph graph) throws IOException;
+        GraphPrinter get(DebugContext ctx, Graph graph) throws IOException;
     }
 
     /**
@@ -93,7 +93,7 @@
         }
     }
 
-    private void ensureInitialized(Graph graph) {
+    private void ensureInitialized(DebugContext ctx, Graph graph) {
         if (printer == null) {
             if (failuresCount >= FAILURE_LIMIT) {
                 return;
@@ -102,7 +102,7 @@
             inlineContextMap = new WeakHashMap<>();
             DebugContext debug = graph.getDebug();
             try {
-                printer = printerSupplier.get(graph);
+                printer = printerSupplier.get(ctx, graph);
             } catch (IOException e) {
                 handleException(debug, e);
             }
@@ -123,7 +123,7 @@
         OptionValues options = debug.getOptions();
         if (object instanceof Graph && DebugOptions.PrintGraph.getValue(options)) {
             final Graph graph = (Graph) object;
-            ensureInitialized(graph);
+            ensureInitialized(debug, graph);
             if (printer == null) {
                 return;
             }
@@ -168,11 +168,13 @@
             // Save inline context for next dump.
             previousInlineContext = inlineContext;
 
+            // Capture before creating the sandbox
+            String currentScopeName = debug.getCurrentScopeName();
             try (DebugContext.Scope s = debug.sandbox("PrintingGraph", null)) {
                 // Finally, output the graph.
                 Map<Object, Object> properties = new HashMap<>();
                 properties.put("graph", graph.toString());
-                properties.put("scope", debug.getCurrentScopeName());
+                properties.put("scope", currentScopeName);
                 if (graph instanceof StructuredGraph) {
                     properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId());
                     try {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/IdealGraphPrinter.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2011, 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.printer;
-
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.bytecode.BytecodeDisassembler;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugOptions;
-import org.graalvm.compiler.graph.Graph;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.NodeMap;
-import org.graalvm.compiler.graph.Position;
-import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
-import org.graalvm.compiler.nodes.BeginNode;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.EndNode;
-import org.graalvm.compiler.nodes.ParameterNode;
-import org.graalvm.compiler.nodes.PhiNode;
-import org.graalvm.compiler.nodes.StateSplit;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
-import org.graalvm.compiler.nodes.cfg.Block;
-import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.util.EconomicSet;
-import org.graalvm.util.Equivalence;
-
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-/**
- * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the
- * <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
- */
-public class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter {
-
-    private final boolean tryToSchedule;
-    private final SnippetReflectionProvider snippetReflection;
-
-    /**
-     * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
-     *
-     * @param tryToSchedule If false, no scheduling is done, which avoids exceptions for
-     *            non-schedulable graphs.
-     */
-    public IdealGraphPrinter(OutputStream stream, boolean tryToSchedule, SnippetReflectionProvider snippetReflection) {
-        super(stream);
-        this.snippetReflection = snippetReflection;
-        this.begin();
-        this.tryToSchedule = tryToSchedule;
-    }
-
-    @Override
-    public SnippetReflectionProvider getSnippetReflectionProvider() {
-        return snippetReflection;
-    }
-
-    /**
-     * Starts a new group of graphs with the given name, short name and method byte code index (BCI)
-     * as properties.
-     */
-    @Override
-    public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) {
-        beginGroup();
-        beginProperties();
-        printProperty("name", name);
-        if (properties != null) {
-            for (Entry<Object, Object> entry : properties.entrySet()) {
-                printProperty(entry.getKey().toString(), entry.getValue().toString());
-            }
-        }
-        endProperties();
-        beginMethod(name, shortName, bci);
-        if (method != null && method.getCode() != null) {
-            printBytecodes(new BytecodeDisassembler(false).disassemble(method));
-        }
-        endMethod();
-    }
-
-    /**
-     * Prints an entire {@link Graph} with the specified title, optionally using short names for
-     * nodes.
-     */
-    @Override
-    public void print(DebugContext debug, Graph graph, Map<Object, Object> properties, int id, String format, Object... args) {
-        String title = id + ": " + String.format(format, simplifyClassArgs(args));
-        beginGraph(title);
-        EconomicSet<Node> noBlockNodes = EconomicSet.create(Equivalence.IDENTITY);
-        ScheduleResult schedule = null;
-        if (graph instanceof StructuredGraph) {
-            StructuredGraph structuredGraph = (StructuredGraph) graph;
-            schedule = structuredGraph.getLastSchedule();
-            if (schedule == null && tryToSchedule) {
-                OptionValues options = graph.getOptions();
-                if (DebugOptions.PrintGraphWithSchedule.getValue(options)) {
-                    try {
-                        SchedulePhase schedulePhase = new SchedulePhase(options);
-                        schedulePhase.apply(structuredGraph);
-                        schedule = structuredGraph.getLastSchedule();
-                    } catch (Throwable t) {
-                    }
-                }
-            }
-        }
-        ControlFlowGraph cfg = schedule == null ? null : schedule.getCFG();
-
-        if (properties != null) {
-            beginProperties();
-            for (Entry<Object, Object> entry : properties.entrySet()) {
-                printProperty(entry.getKey().toString(), entry.getValue().toString());
-            }
-            endProperties();
-        }
-
-        beginNodes();
-        List<Edge> edges = printNodes(graph, cfg == null ? null : cfg.getNodeToBlock(), noBlockNodes);
-        endNodes();
-
-        beginEdges();
-        for (Edge edge : edges) {
-            printEdge(edge);
-        }
-        endEdges();
-
-        if (cfg != null && cfg.getBlocks() != null) {
-            beginControlFlow();
-            for (Block block : cfg.getBlocks()) {
-                printBlock(graph, block, cfg.getNodeToBlock());
-            }
-            printNoBlock(noBlockNodes);
-            endControlFlow();
-        }
-
-        endGraph();
-        flush();
-    }
-
-    private List<Edge> printNodes(Graph graph, NodeMap<Block> nodeToBlock, EconomicSet<Node> noBlockNodes) {
-        ArrayList<Edge> edges = new ArrayList<>();
-
-        NodeMap<Set<Entry<String, Integer>>> colors = graph.createNodeMap();
-        NodeMap<Set<Entry<String, String>>> colorsToString = graph.createNodeMap();
-        NodeMap<Set<String>> bits = graph.createNodeMap();
-
-        for (Node node : graph.getNodes()) {
-
-            beginNode(node.toString(Verbosity.Id));
-            beginProperties();
-            printProperty("idx", node.toString(Verbosity.Id));
-
-            Map<Object, Object> props = node.getDebugProperties();
-            if (!props.containsKey("name") || props.get("name").toString().trim().length() == 0) {
-                String name = node.toString(Verbosity.Name);
-                printProperty("name", name);
-            }
-            printProperty("class", node.getClass().getSimpleName());
-
-            Block block = nodeToBlock == null || nodeToBlock.isNew(node) ? null : nodeToBlock.get(node);
-            if (block != null) {
-                printProperty("block", Integer.toString(block.getId()));
-                // if (!(node instanceof PhiNode || node instanceof FrameState || node instanceof
-                // ParameterNode) && !block.nodes().contains(node)) {
-                // printProperty("notInOwnBlock", "true");
-                // }
-            } else {
-                printProperty("block", "noBlock");
-                noBlockNodes.add(node);
-            }
-
-            Set<Entry<String, Integer>> nodeColors = colors.get(node);
-            if (nodeColors != null) {
-                for (Entry<String, Integer> color : nodeColors) {
-                    String name = color.getKey();
-                    Integer value = color.getValue();
-                    printProperty(name, Integer.toString(value));
-                }
-            }
-            Set<Entry<String, String>> nodeColorStrings = colorsToString.get(node);
-            if (nodeColorStrings != null) {
-                for (Entry<String, String> color : nodeColorStrings) {
-                    String name = color.getKey();
-                    String value = color.getValue();
-                    printProperty(name, value);
-                }
-            }
-            Set<String> nodeBits = bits.get(node);
-            if (nodeBits != null) {
-                for (String bit : nodeBits) {
-                    printProperty(bit, "true");
-                }
-            }
-            if (node instanceof BeginNode) {
-                printProperty("shortName", "B");
-            } else if (node.getClass() == EndNode.class) {
-                printProperty("shortName", "E");
-            } else if (node instanceof ConstantNode) {
-                ConstantNode cn = (ConstantNode) node;
-                updateStringPropertiesForConstant(props, cn);
-            }
-            if (node.predecessor() != null) {
-                printProperty("hasPredecessor", "true");
-            }
-
-            try {
-                printProperty("NodeCost-Size", node.estimatedNodeSize().toString());
-                printProperty("NodeCost-Cycles", node.estimatedNodeCycles().toString());
-            } catch (Throwable t) {
-                props.put("node-cost-exception", t.getMessage());
-            }
-
-            for (Entry<Object, Object> entry : props.entrySet()) {
-                String key = entry.getKey().toString();
-                Object value = entry.getValue();
-                String valueString;
-                if (value == null) {
-                    valueString = "null";
-                } else {
-                    Class<?> type = value.getClass();
-                    if (type.isArray()) {
-                        if (!type.getComponentType().isPrimitive()) {
-                            valueString = Arrays.toString((Object[]) value);
-                        } else if (type.getComponentType() == Integer.TYPE) {
-                            valueString = Arrays.toString((int[]) value);
-                        } else if (type.getComponentType() == Double.TYPE) {
-                            valueString = Arrays.toString((double[]) value);
-                        } else {
-                            valueString = toString();
-                        }
-                    } else {
-                        valueString = value.toString();
-                    }
-                }
-                printProperty(key, valueString);
-            }
-
-            endProperties();
-            endNode();
-
-            // successors
-            int fromIndex = 0;
-            for (Position position : node.successorPositions()) {
-                Node successor = position.get(node);
-                if (successor != null) {
-                    edges.add(new Edge(node.toString(Verbosity.Id), fromIndex, successor.toString(Verbosity.Id), 0, position.getName()));
-                }
-                fromIndex++;
-            }
-
-            // inputs
-            int toIndex = 1;
-            for (Position position : node.inputPositions()) {
-                Node input = position.get(node);
-                if (input != null) {
-                    edges.add(new Edge(input.toString(Verbosity.Id), input.successors().count(), node.toString(Verbosity.Id), toIndex, position.getName()));
-                }
-                toIndex++;
-            }
-        }
-
-        return edges;
-    }
-
-    private void printBlock(Graph graph, Block block, NodeMap<Block> nodeToBlock) {
-        beginBlock(Integer.toString(block.getId()));
-        beginSuccessors();
-        for (Block sux : block.getSuccessors()) {
-            if (sux != null) {
-                printSuccessor(Integer.toString(sux.getId()));
-            }
-        }
-        endSuccessors();
-        beginBlockNodes();
-
-        EconomicSet<Node> nodes = EconomicSet.create(Equivalence.IDENTITY);
-
-        if (nodeToBlock != null) {
-            for (Node n : graph.getNodes()) {
-                Block blk = nodeToBlock.isNew(n) ? null : nodeToBlock.get(n);
-                if (blk == block) {
-                    nodes.add(n);
-                }
-            }
-        }
-
-        if (nodes.size() > 0) {
-            // if this is the first block: add all locals to this block
-            if (block.getBeginNode() == ((StructuredGraph) graph).start()) {
-                for (Node node : graph.getNodes()) {
-                    if (node instanceof ParameterNode) {
-                        nodes.add(node);
-                    }
-                }
-            }
-
-            EconomicSet<Node> snapshot = EconomicSet.create(Equivalence.IDENTITY, nodes);
-            // add all framestates and phis to their blocks
-            for (Node node : snapshot) {
-                if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
-                    nodes.add(((StateSplit) node).stateAfter());
-                }
-                if (node instanceof AbstractMergeNode) {
-                    for (PhiNode phi : ((AbstractMergeNode) node).phis()) {
-                        nodes.add(phi);
-                    }
-                }
-            }
-
-            for (Node node : nodes) {
-                printBlockNode(node.toString(Verbosity.Id));
-            }
-        }
-        endBlockNodes();
-        endBlock();
-    }
-
-    private void printNoBlock(EconomicSet<Node> noBlockNodes) {
-        if (!noBlockNodes.isEmpty()) {
-            beginBlock("noBlock");
-            beginBlockNodes();
-            for (Node node : noBlockNodes) {
-                printBlockNode(node.toString(Verbosity.Id));
-            }
-            endBlockNodes();
-            endBlock();
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringIndexOfNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,13 +22,13 @@
  */
 package org.graalvm.compiler.replacements.amd64;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -44,7 +44,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
 
-@NodeInfo(size = SIZE_64, cycles = CYCLES_256)
+@NodeInfo(size = SIZE_64, cycles = NodeCycles.CYCLES_UNKNOWN)
 public class AMD64StringIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess {
     public static final NodeClass<AMD64StringIndexOfNode> TYPE = NodeClass.create(AMD64StringIndexOfNode.class);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Thu Nov 16 12:15:55 2017 +0000
@@ -63,7 +63,7 @@
                      * This is a node from another graph, so copy over extra state into a new
                      * ConstantNode.
                      */
-                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.asConstant(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
+                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.getValue(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
                 } else {
                     constantNode = otherCon;
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Thu Nov 16 12:15:55 2017 +0000
@@ -33,6 +33,7 @@
 import static org.graalvm.compiler.nodes.java.ArrayLengthNode.readArrayLength;
 import static org.graalvm.compiler.nodes.util.GraphUtil.skipPiWhileNonNull;
 
+import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.List;
@@ -43,6 +44,7 @@
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
+import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.TypeReference;
@@ -50,6 +52,7 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FieldLocationIdentity;
 import org.graalvm.compiler.nodes.FixedNode;
@@ -69,6 +72,7 @@
 import org.graalvm.compiler.nodes.calc.RightShiftNode;
 import org.graalvm.compiler.nodes.calc.SignExtendNode;
 import org.graalvm.compiler.nodes.calc.SubNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
 import org.graalvm.compiler.nodes.debug.VerifyHeapNode;
 import org.graalvm.compiler.nodes.extended.BoxNode;
@@ -150,14 +154,16 @@
     protected final MetaAccessProvider metaAccess;
     protected final ForeignCallsProvider foreignCalls;
     protected final TargetDescription target;
+    private final boolean useCompressedOops;
 
     private BoxingSnippets.Templates boxingSnippets;
     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
 
-    public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target) {
+    public DefaultJavaLoweringProvider(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, TargetDescription target, boolean useCompressedOops) {
         this.metaAccess = metaAccess;
         this.foreignCalls = foreignCalls;
         this.target = target;
+        this.useCompressedOops = useCompressedOops;
     }
 
     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
@@ -218,11 +224,18 @@
             lowerBinaryMath((BinaryMathIntrinsicNode) n, tool);
         } else if (n instanceof StringIndexOfNode) {
             lowerIndexOf((StringIndexOfNode) n);
+        } else if (n instanceof UnpackEndianHalfNode) {
+            lowerSecondHalf((UnpackEndianHalfNode) n);
         } else {
             throw GraalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n);
         }
     }
 
+    private void lowerSecondHalf(UnpackEndianHalfNode n) {
+        ByteOrder byteOrder = target.arch.getByteOrder();
+        n.lower(byteOrder);
+    }
+
     private void lowerIndexOf(StringIndexOfNode n) {
         if (n.getArgument(3).isConstant()) {
             SnippetLowering lowering = new SnippetLowering() {
@@ -326,19 +339,21 @@
         }
     }
 
+    protected abstract JavaKind getStorageKind(ResolvedJavaField field);
+
     protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) {
         assert loadField.getStackKind() != JavaKind.Illegal;
         StructuredGraph graph = loadField.graph();
         ResolvedJavaField field = loadField.field();
         ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
         object = createNullCheckedValue(object, loadField, tool);
-        Stamp loadStamp = loadStamp(loadField.stamp(), field.getJavaKind());
+        Stamp loadStamp = loadStamp(loadField.stamp(), getStorageKind(field));
 
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName();
 
         ReadNode memoryRead = graph.add(new ReadNode(address, fieldLocationIdentity(field), loadStamp, fieldLoadBarrierType(field)));
-        ValueNode readValue = implicitLoadConvert(graph, field.getJavaKind(), memoryRead);
+        ValueNode readValue = implicitLoadConvert(graph, getStorageKind(field), memoryRead);
         loadField.replaceAtUsages(readValue);
         graph.replaceFixed(loadField, memoryRead);
 
@@ -355,7 +370,7 @@
         ResolvedJavaField field = storeField.field();
         ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object();
         object = createNullCheckedValue(object, storeField, tool);
-        ValueNode value = implicitStoreConvert(graph, storeField.field().getJavaKind(), storeField.value());
+        ValueNode value = implicitStoreConvert(graph, getStorageKind(storeField.field()), storeField.value());
         AddressNode address = createFieldAddress(graph, object, field);
         assert address != null;
 
@@ -651,9 +666,7 @@
 
     protected void lowerJavaWriteNode(JavaWriteNode write) {
         StructuredGraph graph = write.graph();
-        JavaKind valueKind = write.getWriteKind();
-        ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible());
-
+        ValueNode value = implicitStoreConvert(graph, write.getWriteKind(), write.value(), write.isCompressible());
         WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getLocationIdentity(), value, write.getBarrierType()));
         memoryWrite.setStateAfter(write.stateAfter());
         graph.replaceFixedWithFixed(write, memoryWrite);
@@ -918,10 +931,20 @@
         return loadStamp(stamp, kind, true);
     }
 
+    private boolean useCompressedOops(JavaKind kind, boolean compressible) {
+        return kind == JavaKind.Object && compressible && useCompressedOops;
+    }
+
+    protected abstract Stamp loadCompressedStamp(ObjectStamp stamp);
+
     /**
      * @param compressible whether the stamp should be compressible
      */
     protected Stamp loadStamp(Stamp stamp, JavaKind kind, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return loadCompressedStamp((ObjectStamp) stamp);
+        }
+
         switch (kind) {
             case Boolean:
             case Byte:
@@ -949,10 +972,16 @@
         return ret;
     }
 
+    protected abstract ValueNode newCompressionNode(CompressionOp op, ValueNode value);
+
     /**
-     * @param compressible whether the covert should be compressible
+     * @param compressible whether the convert should be compressible
      */
     protected ValueNode implicitLoadConvert(JavaKind kind, ValueNode value, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return newCompressionNode(CompressionOp.Uncompress, value);
+        }
+
         switch (kind) {
             case Byte:
             case Short:
@@ -984,6 +1013,10 @@
      * @param compressible whether the covert should be compressible
      */
     protected ValueNode implicitStoreConvert(JavaKind kind, ValueNode value, boolean compressible) {
+        if (useCompressedOops(kind, compressible)) {
+            return newCompressionNode(CompressionOp.Compress, value);
+        }
+
         switch (kind) {
             case Boolean:
             case Byte:
@@ -1011,9 +1044,8 @@
         LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength);
         if (boundsCheck.isTautology()) {
             return null;
-        } else {
-            return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
         }
+        return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
     }
 
     protected GuardingNode createNullCheck(ValueNode object, FixedNode before, LoweringTool tool) {
@@ -1027,9 +1059,8 @@
         GuardingNode nullCheck = createNullCheck(object, before, tool);
         if (nullCheck == null) {
             return object;
-        } else {
-            return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
         }
+        return before.graph().maybeAddOrUnique(PiNode.create(object, (object.stamp()).join(StampFactory.objectNonNull()), (ValueNode) nullCheck));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java	Thu Nov 16 12:15:55 2017 +0000
@@ -75,7 +75,6 @@
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Signature;
 
 /**
@@ -252,6 +251,10 @@
         return new MethodCallTargetNode(invokeKind, targetMethod, args, returnStamp, null);
     }
 
+    protected final JavaKind asKind(JavaType type) {
+        return wordTypes != null ? wordTypes.asKind(type) : type.getJavaKind();
+    }
+
     /**
      * Determines if a given set of arguments is compatible with the signature of a given method.
      *
@@ -267,14 +270,12 @@
         }
         int argIndex = 0;
         if (!isStatic) {
-            ResolvedJavaType expectedType = method.getDeclaringClass();
-            JavaKind expected = wordTypes == null ? expectedType.getJavaKind() : wordTypes.asKind(expectedType);
+            JavaKind expected = asKind(method.getDeclaringClass());
             JavaKind actual = args[argIndex++].stamp().getStackKind();
             assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
         }
         for (int i = 0; i != signature.getParameterCount(false); i++) {
-            JavaType expectedType = signature.getParameterType(i, method.getDeclaringClass());
-            JavaKind expected = wordTypes == null ? expectedType.getJavaKind().getStackKind() : wordTypes.asKind(expectedType).getStackKind();
+            JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
             JavaKind actual = args[argIndex++].stamp().getStackKind();
             if (expected != actual) {
                 throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -433,13 +433,14 @@
                 }
 
                 IntrinsicContext initialIntrinsicContext = null;
-                if (method.getAnnotation(Snippet.class) == null) {
+                Snippet snippetAnnotation = method.getAnnotation(Snippet.class);
+                if (snippetAnnotation == null) {
                     // Post-parse inlined intrinsic
                     initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, bytecodeProvider, INLINE_AFTER_PARSING);
                 } else {
                     // Snippet
                     ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method;
-                    initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING);
+                    initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING, snippetAnnotation.allowPartialIntrinsicArgumentMismatch());
                 }
 
                 createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -93,12 +93,7 @@
      */
     @Override
     public int compareTo(SnippetCounter o) {
-        if (value > o.value) {
-            return -1;
-        } else if (o.value < value) {
-            return 1;
-        }
-        return 0;
+        return Long.signum(o.value - value);
     }
 
     private final Group group;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetIntegerHistogram.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,153 @@
+/*
+ * 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.replacements;
+
+/**
+ * A histogram that can (only) be {@linkplain #inc(long) incremented} from within a snippet for
+ * gathering snippet specific metrics.
+ */
+public final class SnippetIntegerHistogram {
+    private final SnippetCounter.Group group;
+    private final String name;
+
+    private final SnippetCounter counter0;
+    private final SnippetCounter counter1;
+    private final SnippetCounter counter2;
+    private final SnippetCounter counter3;
+    private final SnippetCounter counter4;
+    private final SnippetCounter counter5;
+    private final SnippetCounter counter6;
+    private final SnippetCounter counter7;
+    private final SnippetCounter counter8;
+    private final SnippetCounter counter9;
+    private final SnippetCounter counter10;
+
+    private final int counter0UpperBound;
+    private final int counter1UpperBound;
+    private final int counter2UpperBound;
+    private final int counter3UpperBound;
+    private final int counter4UpperBound;
+    private final int counter5UpperBound;
+    private final int counter6UpperBound;
+    private final int counter7UpperBound;
+    private final int counter8UpperBound;
+    private final int counter9UpperBound;
+
+    public SnippetIntegerHistogram(SnippetCounter.Group group, int log2StepLength, String name, String description) {
+        assert log2StepLength > 0;
+
+        this.group = group;
+        this.name = name;
+
+        int lowerBound = 0;
+        counter0UpperBound = 0;
+        counter0 = createCounter(group, name, description, lowerBound, counter0UpperBound);
+
+        lowerBound = counter0UpperBound + 1;
+        counter1UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter1 = createCounter(group, name, description, lowerBound, counter1UpperBound);
+
+        lowerBound = counter1UpperBound + 1;
+        counter2UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter2 = createCounter(group, name, description, lowerBound, counter2UpperBound);
+
+        lowerBound = counter2UpperBound + 1;
+        counter3UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter3 = createCounter(group, name, description, lowerBound, counter3UpperBound);
+
+        lowerBound = counter3UpperBound + 1;
+        counter4UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter4 = createCounter(group, name, description, lowerBound, counter4UpperBound);
+
+        lowerBound = counter4UpperBound + 1;
+        counter5UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter5 = createCounter(group, name, description, lowerBound, counter5UpperBound);
+
+        lowerBound = counter5UpperBound + 1;
+        counter6UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter6 = createCounter(group, name, description, lowerBound, counter6UpperBound);
+
+        lowerBound = counter6UpperBound + 1;
+        counter7UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter7 = createCounter(group, name, description, lowerBound, counter7UpperBound);
+
+        lowerBound = counter7UpperBound + 1;
+        counter8UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter8 = createCounter(group, name, description, lowerBound, counter8UpperBound);
+
+        lowerBound = counter8UpperBound + 1;
+        counter9UpperBound = Math.max(1, lowerBound - 1) << log2StepLength;
+        counter9 = createCounter(group, name, description, lowerBound, counter9UpperBound);
+
+        lowerBound = counter9UpperBound + 1;
+        counter10 = createCounter(group, name, description, lowerBound, Long.MAX_VALUE);
+    }
+
+    private static SnippetCounter createCounter(SnippetCounter.Group group, String name, String description, long lowerBound, long upperBound) {
+        if (group != null) {
+            SnippetCounter snippetCounter = new SnippetCounter(group, name + "[" + lowerBound + ", " + upperBound + "]", description);
+            return snippetCounter;
+        }
+        return null;
+    }
+
+    /**
+     * Increments the value of the matching histogram element. This method can only be used in a
+     * snippet on a compile-time constant {@link SnippetIntegerHistogram} object.
+     */
+    public void inc(long value) {
+        if (group != null) {
+            if (value <= counter0UpperBound) {
+                counter0.inc();
+            } else if (value <= counter1UpperBound) {
+                counter1.inc();
+            } else if (value <= counter2UpperBound) {
+                counter2.inc();
+            } else if (value <= counter3UpperBound) {
+                counter3.inc();
+            } else if (value <= counter4UpperBound) {
+                counter4.inc();
+            } else if (value <= counter5UpperBound) {
+                counter5.inc();
+            } else if (value <= counter6UpperBound) {
+                counter6.inc();
+            } else if (value <= counter7UpperBound) {
+                counter7.inc();
+            } else if (value <= counter8UpperBound) {
+                counter8.inc();
+            } else if (value <= counter9UpperBound) {
+                counter9.inc();
+            } else {
+                counter10.inc();
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (group != null) {
+            return "SnippetHistogram-" + group.name + ":" + name;
+        }
+        return super.toString();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,15 +23,15 @@
 package org.graalvm.compiler.replacements.nodes;
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1024;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1024;
 
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodeinfo.NodeSize;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.NamedLocationIdentity;
@@ -57,7 +57,7 @@
 /**
  * Compares two arrays with the same length.
  */
-@NodeInfo(cycles = CYCLES_1024, size = SIZE_1024)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
 public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
 
     public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicArrayCopyNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,7 +24,6 @@
 
 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.InputType.State;
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
 import static org.graalvm.word.LocationIdentity.any;
 
@@ -32,6 +31,7 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.DeoptimizingNode;
@@ -56,7 +56,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(cycles = CYCLES_256, size = SIZE_64)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_64)
 public class BasicArrayCopyNode extends AbstractMemoryCheckpoint implements Virtualizable, MemoryCheckpoint.Single, MemoryAccess, Lowerable, DeoptimizingNode.DeoptDuring {
 
     public static final NodeClass<BasicArrayCopyNode> TYPE = NodeClass.create(BasicArrayCopyNode.class);
@@ -215,7 +215,7 @@
                         return;
                     }
                     for (int i = 0; i < len; i++) {
-                        tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i), false);
+                        tool.setVirtualEntry(destVirtual, destPosInt + i, tool.getEntry(srcVirtual, srcPosInt + i));
                     }
                     tool.delete();
                     DebugContext debug = getDebug();
@@ -235,7 +235,7 @@
                     for (int i = 0; i < len; i++) {
                         LoadIndexedNode load = new LoadIndexedNode(graph().getAssumptions(), srcAlias, ConstantNode.forInt(i + srcPosInt, graph()), destComponentType.getJavaKind());
                         tool.addNode(load);
-                        tool.setVirtualEntry(destVirtual, destPosInt + i, load, false);
+                        tool.setVirtualEntry(destVirtual, destPosInt + i, load);
                     }
                     tool.delete();
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -22,7 +22,6 @@
  */
 package org.graalvm.compiler.replacements.nodes;
 
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
 
 import java.util.Collections;
@@ -32,6 +31,7 @@
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
 import org.graalvm.compiler.nodes.ValueNode;
@@ -49,7 +49,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
+@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = SIZE_8)
 public abstract class BasicObjectCloneNode extends MacroStateSplitNode implements VirtualizableAllocation, ArrayLengthProvider {
 
     public static final NodeClass<BasicObjectCloneNode> TYPE = NodeClass.create(BasicObjectCloneNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BinaryMathIntrinsicNode.java	Thu Nov 16 12:15:55 2017 +0000
@@ -37,7 +37,7 @@
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.BinaryNode;
-import org.graalvm.compiler.nodes.calc.DivNode;
+import org.graalvm.compiler.nodes.calc.FloatDivNode;
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.calc.SqrtNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
@@ -141,7 +141,7 @@
 
             // x**-1 = 1/x
             if (yValue == -1.0D) {
-                return new DivNode(ConstantNode.forDouble(1), x);
+                return new FloatDivNode(ConstantNode.forDouble(1), x);
             }
 
             // x**2 = x*x
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -36,6 +36,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
 import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.debug.DebugDumpHandler;
@@ -392,6 +393,20 @@
      * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
      */
     protected DebugContext getDebugContext(OptionValues options) {
+        return getDebugContext(options, null, null);
+    }
+
+    /**
+     * Gets a {@link DebugContext} object corresponding to {@code options}, creating a new one if
+     * none currently exists.Debug contexts created by this method will have their
+     * {@link DebugDumpHandler}s closed in {@link #afterTest()}.
+     *
+     * @param options currently active options
+     * @param id identification of the compilation or {@code null}
+     * @param method method to use for a proper description of the context or {@code null}
+     * @return configured context for compilation
+     */
+    protected DebugContext getDebugContext(OptionValues options, String id, ResolvedJavaMethod method) {
         List<DebugContext> cached = cachedDebugs.get();
         if (cached == null) {
             cached = new ArrayList<>();
@@ -402,7 +417,13 @@
                 return debug;
             }
         }
-        DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
+        final DebugContext.Description descr;
+        if (method == null) {
+            descr = NO_DESCRIPTION;
+        } else {
+            descr = new DebugContext.Description(method, id == null ? method.getName() : id);
+        }
+        DebugContext debug = DebugContext.create(options, descr, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, getDebugHandlersFactories());
         cached.add(debug);
         return debug;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectList.java	Thu Nov 16 12:15:55 2017 +0000
@@ -171,9 +171,14 @@
     }
 
     public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes, boolean cfgKills) {
+        boolean message = false;
         for (int i = 0; i < size(); i++) {
             Effect effect = effects[i];
             if (effect.isCfgKill() == cfgKills) {
+                if (!message) {
+                    message = true;
+                    debug.log(cfgKills ? " ==== cfg kill effects" : " ==== effects");
+                }
                 try {
                     effect.apply(graph, obsoleteNodes);
                 } catch (Throwable t) {
@@ -202,7 +207,7 @@
                     // Inner classes could capture the EffectList itself.
                     continue;
                 }
-                str.append(first ? "" : ", ").append(format(object));
+                str.append(first ? "" : ", ").append(field.getName()).append("=").append(format(object));
                 first = false;
             } catch (SecurityException | IllegalAccessException e) {
                 throw new RuntimeException(e);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java	Thu Nov 16 12:15:55 2017 +0000
@@ -184,7 +184,6 @@
         };
         ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
         for (GraphEffectList effects : effectList) {
-            debug.log(" ==== effects");
             effects.apply(graph, obsoleteNodes, false);
         }
         /*
@@ -193,7 +192,6 @@
          * indexes.
          */
         for (GraphEffectList effects : effectList) {
-            debug.log(" ==== cfg kill effects");
             effects.apply(graph, obsoleteNodes, true);
         }
         debug.dump(DebugContext.DETAILED_LEVEL, graph, "After applying effects");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Thu Nov 16 12:15:55 2017 +0000
@@ -99,8 +99,8 @@
                             closure.applyEffects();
                         }
 
-                        if (debug.isDumpEnabled(DebugContext.INFO_LEVEL)) {
-                            debug.dump(DebugContext.DETAILED_LEVEL, graph, "%s iteration", getName());
+                        if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
+                            debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
                         }
 
                         new DeadCodeEliminationPhase(Required).apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/ObjectState.java	Thu Nov 16 12:15:55 2017 +0000
@@ -68,6 +68,7 @@
     }
 
     public ObjectState(ValueNode[] entries, LockState locks, boolean ensureVirtualized) {
+        assert checkIllegalValues(entries);
         this.entries = entries;
         this.locks = locks;
         this.ensureVirtualized = ensureVirtualized;
@@ -92,6 +93,30 @@
         return new ObjectState(this);
     }
 
+    /**
+     * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+     * value is a double word value.
+     */
+    public static boolean checkIllegalValues(ValueNode[] values) {
+        if (values != null) {
+            for (int v = 1; v < values.length; v++) {
+                checkIllegalValue(values, v);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Ensure that if an {@link JavaConstant#forIllegal() illegal value} is seen that the previous
+     * value is a double word value.
+     */
+    public static boolean checkIllegalValue(ValueNode[] values, int v) {
+        if (v > 0 && values[v].isConstant() && values[v].asConstant().equals(JavaConstant.forIllegal())) {
+            assert values[v - 1].getStackKind().needsTwoSlots();
+        }
+        return true;
+    }
+
     public EscapeObjectState createEscapeObjectState(DebugContext debug, VirtualObjectNode virtual) {
         GET_ESCAPED_OBJECT_STATE.increment(debug);
         if (cachedState == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java	Thu Nov 16 12:15:55 2017 +0000
@@ -854,6 +854,7 @@
                                 ValueNode nextValue = objectState.getEntry(valueIndex + 1);
                                 if (value.isConstant() && value.asConstant().equals(JavaConstant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(JavaConstant.INT_0)) {
                                     // rewrite to a zero constant of the larger kind
+                                    debug.log("Rewriting entry %s to constant of larger size", valueIndex);
                                     states[i].setEntry(object, valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], graph()));
                                     states[i].setEntry(object, valueIndex + 1, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()));
                                 } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/VirtualizerToolImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -30,18 +30,22 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
+import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.calc.UnpackEndianHalfNode;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.MetaAccessProvider;
 
@@ -58,6 +62,7 @@
     private final OptionValues options;
     private final DebugContext debug;
     private final LoweringProvider loweringProvider;
+    private ConstantNode illegalConstant;
 
     VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, PartialEscapeClosure<?> closure,
                     Assumptions assumptions, OptionValues options, DebugContext debug, LoweringProvider loweringProvider) {
@@ -125,17 +130,81 @@
     }
 
     @Override
-    public void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, boolean unsafe) {
+    public boolean setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value, JavaKind theAccessKind, long offset) {
         ObjectState obj = state.getObjectState(virtual);
         assert obj.isVirtual() : "not virtual: " + obj;
         ValueNode newValue;
+        JavaKind entryKind = virtual.entryKind(index);
+        JavaKind accessKind = theAccessKind != null ? theAccessKind : entryKind;
         if (value == null) {
             newValue = null;
         } else {
             newValue = closure.getAliasAndResolve(state, value);
-            assert unsafe || obj.getEntry(index) == null || obj.getEntry(index).getStackKind() == newValue.getStackKind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
+        }
+        getDebug().log(DebugContext.DETAILED_LEVEL, "Setting entry %d in virtual object %s %s results in %s", index, virtual.getObjectId(), virtual, state.getObjectState(virtual.getObjectId()));
+        ValueNode oldValue = getEntry(virtual, index);
+        boolean canVirtualize = entryKind == accessKind || (entryKind == accessKind.getStackKind() && virtual instanceof VirtualInstanceNode);
+        if (!canVirtualize) {
+            if (entryKind == JavaKind.Long && oldValue.getStackKind() == newValue.getStackKind() && oldValue.getStackKind().isPrimitive()) {
+                /*
+                 * Special case: If the entryKind is long, allow arbitrary kinds as long as a value
+                 * of the same kind is already there. This can only happen if some other node
+                 * initialized the entry with a value of a different kind. One example where this
+                 * happens is the Truffle NewFrameNode.
+                 */
+                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s with primitive of kind %s in long entry ", current, oldValue.getStackKind());
+                canVirtualize = true;
+            } else if (entryKind == JavaKind.Int && (accessKind == JavaKind.Long || accessKind == JavaKind.Double) && offset % 8 == 0) {
+                /*
+                 * Special case: Allow storing a single long or double value into two consecutive
+                 * int slots.
+                 */
+                int nextIndex = virtual.entryIndexForOffset(offset + 4, JavaKind.Int);
+                if (nextIndex != -1) {
+                    canVirtualize = true;
+                    assert nextIndex == index + 1 : "expected to be sequential";
+                    getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for double word stored in two ints", current);
+                }
+            }
         }
-        state.setEntry(virtual.getObjectId(), index, newValue);
+
+        if (canVirtualize) {
+            getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s for entryKind %s and access kind %s", current, entryKind, accessKind);
+            state.setEntry(virtual.getObjectId(), index, newValue);
+            if (entryKind == JavaKind.Int) {
+                if (accessKind.needsTwoSlots()) {
+                    // Storing double word value two int slots
+                    assert virtual.entryKind(index + 1) == JavaKind.Int;
+                    state.setEntry(virtual.getObjectId(), index + 1, getIllegalConstant());
+                } else if (oldValue.getStackKind() == JavaKind.Double || oldValue.getStackKind() == JavaKind.Long) {
+                    // Splitting double word constant by storing over it with an int
+                    getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing second half of double word value %s", current, oldValue);
+                    ValueNode secondHalf = UnpackEndianHalfNode.create(oldValue, false);
+                    addNode(secondHalf);
+                    state.setEntry(virtual.getObjectId(), index + 1, secondHalf);
+                }
+            }
+            if (oldValue.isConstant() && oldValue.asConstant().equals(JavaConstant.forIllegal())) {
+                // Storing into second half of double, so replace previous value
+                ValueNode previous = getEntry(virtual, index - 1);
+                getDebug().log(DebugContext.DETAILED_LEVEL, "virtualizing %s producing first half of double word value %s", current, previous);
+                ValueNode firstHalf = UnpackEndianHalfNode.create(previous, true);
+                addNode(firstHalf);
+                state.setEntry(virtual.getObjectId(), index - 1, firstHalf);
+            }
+            return true;
+        }
+        // Should only occur if there are mismatches between the entry and access kind
+        assert entryKind != accessKind;
+        return false;
+    }
+
+    private ValueNode getIllegalConstant() {
+        if (illegalConstant == null) {
+            illegalConstant = ConstantNode.forConstant(JavaConstant.forIllegal(), getMetaAccessProvider());
+            addNode(illegalConstant);
+        }
+        return illegalConstant;
     }
 
     @Override
@@ -149,10 +218,6 @@
         return state.getObjectState(virtualObject).getEnsureVirtualized();
     }
 
-    private static boolean isObjectEntry(ValueNode value) {
-        return value.getStackKind() == JavaKind.Object || value instanceof VirtualObjectNode;
-    }
-
     @Override
     public void replaceWithVirtual(VirtualObjectNode virtual) {
         closure.addVirtualAlias(virtual, current);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Thu Nov 16 12:15:55 2017 +0000
@@ -113,12 +113,30 @@
         private GraphElements<M, ?, ?, ?> elements = null;
         private GraphTypes types = DefaultGraphTypes.DEFAULT;
         private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty();
+        private int major = 4;
+        private int minor = 0;
 
         Builder(GraphStructure<G, N, ?, ?> structure) {
             this.structure = structure;
         }
 
         /**
+         * Chooses which version of the protocol to use. The default version is <code>4.0</code>
+         * (when the {@link GraphOutput} & co. classes were introduced). The default can be changed
+         * to other known versions manually by calling this method.
+         *
+         * @param majorVersion by default 4, newer version may be known
+         * @param minorVersion usually 0
+         * @return this builder
+         * @since 0.28
+         */
+        public Builder<G, N, M> protocolVersion(int majorVersion, int minorVersion) {
+            this.major = majorVersion;
+            this.minor = minorVersion;
+            return this;
+        }
+
+        /**
          * Associates different implementation of types.
          *
          * @param graphTypes implementation of types and enum recognition
@@ -161,7 +179,28 @@
          * @throws IOException if something goes wrong when writing to the channel
          */
         public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException {
-            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(structure, types, blocks, elements, channel);
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(major, minor, structure, types, blocks, elements, channel);
+            return new GraphOutput<>(p);
+        }
+
+        /**
+         * Support for nesting heterogenous graphs. The newly created output uses all the interfaces
+         * currently associated with this builder, but shares with {@code parent} the output
+         * {@code channel}, internal constant pool and {@link #protocolVersion(int, int) protocol
+         * version}.
+         * <p>
+         * Both GraphOutput (the {@code parent} and the returned one) has to be used in
+         * synchronization - e.g. only one
+         * {@link #beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map)
+         * begin}, {@link #endGroup() end} of group or
+         * {@link #print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...)
+         * printing} can be on at a given moment.
+         *
+         * @param parent the output to inherit {@code channel} and protocol version from
+         * @return new output sharing {@code channel} and other internals with {@code parent}
+         */
+        public GraphOutput<G, M> build(GraphOutput<?, ?> parent) {
+            ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(parent.printer, structure, types, blocks, elements);
             return new GraphOutput<>(p);
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Thu Nov 16 12:15:55 2017 +0000
@@ -52,6 +52,7 @@
     private static final int POOL_FIELD = 0x07;
     private static final int POOL_SIGNATURE = 0x08;
     private static final int POOL_NODE_SOURCE_POSITION = 0x09;
+    private static final int POOL_NODE = 0x0a;
 
     private static final int PROPERTY_POOL = 0x00;
     private static final int PROPERTY_INT = 0x01;
@@ -71,19 +72,12 @@
     private final ConstantPool constantPool;
     private final ByteBuffer buffer;
     private final WritableByteChannel channel;
-    private final int versionMajor;
-    private final int versionMinor;
-
-    protected GraphProtocol(WritableByteChannel channel) throws IOException {
-        this(channel, 4, 0);
-    }
+    final int versionMajor;
+    final int versionMinor;
 
-    private GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
-        if (major > 4) {
-            throw new IllegalArgumentException();
-        }
-        if (major == 4 && minor > 0) {
-            throw new IllegalArgumentException();
+    GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException {
+        if (major > 5 || (major == 5 && minor > 0)) {
+            throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
         }
         this.versionMajor = major;
         this.versionMinor = minor;
@@ -93,6 +87,14 @@
         writeVersion();
     }
 
+    GraphProtocol(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent) {
+        this.versionMajor = parent.versionMajor;
+        this.versionMinor = parent.versionMinor;
+        this.constantPool = parent.constantPool;
+        this.buffer = parent.buffer;
+        this.channel = parent.channel;
+    }
+
     @SuppressWarnings("all")
     public final void print(Graph graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException {
         writeByte(BEGIN_GRAPH);
@@ -137,9 +139,33 @@
 
     protected abstract ResolvedJavaMethod findMethod(Object obj);
 
+    /**
+     * Attempts to recognize the provided object as a node. Used to encode it with
+     * {@link #POOL_NODE} pool type.
+     *
+     * @param obj any object
+     * @return <code>null</code> if it is not a node object, non-null otherwise
+     */
+    protected abstract Node findNode(Object obj);
+
+    /**
+     * Determines whether the provided object is node class or not.
+     *
+     * @param obj object to check
+     * @return {@code null} if {@code obj} does not represent a NodeClass otherwise the NodeClass
+     *         represented by {@code obj}
+     */
     protected abstract NodeClass findNodeClass(Object obj);
 
     /**
+     * Returns the NodeClass for a given Node {@code obj}.
+     *
+     * @param obj instance of node
+     * @return non-{@code null} instance of the node's class object
+     */
+    protected abstract NodeClass findClassForNode(Node obj);
+
+    /**
      * Find a Java class. The returned object must be acceptable by
      * {@link #findJavaTypeName(java.lang.Object)} and return valid name for the class.
      *
@@ -239,7 +265,7 @@
     private void flush() throws IOException {
         buffer.flip();
         /*
-         * Try not to let interrupted threads aborting the write. There's still a race here but an
+         * Try not to let interrupted threads abort the write. There's still a race here but an
          * interrupt that's been pending for a long time shouldn't stop this writing.
          */
         boolean interrupted = Thread.interrupted();
@@ -338,7 +364,8 @@
         }
     }
 
-    private void writePoolObject(Object object) throws IOException {
+    private void writePoolObject(Object obj) throws IOException {
+        Object object = obj;
         if (object == null) {
             writeByte(POOL_NULL);
             return;
@@ -347,23 +374,31 @@
         if (id == null) {
             addPoolEntry(object);
         } else {
-            if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
-                writeByte(POOL_ENUM);
-            } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
-                writeByte(POOL_CLASS);
-            } else if (findJavaField(object) != null) {
+            if (findJavaField(object) != null) {
                 writeByte(POOL_FIELD);
             } else if (findSignature(object) != null) {
                 writeByte(POOL_SIGNATURE);
             } else if (versionMajor >= 4 && findNodeSourcePosition(object) != null) {
                 writeByte(POOL_NODE_SOURCE_POSITION);
             } else {
+                final Node node = findNode(object);
+                if (versionMajor == 4 && node != null) {
+                    object = classForNode(node);
+                }
                 if (findNodeClass(object) != null) {
                     writeByte(POOL_NODE_CLASS);
+                } else if (versionMajor >= 5 && node != null) {
+                    writeByte(POOL_NODE);
                 } else if (findMethod(object) != null) {
                     writeByte(POOL_METHOD);
                 } else {
-                    writeByte(POOL_STRING);
+                    if (object instanceof Enum<?> || findEnumOrdinal(object) >= 0) {
+                        writeByte(POOL_ENUM);
+                    } else if (object instanceof Class<?> || findJavaTypeName(object) != null) {
+                        writeByte(POOL_CLASS);
+                    } else {
+                        writeByte(POOL_STRING);
+                    }
                 }
             }
             writeShort(id.charValue());
@@ -383,10 +418,7 @@
         writeInt(size);
         int cnt = 0;
         for (Node node : findNodes(info)) {
-            NodeClass nodeClass = findNodeClass(node);
-            if (nodeClass == null) {
-                throw new IOException("No class for " + node);
-            }
+            NodeClass nodeClass = classForNode(node);
             findNodeProperties(node, props, info);
 
             writeInt(findNodeId(node));
@@ -405,7 +437,7 @@
     }
 
     private void writeEdges(Graph graph, Node node, boolean dumpInputs) throws IOException {
-        NodeClass clazz = findNodeClass(node);
+        NodeClass clazz = classForNode(node);
         Edges edges = findClassEdges(clazz, dumpInputs);
         int size = findSize(edges);
         for (int i = 0; i < size; i++) {
@@ -434,6 +466,14 @@
         }
     }
 
+    private NodeClass classForNode(Node node) throws IOException {
+        NodeClass clazz = findClassForNode(node);
+        if (clazz == null) {
+            throw new IOException("No class for " + node);
+        }
+        return clazz;
+    }
+
     private void writeNodeRef(Node node) throws IOException {
         writeInt(findNodeId(node));
     }
@@ -480,7 +520,8 @@
     }
 
     @SuppressWarnings("all")
-    private void addPoolEntry(Object object) throws IOException {
+    private void addPoolEntry(Object obj) throws IOException {
+        Object object = obj;
         ResolvedJavaField field;
         String typeName;
         Signature signature;
@@ -489,24 +530,7 @@
         char index = constantPool.add(object);
         writeByte(POOL_NEW);
         writeShort(index);
-        if ((typeName = findJavaTypeName(object)) != null) {
-            writeByte(POOL_CLASS);
-            writeString(typeName);
-            String[] enumValueNames = findEnumTypeValues(object);
-            if (enumValueNames != null) {
-                writeByte(ENUM_KLASS);
-                writeInt(enumValueNames.length);
-                for (String o : enumValueNames) {
-                    writePoolObject(o);
-                }
-            } else {
-                writeByte(KLASS);
-            }
-        } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
-            writeByte(POOL_ENUM);
-            writePoolObject(findEnumClass(object));
-            writeInt(enumOrdinal);
-        } else if ((field = findJavaField(object)) != null) {
+        if ((field = findJavaField(object)) != null) {
             writeByte(POOL_FIELD);
             writePoolObject(findFieldDeclaringClass(field));
             writePoolObject(findFieldName(field));
@@ -535,6 +559,18 @@
             }
             writePoolObject(findNodeSourcePositionCaller(pos));
         } else {
+            Node node = findNode(object);
+            if (node != null) {
+                if (versionMajor >= 5) {
+                    writeByte(POOL_NODE);
+                    writeInt(findNodeId(node));
+                    writePoolObject(classForNode(node));
+                    return;
+                }
+                if (versionMajor == 4) {
+                    object = classForNode(node);
+                }
+            }
             NodeClass nodeClass = findNodeClass(object);
             if (nodeClass != null) {
                 writeByte(POOL_NODE_CLASS);
@@ -553,8 +589,27 @@
             }
             ResolvedJavaMethod method = findMethod(object);
             if (method == null) {
-                writeByte(POOL_STRING);
-                writeString(object.toString());
+                if ((typeName = findJavaTypeName(object)) != null) {
+                    writeByte(POOL_CLASS);
+                    writeString(typeName);
+                    String[] enumValueNames = findEnumTypeValues(object);
+                    if (enumValueNames != null) {
+                        writeByte(ENUM_KLASS);
+                        writeInt(enumValueNames.length);
+                        for (String o : enumValueNames) {
+                            writePoolObject(o);
+                        }
+                    } else {
+                        writeByte(KLASS);
+                    }
+                } else if ((enumOrdinal = findEnumOrdinal(object)) >= 0) {
+                    writeByte(POOL_ENUM);
+                    writePoolObject(findEnumClass(object));
+                    writeInt(enumOrdinal);
+                } else {
+                    writeByte(POOL_STRING);
+                    writeString(object.toString());
+                }
                 return;
             }
             writeByte(POOL_METHOD);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphSnippets.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,285 @@
+/*
+ * 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.graphio;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+final class GraphSnippets {
+    static GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> acmeGraphStructure() {
+        // @formatter:off
+        // BEGIN: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+        class AcmeGraphStructure implements
+        GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> {
+
+            @Override
+            public AcmeGraph graph(AcmeGraph currentGraph, Object obj) {
+                return obj instanceof AcmeGraph ? (AcmeGraph) obj : null;
+            }
+
+            @Override
+            public Iterable<? extends AcmeNode> nodes(AcmeGraph graph) {
+                return graph.allNodes();
+            }
+
+            @Override
+            public int nodesCount(AcmeGraph graph) {
+                return graph.allNodes().size();
+            }
+
+            @Override
+            public int nodeId(AcmeNode node) {
+                return node.id;
+            }
+
+            @Override
+            public boolean nodeHasPredecessor(AcmeNode node) {
+                return node.id > 0;
+            }
+
+            @Override
+            public void nodeProperties(
+                AcmeGraph graph, AcmeNode node, Map<String, ? super Object> properties
+            ) {
+                properties.put("id", node.id);
+            }
+
+            @Override
+            public AcmeNodeType nodeClass(Object obj) {
+                return obj instanceof AcmeNodeType ? (AcmeNodeType) obj : null;
+            }
+
+            @Override
+            public AcmeNode node(Object obj) {
+                return obj instanceof AcmeNode ? (AcmeNode) obj : null;
+            }
+
+            @Override
+            public AcmeNodeType classForNode(AcmeNode node) {
+                // we have only one type of nodes
+                return AcmeNodeType.STANDARD;
+            }
+
+
+            @Override
+            public String nameTemplate(AcmeNodeType nodeClass) {
+                return "Acme ({p#id})";
+            }
+
+            @Override
+            public Object nodeClassType(AcmeNodeType nodeClass) {
+                return nodeClass.getClass();
+            }
+
+            @Override
+            public AcmePorts portInputs(AcmeNodeType nodeClass) {
+                return AcmePorts.INPUT;
+            }
+
+            @Override
+            public AcmePorts portOutputs(AcmeNodeType nodeClass) {
+                return AcmePorts.OUTPUT;
+            }
+
+            @Override
+            public int portSize(AcmePorts port) {
+                return port == AcmePorts.OUTPUT ? 1 : 0;
+            }
+
+            @Override
+            public boolean edgeDirect(AcmePorts port, int index) {
+                return false;
+            }
+
+            @Override
+            public String edgeName(AcmePorts port, int index) {
+                return port.name();
+            }
+
+            @Override
+            public Object edgeType(AcmePorts port, int index) {
+                return port;
+            }
+
+            @Override
+            public Collection<? extends AcmeNode> edgeNodes(
+                AcmeGraph graph, AcmeNode node, AcmePorts port, int index
+            ) {
+                if (port == AcmePorts.OUTPUT) {
+                    return node.outgoing.targets;
+                }
+                return null;
+            }
+        }
+
+        // END: org.graalvm.graphio.GraphSnippets#acmeGraphStructure
+
+        return new AcmeGraphStructure();
+    }
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#buildOutput
+    static GraphOutput<AcmeGraph, ?> buildOutput(WritableByteChannel channel)
+    throws IOException {
+        return GraphOutput.newBuilder(acmeGraphStructure()).
+            // use the latest version; currently 5.0
+            protocolVersion(5, 0).
+            build(channel);
+    }
+    // END: org.graalvm.graphio.GraphSnippets#buildOutput
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#buildAll
+    static GraphOutput<AcmeGraph, ?> buildAll(WritableByteChannel channel)
+    throws IOException {
+        GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = acmeBlocks();
+        GraphElements<AcmeMethod, AcmeField,
+            AcmeSignature, AcmeCodePosition> graphElements = acmeElements();
+        GraphTypes graphTypes = acmeTypes();
+
+        return GraphOutput.newBuilder(acmeGraphStructure()).
+            protocolVersion(5, 0).
+            blocks(graphBlocks).
+            elements(graphElements).
+            types(graphTypes).
+            build(channel);
+    }
+    // END: org.graalvm.graphio.GraphSnippets#buildAll
+
+    private static GraphTypes acmeTypes() {
+        GraphTypes graphTypes = null;
+        // in real world don't return null
+        return graphTypes;
+    }
+
+    private static GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> acmeElements() {
+        GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> graphElements = null;
+        // in real world don't return null
+        return graphElements;
+    }
+
+    private static GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> acmeBlocks() {
+        GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = null;
+        // in real world don't return null
+        return graphBlocks;
+    }
+
+    private static class AcmeGraph {
+        final AcmeNode root;
+
+        AcmeGraph(AcmeNode root) {
+            this.root = root;
+        }
+
+        Set<AcmeNode> allNodes() {
+            return allNodes(root, new LinkedHashSet<>());
+        }
+
+        private static Set<AcmeNode> allNodes(AcmeNode node, Set<AcmeNode> collectTo) {
+            if (collectTo.add(node)) {
+                for (AcmeNode target : node.outgoing.targets) {
+                    allNodes(target, collectTo);
+                }
+            }
+            return collectTo;
+        }
+    }
+
+    private static class AcmeNode {
+        final int id;
+        final AcmeEdges outgoing;
+
+        AcmeNode(int id) {
+            this.id = id;
+            this.outgoing = new AcmeEdges();
+        }
+
+        void linkTo(AcmeNode target) {
+            outgoing.targets.add(target);
+        }
+    }
+
+    private enum AcmeNodeType {
+        STANDARD
+    }
+
+    private enum AcmePorts {
+        INPUT,
+        OUTPUT;
+    }
+
+    private static class AcmeEdges {
+        final Set<AcmeNode> targets;
+
+        AcmeEdges() {
+            this.targets = new LinkedHashSet<>();
+        }
+    }
+
+    private static class AcmeBlocks {
+    }
+
+    private static class AcmeMethod {
+    }
+
+    private static class AcmeField {
+    }
+
+    private static class AcmeSignature {
+    }
+
+    private static class AcmeCodePosition {
+    }
+
+    // BEGIN: org.graalvm.graphio.GraphSnippets#dump
+    static void dump(File toFile) throws IOException {
+        try (
+            FileChannel ch = new FileOutputStream(toFile).getChannel();
+            GraphOutput<AcmeGraph, ?> output = buildOutput(ch);
+        ) {
+            AcmeNode root = new AcmeNode(0);
+            AcmeNode n1 = new AcmeNode(1);
+            AcmeNode n2 = new AcmeNode(2);
+            AcmeNode n3 = new AcmeNode(3);
+
+            root.linkTo(n1);
+            root.linkTo(n2);
+            n1.linkTo(n3);
+            n2.linkTo(n3);
+
+            AcmeGraph diamondGraph = new AcmeGraph(root);
+
+            output.beginGroup(diamondGraph, "Diamond", "dia", null, 0, null);
+            output.print(diamondGraph, null, 0, "Diamond graph #%d", 1);
+            output.endGroup();
+        }
+    }
+    // END: org.graalvm.graphio.GraphSnippets#dump
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphStructure.java	Thu Nov 16 12:15:55 2017 +0000
@@ -38,9 +38,9 @@
  */
 public interface GraphStructure<G, N, C, P> {
     /**
-     * Casts the provided object to graph, if possible. If the given object <code>obj</code> can be
-     * seen as a graph or sub-graph of a graph, then return the properly typed instance. Otherwise
-     * return <code>null</code>
+     * Casts {@code obj} to graph, if possible. If the given object <code>obj</code> can be seen as
+     * a graph or sub-graph of a graph, then return the properly typed instance. Otherwise return
+     * <code>null</code>
      *
      * @param currentGraph the currently processed graph
      * @param obj an object to check and view as a graph
@@ -69,8 +69,8 @@
     int nodesCount(G graph);
 
     /**
-     * Id of a node. Each node in the graph is uniquely identified by a integer value. If two nodes
-     * have the same id, then they shall be <code>==</code> to each other.
+     * Id of {@code node}. Each node in the graph is uniquely identified by an integer value. If two
+     * nodes have the same id, then they shall be <code>==</code> to each other.
      *
      * @param node the node to query for an id
      * @return the id of the node
@@ -96,16 +96,35 @@
     void nodeProperties(G graph, N node, Map<String, ? super Object> properties);
 
     /**
-     * Finds the node class for the provided object, if possible. If the given object
-     * <code>obj</code> can be seen as an instance of node class or it is a node in this graph,
-     * return the properly typed instance of the node class. Otherwise return <code>null</code>
+     * Finds a node for {@code obj}, if possible. If the given object <code>obj</code> can be seen
+     * as an instance of node return the properly typed instance of the node class. Otherwise return
+     * <code>null</code>.
+     *
+     * @param obj an object to find node for
+     * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+     */
+    N node(Object obj);
+
+    /**
+     * Finds a node class for {@code obj}, if possible. If the given object <code>obj</code> can be
+     * seen as an instance of node class return the properly typed instance of the node class.
+     * Otherwise return <code>null</code>.
      *
      * @param obj an object to find node class for
-     * @return appropriate graph object or <code>null</code> if the object doesn't represent a graph
+     * @return appropriate graph object or <code>null</code> if the object doesn't represent a node
+     *         class
      */
     C nodeClass(Object obj);
 
     /**
+     * Finds a node class for {@code node}.
+     *
+     * @param node an instance of node in this graph
+     * @return the node's node class, never <code>null</code>
+     */
+    C classForNode(N node);
+
+    /**
      * The template used to build the name of nodes of this class. The template may use references
      * to inputs (&#123;i#inputName&#125;) and its properties (&#123;p#propertyName&#125;).
      *
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -34,9 +34,18 @@
     private final GraphBlocks<Graph, Block, Node> blocks;
     private final GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements;
 
-    ProtocolImpl(GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+    ProtocolImpl(int major, int minor, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
                     GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements, WritableByteChannel channel) throws IOException {
-        super(channel);
+        super(channel, major, minor);
+        this.structure = structure;
+        this.types = enums;
+        this.blocks = blocks;
+        this.elements = elements;
+    }
+
+    ProtocolImpl(GraphProtocol<?, ?, ?, ?, ?, ?, ?, ?, ?> parent, GraphStructure<Graph, Node, NodeClass, Port> structure, GraphTypes enums, GraphBlocks<Graph, Block, Node> blocks,
+                    GraphElements<ResolvedJavaMethod, ResolvedJavaField, Signature, NodeSourcePosition> elements) {
+        super(parent);
         this.structure = structure;
         this.types = enums;
         this.blocks = blocks;
@@ -49,11 +58,21 @@
     }
 
     @Override
+    protected Node findNode(Object obj) {
+        return structure.node(obj);
+    }
+
+    @Override
     protected NodeClass findNodeClass(Object obj) {
         return structure.nodeClass(obj);
     }
 
     @Override
+    protected NodeClass findClassForNode(Node obj) {
+        return structure.classForNode(obj);
+    }
+
+    @Override
     protected String findNameTemplate(NodeClass clazz) {
         return structure.nameTemplate(clazz);
     }
Binary file src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/doc-files/diamond.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,86 @@
+
+/*
+ * 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.
+ */
+
+/**
+ * Send your graphs to <b>IGV</b> via a socket or a file. This package allows one to easily encode
+ * any graph-like data structure and send it for visualization to
+ * <em>OracleLab's Ideal Graph Visualizer</em> tool. Assuming you already have your own data
+ * structure that contains <b>nodes</b> and <b>edges</b> among them, creating a
+ * {@link org.graalvm.graphio.GraphOutput} specialized for your data is a matter of implementing a
+ * single interface:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#acmeGraphStructure}
+ *
+ * The {@link org.graalvm.graphio.GraphStructure} interface defines the set of operations that are
+ * needed by the <em>graph protocol</em> to encode a graph into the <b>IGV</b> expected format. The
+ * graph structure is implemented as a so called
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern: there is no
+ * need to change your data structures or implement some special interfaces - everything needed is
+ * provided by implementing the {@link org.graalvm.graphio.GraphStructure} operations.
+ * <p>
+ * The next step is to turn this graph structure into an instance of
+ * {@link org.graalvm.graphio.GraphOutput}. To do so use the associated
+ * {@link org.graalvm.graphio.GraphOutput.Builder builder} just like shown in the following method:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildOutput}
+ *
+ * Now you are ready to dump your graph into <b>IGV</b>. Where to obtain the right channel? One
+ * option is to create a {@link java.nio.channels.FileChannel} and dump the data into a file
+ * (preferrably with <code>.bgv</code> extension). The other is to open a socket to port
+ * <code>4445</code> (the default port <b>IGV</b> listens to) and dump the data there. Here is an
+ * example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#dump}
+ *
+ * Call the {@code dump} method with pointer to file {@code diamond.bgv} and then you can open the
+ * file in <b>IGV</b>. The result will look like this:
+ * <p>
+ * <img src="doc-files/diamond.png">
+ * <p>
+ * You can verify the behavior directly in the <b>IGV</b> by downloading
+ * <a href="doc-files/diamond.bgv">diamond.bgv</a> file generated from the above diamond structure
+ * graph.
+ * <p>
+ * The primary <b>IGV</b> focus is on graphs used by Graal compiler. As such they aren't plain
+ * graphs, but contain various compiler oriented attributes:
+ * <ul>
+ * <li>{@linkplain org.graalvm.graphio.GraphBlocks code blocks} information</li>
+ * <li>{@linkplain org.graalvm.graphio.GraphElements method and fields} information</li>
+ * <li>Advanced support for {@linkplain org.graalvm.graphio.GraphTypes recognizing types}</li>
+ * </ul>
+ * all these additional interfaces ({@link org.graalvm.graphio.GraphBlocks},
+ * {@link org.graalvm.graphio.GraphElements} and {@link org.graalvm.graphio.GraphTypes}) are
+ * optional - they don't have to be provided. As such they can be specified via
+ * {@link org.graalvm.graphio.GraphOutput.Builder} instance methods, which may, but need not be
+ * called at all. Here is an example:
+ *
+ * {@link org.graalvm.graphio.GraphSnippets#buildAll}
+ *
+ * All these interfaces follow the
+ * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern again - e.g.
+ * no need to change your existing data structures, just implement the operations provided by the
+ * interfaces you pass into the builder. By combining these interfaces together you can get as rich,
+ * colorful, source linked graphs as Graal compiler produces to describe its optimizations.
+ */
+package org.graalvm.graphio;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.word/.checkstyle_checks.xml	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: Checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="error"/>
+  <module name="TreeWalker">
+    <module name="AvoidStarImport">
+      <property name="allowClassImports" value="false"/>
+      <property name="allowStaticMemberImports" value="false"/>
+    </module>
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocStyle">
+      <property name="checkHtml" value="false"/>
+    </module>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName">
+      <property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
+    </module>
+    <module name="MethodName"/>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="TypeName">
+      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
+    </module>
+    <module name="RedundantImport"/>
+    <module name="LineLength">
+      <property name="max" value="250"/>
+    </module>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore">
+      <property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad">
+      <property name="tokens" value="RPAREN,TYPECAST"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround">
+      <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
+    </module>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks">
+      <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+      <property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
+    </module>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="EmptyStatement"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+      <property name="ignoreConstructorParameter" value="true"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ArrayTypeStyle"/>
+    <module name="UpperEll"/>
+    <module name="FallThrough"/>
+    <module name="FinalLocalVariable">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="MultipleVariableDeclarations"/>
+    <module name="StringLiteralEquality">
+      <property name="severity" value="error"/>
+    </module>
+    <module name="SuperFinalize"/>
+    <module name="UnnecessaryParentheses">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="Indentation">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="StaticVariableName">
+      <property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
+    </module>
+    <module name="EmptyForInitializerPad"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="ModifierOrder"/>
+    <module name="DefaultComesLast"/>
+    <module name="InnerAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ModifiedControlVariable"/>
+    <module name="MutableException">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="ParameterAssignment">
+      <property name="severity" value="ignore"/>
+      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="format" value="\s$"/>
+      <property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
+      <property name="format" value=" ,"/>
+      <property name="message" value="illegal space before a comma"/>
+      <property name="ignoreComments" value="true"/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
+      <metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="[^\x00-\x7F]"/>
+      <property name="message" value="Only use ASCII characters."/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
+      <property name="message" value="Don't use old synchronized collection classes"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof MoveOp"/>
+      <property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof ValueMoveOp"/>
+      <property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="instanceof LoadConstantOp"/>
+      <property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(MoveOp\)"/>
+      <property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(ValueMoveOp\)"/>
+      <property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
+    </module>
+    <module name="RegexpSinglelineJava">
+      <property name="format" value="\(LoadConstantOp\)"/>
+      <property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
+    </module>
+  </module>
+  <module name="RegexpHeader">
+    <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.  Oracle designates this\n \* particular file as subject to the &quot;Classpath&quot; exception as provided\n \* by Oracle in the LICENSE file that accompanied this code.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="FileTabCharacter">
+    <property name="severity" value="error"/>
+    <property name="fileExtensions" value="java"/>
+  </module>
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
+    <property name="checkFormat" value="ConstantNameCheck"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop method name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume method name check"/>
+    <property name="checkFormat" value="MethodName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
+    <property name="checkFormat" value="ParameterAssignment"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
+    <property name="checkFormat" value="FinalLocalVariable"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop"/>
+    <property name="onCommentFormat" value="Checkstyle: resume"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
+    <property name="checkFormat" value="InnerAssignment"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="Checkstyle: stop field name check"/>
+    <property name="onCommentFormat" value="Checkstyle: resume field name check"/>
+    <property name="checkFormat" value="MemberName"/>
+    <property name="checkC" value="false"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
+  </module>
+  <module name="RegexpMultiline">
+    <metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
+    <property name="format" value="\r\n"/>
+    <property name="message" value="illegal Windows line ending"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop header check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume header check"/>
+    <property name="checkFormat" value=".*Header"/>
+    <metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: stop line length check"/>
+    <property name="onCommentFormat" value="CheckStyle: resume line length check"/>
+    <property name="checkFormat" value="LineLength"/>
+  </module>
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CheckStyle: start generated"/>
+    <property name="onCommentFormat" value="CheckStyle: stop generated"/>
+    <property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
+  </module>
+</module>
--- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java	Thu Nov 16 12:15:55 2017 +0000
@@ -270,7 +270,7 @@
         {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
                 "The %1$s algorithm specified for the %2$s option is considered a security risk."},
         {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
-                "The %s signing key has a keysize of %d which is considered a security risk."},
+                "The %1$s signing key has a keysize of %2$d which is considered a security risk."},
         {"This.jar.contains.entries.whose.certificate.chain.is.invalid.reason.1",
                  "This jar contains entries whose certificate chain is invalid. Reason: %s"},
         {"This.jar.contains.entries.whose.tsa.certificate.chain.is.invalid.reason.1",
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -139,7 +139,7 @@
         head.addContent(windowTitle);
         Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
         head.addContent(meta);
-        head.addContent(getStyleSheetProperties(configuration));
+        addStyleSheetProperties(configuration, head);
         head.addContent(getFramesJavaScript());
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, body);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Thu Nov 16 12:15:55 2017 +0000
@@ -133,6 +133,11 @@
     public String stylesheetfile = "";
 
     /**
+     * Argument for command line option "--add-stylesheet".
+     */
+    public List<String> additionalStylesheets = new ArrayList<>();
+
+    /**
      * Argument for command line option "-Xdocrootparent".
      */
     public String docrootparent = "";
@@ -304,6 +309,22 @@
                 return false;
             }
         }
+        // check if stylesheetfile exists
+        if (!stylesheetfile.isEmpty()) {
+            DocFile stylesheet = DocFile.createFileForInput(this, stylesheetfile);
+            if (!stylesheet.exists()) {
+                reporter.print(ERROR, getText("doclet.File_not_found", stylesheetfile));
+                return false;
+            }
+        }
+        // check if additional stylesheets exists
+        for (String ssheet : additionalStylesheets) {
+            DocFile ssfile = DocFile.createFileForInput(this, ssheet);
+            if (!ssfile.exists()) {
+                reporter.print(ERROR, getText("doclet.File_not_found", ssheet));
+                return false;
+            }
+        }
 
         // In a more object-oriented world, this would be done by methods on the Option objects.
         // Note that -windowtitle silently removes any and all HTML elements, and so does not need
@@ -554,6 +575,13 @@
     public Set<Doclet.Option> getSupportedOptions() {
         Resources resources = getResources();
         Doclet.Option[] options = {
+            new Option(resources, "--add-stylesheet", 1) {
+                @Override
+                public boolean process(String opt, List<String> args) {
+                    additionalStylesheets.add(args.get(0));
+                    return true;
+                }
+            },
             new Option(resources, "-bottom", 1) {
                 @Override
                 public boolean process(String opt,  List<String> args) {
@@ -722,7 +750,7 @@
                     return true;
                 }
             },
-            new Option(resources, "-stylesheetfile", 1) {
+            new Option(resources, "--main-stylesheet -stylesheetfile", 1) {
                 @Override
                 public boolean process(String opt,  List<String> args) {
                     stylesheetfile = args.get(0);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Thu Nov 16 12:15:55 2017 +0000
@@ -125,6 +125,9 @@
         boolean nodeprecated = configuration.nodeprecated;
         performCopy(configuration.helpfile);
         performCopy(configuration.stylesheetfile);
+        for (String stylesheet : configuration.additionalStylesheets) {
+            performCopy(stylesheet);
+        }
         // do early to reduce memory footprint
         if (configuration.classuse) {
             ClassUseWriter.generate(configuration, classtree);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -2162,6 +2162,7 @@
                 pathToRoot.resolve(stylesheet).getPath(),
                 "Style");
         head.addContent(link);
+        addStylesheets(configuration, head);
         if (configuration.createindex) {
             HtmlTree jq_link = HtmlTree.LINK("stylesheet", "text/css",
                     pathToRoot.resolve(DocPaths.JQUERY_FILES.resolve(DocPaths.JQUERY_STYLESHEET_FILE)).getPath(),
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -94,7 +94,7 @@
             head.addContent(metaRefresh);
         }
 
-        head.addContent(getStyleSheetProperties(configuration));
+        addStyleSheetProperties(configuration, head);
 
         ContentBuilder bodyContent = new ContentBuilder();
         bodyContent.addContent(HtmlTree.NOSCRIPT(
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -26,6 +26,7 @@
 package jdk.javadoc.internal.doclets.formats.html;
 
 import java.io.*;
+import java.util.List;
 
 import javax.lang.model.element.Element;
 import javax.lang.model.element.PackageElement;
@@ -210,7 +211,7 @@
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(HtmlTree.TITLE(new StringContent(
                 configuration.getText("doclet.Window_Source_title"))));
-        head.addContent(getStyleSheetProperties());
+        addStyleSheetProperties(head);
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, body);
         Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree);
@@ -227,9 +228,9 @@
     /**
      * Returns a link to the stylesheet file.
      *
-     * @return an HtmlTree for the lINK tag which provides the stylesheet location
+     * @param head an HtmlTree to which the stylesheet links will be added
      */
-    public HtmlTree getStyleSheetProperties() {
+    public void addStyleSheetProperties(Content head) {
         String filename = configuration.stylesheetfile;
         DocPath stylesheet;
         if (filename.length() > 0) {
@@ -240,7 +241,21 @@
         }
         DocPath p = relativePath.resolve(stylesheet);
         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", p.getPath(), "Style");
-        return link;
+        head.addContent(link);
+        addStylesheets(head);
+    }
+
+    protected void addStylesheets(Content tree) {
+        List<String> stylesheets = configuration.additionalStylesheets;
+        if (!stylesheets.isEmpty()) {
+            stylesheets.forEach((ssheet) -> {
+                DocFile file = DocFile.createFileForInput(configuration, ssheet);
+                DocPath ssheetPath = DocPath.create(file.getName());
+                HtmlTree slink = HtmlTree.LINK("stylesheet", "text/css", relativePath.resolve(ssheetPath).getPath(),
+                        "Style");
+                tree.addContent(slink);
+            });
+        }
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Nov 16 12:15:55 2017 +0000
@@ -311,9 +311,9 @@
      * Returns a link to the stylesheet file.
      *
      * @param configuration the configuration for this doclet
-     * @return an HtmlTree for the lINK tag which provides the stylesheet location
+     * @param head HtmlTree to which the stylesheet links will be added
      */
-    public HtmlTree getStyleSheetProperties(HtmlConfiguration configuration) {
+    public void addStyleSheetProperties(HtmlConfiguration configuration, Content head) {
         String stylesheetfile = configuration.stylesheetfile;
         DocPath stylesheet;
         if (stylesheetfile.isEmpty()) {
@@ -325,7 +325,21 @@
         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
                 pathToRoot.resolve(stylesheet).getPath(),
                 "Style");
-        return link;
+        head.addContent(link);
+        addStylesheets(configuration, head);
+    }
+
+    protected void addStylesheets(HtmlConfiguration configuration, Content tree) {
+        List<String> stylesheets = configuration.additionalStylesheets;
+        if (!stylesheets.isEmpty()) {
+            stylesheets.forEach((ssheet) -> {
+                DocFile file = DocFile.createFileForInput(configuration, ssheet);
+                DocPath ssheetPath = DocPath.create(file.getName());
+                HtmlTree slink = HtmlTree.LINK("stylesheet", "text/css", pathToRoot.resolve(ssheetPath).getPath(),
+                        "Style");
+                tree.addContent(slink);
+            });
+        }
     }
 
     protected Comment getGeneratedBy(boolean timestamp) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu Nov 16 12:15:55 2017 +0000
@@ -175,6 +175,10 @@
 doclet.Same_element_name_used=Element name or pattern used twice: {0}
 
 # option specifiers
+doclet.usage.add-stylesheet.parameters=\
+    <file>
+doclet.usage.add-stylesheet.description=\
+    Additional stylesheet file for the generated documentation
 doclet.usage.d.parameters=\
     <directory>
 doclet.usage.d.description=\
@@ -329,9 +333,9 @@
 doclet.usage.keywords.description=\
     Include HTML meta tags with package, class and member info
 
-doclet.usage.stylesheetfile.parameters=\
-    <path>
-doclet.usage.stylesheetfile.description=\
+doclet.usage.main-stylesheet.parameters=\
+    <file>
+doclet.usage.main-stylesheet.description=\
     File to change style of the generated documentation
 
 doclet.usage.docencoding.parameters=\
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Thu Nov 16 12:15:55 2017 +0000
@@ -74,14 +74,16 @@
 
     private final Path file;
     private final String moduleName;
+    private final Runtime.Version version;
     // currently processed JarFile
     private JarFile jarFile;
 
-    protected JarArchive(String mn, Path file) {
+    protected JarArchive(String mn, Path file, Runtime.Version version) {
         Objects.requireNonNull(mn);
         Objects.requireNonNull(file);
         this.moduleName = mn;
         this.file = file;
+        this.version = Objects.requireNonNull(version);
     }
 
     @Override
@@ -126,7 +128,7 @@
         if (jarFile != null) {
             jarFile.close();
         }
-        jarFile = new JarFile(file.toFile(), true, ZipFile.OPEN_READ, JarFile.runtimeVersion());
+        jarFile = new JarFile(file.toFile(), true, ZipFile.OPEN_READ, version);
     }
 
     protected JarFile getJarFile() {
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Nov 16 12:15:55 2017 +0000
@@ -421,6 +421,9 @@
      * the observable modules to those in the transitive closure of
      * the modules specified in {@code limitMods} plus other modules
      * specified in the {@code roots} set.
+     *
+     * @throws IllegalArgumentException if java.base module is present
+     * but its descriptor has no version
      */
     public static ModuleFinder newModuleFinder(List<Path> paths,
                                                Set<String> limitMods,
@@ -429,8 +432,25 @@
         if (Objects.requireNonNull(paths).isEmpty()) {
              throw new IllegalArgumentException("Empty module path");
         }
+
         Path[] entries = paths.toArray(new Path[0]);
-        ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
+        Runtime.Version version = Runtime.version();
+        ModuleFinder finder = ModulePath.of(version, true, entries);
+
+        if (finder.find("java.base").isPresent()) {
+            // use the version of java.base module, if present, as
+            // the release version for multi-release JAR files
+            ModuleDescriptor.Version v = finder.find("java.base").get()
+                .descriptor().version().orElseThrow(() ->
+                    new IllegalArgumentException("No version in java.base descriptor")
+                );
+
+            // java.base version is different than the current runtime version
+            version = Runtime.Version.parse(v.toString());
+            if (Runtime.version().major() != version.major()) {
+                finder = ModulePath.of(version, true, entries);
+            }
+        }
 
         // if limitmods is specified then limit the universe
         if (limitMods != null && !limitMods.isEmpty()) {
@@ -744,6 +764,7 @@
         final ByteOrder order;
         final Path packagedModulesPath;
         final boolean ignoreSigning;
+        final Runtime.Version version;
         final Set<Archive> archives;
 
         ImageHelper(Configuration cf,
@@ -754,6 +775,17 @@
             this.order = order;
             this.packagedModulesPath = packagedModulesPath;
             this.ignoreSigning = ignoreSigning;
+
+            // use the version of java.base module, if present, as
+            // the release version for multi-release JAR files
+            this.version = cf.findModule("java.base")
+                .map(ResolvedModule::reference)
+                .map(ModuleReference::descriptor)
+                .flatMap(ModuleDescriptor::version)
+                .map(ModuleDescriptor.Version::toString)
+                .map(Runtime.Version::parse)
+                .orElse(Runtime.version());
+
             this.archives = modsPaths.entrySet().stream()
                                 .map(e -> newArchive(e.getKey(), e.getValue()))
                                 .collect(Collectors.toSet());
@@ -763,7 +795,7 @@
             if (path.toString().endsWith(".jmod")) {
                 return new JmodArchive(module, path);
             } else if (path.toString().endsWith(".jar")) {
-                ModularJarArchive modularJarArchive = new ModularJarArchive(module, path);
+                ModularJarArchive modularJarArchive = new ModularJarArchive(module, path, version);
 
                 Stream<Archive.Entry> signatures = modularJarArchive.entries().filter((entry) -> {
                     String name = entry.name().toUpperCase(Locale.ENGLISH);
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java	Thu Nov 16 12:15:55 2017 +0000
@@ -39,8 +39,8 @@
     private static final String JAR_EXT = ".jar";
     private static final String MODULE_INFO = "module-info.class";
 
-    public ModularJarArchive(String mn, Path jmod) {
-        super(mn, jmod);
+    public ModularJarArchive(String mn, Path jmod, Runtime.Version version) {
+        super(mn, jmod, version);
         String filename = Objects.requireNonNull(jmod.getFileName()).toString();
         if (!filename.endsWith(JAR_EXT)) {
             throw new UnsupportedOperationException("Unsupported format: " + filename);
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Thu Nov 16 12:15:55 2017 +0000
@@ -242,8 +242,14 @@
         lines.map(line -> line.split(" "))
              .forEach(parts -> {
                 switch (parts[0]) {
-                    case "[BMH_RESOLVE]":
-                        speciesTypes.add(expandSignature(parts[1]));
+                    case "[SPECIES_RESOLVE]":
+                        // Allow for new types of species data classes being resolved here
+                        if (parts.length == 3 && parts[1].startsWith("java.lang.invoke.BoundMethodHandle$Species_")) {
+                            String species = parts[1].substring("java.lang.invoke.BoundMethodHandle$Species_".length());
+                            if (!"L".equals(species)) {
+                                speciesTypes.add(expandSignature(species));
+                            }
+                        }
                         break;
                     case "[LF_RESOLVE]":
                         String methodType = parts[3];
@@ -449,7 +455,7 @@
             "/java.base/" + INVOKERS_HOLDER + ".class";
 
     // Convert LL -> LL, L3 -> LLL
-    private static String expandSignature(String signature) {
+    public static String expandSignature(String signature) {
         StringBuilder sb = new StringBuilder();
         char last = 'X';
         int count = 0;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java	Thu Nov 16 12:15:55 2017 +0000
@@ -76,14 +76,16 @@
 
     @Override
     public String getMethodCallSyntax(final String obj, final String method, final String... args) {
-        final StringBuilder sb = new StringBuilder().append(obj).append('.').append(method).append('(');
+        final StringBuilder sb = new StringBuilder().
+            append(Objects.requireNonNull(obj)).append('.').
+            append(Objects.requireNonNull(method)).append('(');
         final int len = args.length;
 
         if (len > 0) {
-            sb.append(args[0]);
+            sb.append(Objects.requireNonNull(args[0]));
         }
         for (int i = 1; i < len; i++) {
-            sb.append(',').append(args[i]);
+            sb.append(',').append(Objects.requireNonNull(args[i]));
         }
         sb.append(')');
 
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeMath.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeMath.java	Thu Nov 16 12:15:55 2017 +0000
@@ -105,8 +105,8 @@
      * @return abs of argument
      */
     @SpecializedFunction
-    public static int abs(final Object self, final int x) {
-        return Math.abs(x);
+    public static double abs(final Object self, final int x) {
+        return x == Integer.MIN_VALUE? Math.abs((double)x) : Math.abs(x);
     }
 
     /**
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Nov 16 12:15:55 2017 +0000
@@ -2050,7 +2050,7 @@
 
         final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
         setMap(newMap);
-        set(key, value, 0);
+        set(key, value, NashornCallSiteDescriptor.CALLSITE_DECLARE);
     }
 
     /**
@@ -3071,7 +3071,7 @@
         }
 
         if (f != null) {
-            if (!f.getProperty().isWritable() || !f.getProperty().hasNativeSetter()) {
+            if ((!f.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(callSiteFlags)) || !f.getProperty().hasNativeSetter()) {
                 if (isScopeFlag(callSiteFlags) && f.getProperty().isLexicalBinding()) {
                     throw typeError("assign.constant", key.toString()); // Overwriting ES6 const should throw also in non-strict mode.
                 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Nov 16 12:15:55 2017 +0000
@@ -505,6 +505,15 @@
     }
 
     /**
+     * Returns true if {@code flags} has the {@link  #CALLSITE_DECLARE} bit set.
+     * @param flags the flags
+     * @return true if the flag is set, false otherwise.
+     */
+    public static boolean isDeclaration(final int flags) {
+        return (flags & CALLSITE_DECLARE) != 0;
+    }
+
+    /**
      * Get a program point from a descriptor (must be optimistic)
      * @param desc descriptor
      * @return program point
--- a/test/hotspot/gtest/classfile/test_AltHashing.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/classfile/test_AltHashing.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -51,7 +51,7 @@
 class AltHashingTest : public ::testing::Test {
  public:
 
-  static juint murmur3_32(const int* data, int len) {
+  static juint murmur3_32(const jint* data, int len) {
     return AltHashing::murmur3_32(data, len);
   }
 };
--- a/test/hotspot/gtest/logging/logTestFixture.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/logTestFixture.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,11 +22,11 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logTestFixture.hpp"
 #include "logTestUtils.inline.hpp"
 #include "logging/logConfiguration.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 #include "utilities/ostream.hpp"
 
--- a/test/hotspot/gtest/logging/test_log.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_log.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,11 +22,11 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "logTestFixture.hpp"
 #include "logTestUtils.inline.hpp"
 #include "logging/log.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 
 class LogTest : public LogTestFixture {
--- a/test/hotspot/gtest/logging/test_logConfiguration.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logConfiguration.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logTestFixture.hpp"
 #include "logTestUtils.inline.hpp"
 #include "logging/logConfiguration.hpp"
@@ -31,7 +32,6 @@
 #include "logging/logTag.hpp"
 #include "logging/logTagSet.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 #include "utilities/ostream.hpp"
 
--- a/test/hotspot/gtest/logging/test_logDecorators.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logDecorators.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,8 +22,8 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logDecorators.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 
 static LogDecorators::Decorator decorator_array[] = {
--- a/test/hotspot/gtest/logging/test_logFileOutput.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logFileOutput.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,10 +22,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logTestUtils.inline.hpp"
 #include "logging/logFileOutput.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "runtime/os.hpp"
 #include "unittest.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/test/hotspot/gtest/logging/test_logMessageTest.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logMessageTest.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,11 +22,11 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logTestFixture.hpp"
 #include "logTestUtils.inline.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/test/hotspot/gtest/logging/test_logTagLevelExpression.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logTagLevelExpression.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,10 +22,10 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logging/logLevel.hpp"
 #include "logging/logTagLevelExpression.hpp"
 #include "logging/logTagSet.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/logging/test_logTagSetDescriptions.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,12 +22,12 @@
  *
  */
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "logTestUtils.inline.hpp"
 #include "logging/logConfiguration.hpp"
 #include "logging/logTagSet.hpp"
 #include "logging/logTagSetDescriptions.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "unittest.hpp"
 #include "utilities/ostream.hpp"
 
--- a/test/hotspot/gtest/runtime/test_arguments.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/runtime/test_arguments.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,9 +22,9 @@
  */
 
 #include "precompiled.hpp"
-#include "prims/jvm.h"
+#include "jvm.h"
+#include "unittest.hpp"
 #include "runtime/arguments.hpp"
-#include "unittest.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/test/hotspot/gtest/utilities/test_json.cpp	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/gtest/utilities/test_json.cpp	Thu Nov 16 12:15:55 2017 +0000
@@ -22,8 +22,8 @@
  */
 
 #include "precompiled.hpp"
+#include "jvm.h"
 #include "memory/resourceArea.hpp"
-#include "prims/jvm.h"
 #include "utilities/json.hpp"
 #include "unittest.hpp"
 
--- a/test/hotspot/jtreg/ProblemList.txt	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/ProblemList.txt	Thu Nov 16 12:15:55 2017 +0000
@@ -54,6 +54,9 @@
 # aot test intermittently failing in jprt 8175791
 compiler/aot/DeoptimizationTest.java 8175791 windows-all
 
+applications/ctw/modules/java_desktop.java 8189604 windows-all
+applications/ctw/modules/jdk_jconsole.java 8189604 windows-all
+
 #############################################################################
 
 # :hotspot_gc
--- a/test/hotspot/jtreg/TEST.groups	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/TEST.groups	Thu Nov 16 12:15:55 2017 +0000
@@ -107,15 +107,11 @@
   -compiler/loopopts/Test7052494.java \
   -compiler/runtime/Test6826736.java
 
-hotspot_tier1_compiler_closed = \
-  sanity/ExecuteInternalVMTests.java
-
 hotspot_not_fast_compiler = \
   :hotspot_compiler \
   -:hotspot_tier1_compiler_1 \
   -:hotspot_tier1_compiler_2 \
   -:hotspot_tier1_compiler_3 \
-  -:hotspot_tier1_compiler_closed
 
 hotspot_tier1_gc_1 = \
   gc/g1/
@@ -130,9 +126,6 @@
   -gc/cms/TestMBeanCMS.java \
   -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
 
-hotspot_tier1_gc_closed = \
-  sanity/ExecuteInternalVMTests.java
-
 hotspot_tier1_gc_gcold = \
   gc/stress/gcold/TestGCOldWithG1.java
   gc/stress/gcold/TestGCOldWithCMS.java
@@ -204,10 +197,8 @@
   :hotspot_tier1_compiler_1 \
   :hotspot_tier1_compiler_2 \
   :hotspot_tier1_compiler_3 \
-  :hotspot_tier1_compiler_closed \
   :hotspot_tier1_gc_1 \
   :hotspot_tier1_gc_2 \
-  :hotspot_tier1_gc_closed \
   :hotspot_tier1_gc_gcold \
   :hotspot_tier1_runtime \
   :hotspot_tier1_serviceability
--- a/test/hotspot/jtreg/applications/ctw/Modules.java	Thu Nov 16 10:29:18 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test
- * @summary run CTW for all classes from boot "modules" jimage -- lib/modules.
- *
- * @library /test/lib / /testlibrary/ctw/src
- * @modules java.base/jdk.internal.jimage
- *          java.base/jdk.internal.misc
- *          java.base/jdk.internal.reflect
- *
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/timeout=0 sun.hotspot.tools.ctw.CtwRunner modules
- */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/generate.bash	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+#  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.
+#
+
+# generates CTW tests for modules passed as argument
+
+for module in $@
+do
+    file=${module//./_}.java
+    echo creating $file for $module...
+    cat > $file <<EOF
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from $module module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules $module
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox\$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:$module
+ */
+EOF
+
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_activation.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.activation module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.activation
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.activation
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_base.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.base module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.base
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.base
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_compiler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.compiler module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.compiler
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.compiler
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_corba.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.corba module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.corba
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.corba
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_datatransfer.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.datatransfer module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.datatransfer
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.datatransfer
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_desktop.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.desktop module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.desktop
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.desktop
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_instrument.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.instrument module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.instrument
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.instrument
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_logging.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.logging module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.logging
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.logging
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_management.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.management module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.management
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.management
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_management_rmi.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.management.rmi module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.management.rmi
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.management.rmi
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_naming.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.naming module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.naming
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.naming
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_prefs.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.prefs module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.prefs
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.prefs
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_rmi.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.rmi module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.rmi
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.rmi
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_scripting.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.scripting module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.scripting
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.scripting
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_security_jgss.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.security.jgss module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.security.jgss
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.security.jgss
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_security_sasl.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.security.sasl module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.security.sasl
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.security.sasl
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_smartcardio.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.smartcardio module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.smartcardio
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.smartcardio
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_sql.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.sql module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.sql
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.sql
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_sql_rowset.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.sql.rowset module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.sql.rowset
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.sql.rowset
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_transaction.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.transaction module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.transaction
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.transaction
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_xml.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.xml module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.xml
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.xml
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_xml_bind.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.xml.bind module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.xml.bind
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.xml.bind
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_xml_crypto.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.xml.crypto module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.xml.crypto
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.xml.crypto
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_xml_ws.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.xml.ws module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.xml.ws
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.xml.ws
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/java_xml_ws_annotation.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from java.xml.ws.annotation module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules java.xml.ws.annotation
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:java.xml.ws.annotation
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_base.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.base module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.base
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.base
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_controls.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.controls module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.controls
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.controls
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_fxml.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.fxml module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.fxml
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.fxml
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_graphics.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.graphics module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.graphics
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.graphics
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_media.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.media module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.media
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.media
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_swing.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.swing module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.swing
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.swing
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/javafx_web.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from javafx.web module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules javafx.web
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:javafx.web
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_accessibility.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.accessibility module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.accessibility
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.accessibility
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_aot.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.aot module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.aot
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.aot
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_attach.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.attach module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.attach
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.attach
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_charsets.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.charsets module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.charsets
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.charsets
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_compiler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.compiler module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.compiler
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.compiler
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_cryptoki.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.crypto.cryptoki module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.crypto.cryptoki
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.crypto.cryptoki
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ec.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.crypto.ec module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.crypto.ec
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.crypto.ec
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_mscapi.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.crypto.mscapi module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.crypto.mscapi
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.crypto.mscapi
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_crypto_ucrypto.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.crypto.ucrypto module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.crypto.ucrypto
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.crypto.ucrypto
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_dynalink.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.dynalink module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.dynalink
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.dynalink
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_editpad.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.editpad module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.editpad
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.editpad
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_hotspot_agent.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.hotspot.agent module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.hotspot.agent
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.hotspot.agent
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_httpserver.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.httpserver module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.httpserver
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.httpserver
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_incubator_httpclient.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.incubator.httpclient module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.incubator.httpclient
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.incubator.httpclient
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_ed.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.ed module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.ed
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.ed
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_jvmstat.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.jvmstat module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.jvmstat
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.jvmstat
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_le.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.le module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.le
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.le
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_opt.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.opt module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.opt
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.opt
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_vm_ci.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.vm.ci module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.vm.ci
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.vm.ci
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_vm_compiler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.vm.compiler module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.vm.compiler
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.vm.compiler
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_internal_vm_compiler_management.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.internal.vm.compiler.management module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.internal.vm.compiler.management
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.internal.vm.compiler.management
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jartool.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jartool module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jartool
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jartool
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_javadoc.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.javadoc module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.javadoc
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.javadoc
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jcmd.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jcmd module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jcmd
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jcmd
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jconsole.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jconsole module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jconsole
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jconsole
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jdeps.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jdeps module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jdeps
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jdeps
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jdi.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jdi module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jdi
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jdi
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jlink.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jlink module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jlink
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jlink
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jshell.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jshell module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jshell
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jshell
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jsobject.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jsobject module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jsobject
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jsobject
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_jstatd.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.jstatd module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.jstatd
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.jstatd
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_localedata.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.localedata module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.localedata
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.localedata
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_management.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.management module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.management
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.management
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_management_agent.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.management.agent module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.management.agent
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.management.agent
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_naming_dns.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.naming.dns module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.naming.dns
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.naming.dns
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_naming_rmi.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.naming.rmi module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.naming.rmi
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.naming.rmi
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_net.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.net module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.net
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.net
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_packager.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.packager module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.packager
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.packager
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_packager_services.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.packager.services module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.packager.services
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.packager.services
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_rmic.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.rmic module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.rmic
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.rmic
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_scripting_nashorn.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.scripting.nashorn module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.scripting.nashorn
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.scripting.nashorn
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_scripting_nashorn_shell.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.scripting.nashorn.shell module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.scripting.nashorn.shell
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.scripting.nashorn.shell
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_sctp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.sctp module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.sctp
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.sctp
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_security_auth.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.security.auth module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.security.auth
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.security.auth
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_security_jgss.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.security.jgss module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.security.jgss
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.security.jgss
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_unsupported.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.unsupported module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.unsupported
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.unsupported
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_xml_bind.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.xml.bind module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.xml.bind
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.xml.bind
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_xml_dom.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.xml.dom module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.xml.dom
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.xml.dom
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_xml_ws.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.xml.ws module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.xml.ws
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.xml.ws
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/applications/ctw/modules/jdk_zipfs.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary run CTW for all classes from jdk.zipfs module
+ *
+ * @library /test/lib / /testlibrary/ctw/src
+ * @modules java.base/jdk.internal.jimage
+ *          java.base/jdk.internal.misc
+ *          java.base/jdk.internal.reflect
+ * @modules jdk.zipfs
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/timeout=7200 sun.hotspot.tools.ctw.CtwRunner modules:jdk.zipfs
+ */
--- a/test/hotspot/jtreg/compiler/codecache/jmx/InitialAndMaxUsageTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/compiler/codecache/jmx/InitialAndMaxUsageTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -75,18 +75,12 @@
         }
     }
 
-    private void fillWithSize(long size, List<Long> blobs, MemoryPoolMXBean bean) {
-        long blob;
-        /* Don't fill too much to have space for adapters. So, stop after crossing 95% and
-           don't allocate in case we'll cross 97% on next allocation. We can hit situation
-           like 94% -> (1 allocation) -> 100% otherwise. So, check if
-           <Usage + allocatedSize> is less than 97%, then allocate in case it is, then, stop
-           further allocations with given size in case <Usage> more than 95% */
-        while (((double) bean.getUsage().getUsed() + size <= (CACHE_USAGE_COEF + 0.02d)  * maxSize)
-                && (blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) != 0L
-                && ((double) bean.getUsage().getUsed() <= CACHE_USAGE_COEF * maxSize)) {
-            blobs.add(blob);
-        }
+    private boolean canAllocate(double size, long maxSize, MemoryPoolMXBean bean) {
+        // Don't fill too much to have space for adapters. So, stop after crossing 95% and
+        // don't allocate in case we'll cross 97% on next allocation.
+        double used = bean.getUsage().getUsed();
+        return (used <= CACHE_USAGE_COEF * maxSize) &&
+               (used + size <= (CACHE_USAGE_COEF + 0.02d)  * maxSize);
     }
 
     protected void runTest() {
@@ -106,8 +100,12 @@
          lots of small allocations takes too much time, so, just a small
          optimization */
         try {
-            for (int coef = 1000000; coef > 0; coef /= 10) {
-                fillWithSize(coef * minAllocationUnit, blobs, bean);
+            for (long size = 100_000 * minAllocationUnit; size > 0; size /= 10) {
+                long blob = 0;
+                while (canAllocate(size, maxSize, bean) &&
+                       (blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) != 0) {
+                    blobs.add(blob);
+                }
             }
             Asserts.assertGT((double) bean.getUsage().getUsed(),
                     CACHE_USAGE_COEF * maxSize, String.format("Unable to fill "
--- a/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Thu Nov 16 12:15:55 2017 +0000
@@ -224,8 +224,8 @@
         return CTVM.getLocalVariableTableStart((HotSpotResolvedJavaMethodImpl)method);
     }
 
-    public static void setNotInlineableOrCompileable(HotSpotResolvedJavaMethod method) {
-        CTVM.setNotInlineableOrCompileable((HotSpotResolvedJavaMethodImpl)method);
+    public static void setNotInlinableOrCompilable(HotSpotResolvedJavaMethod method) {
+        CTVM.setNotInlinableOrCompilable((HotSpotResolvedJavaMethodImpl)method);
     }
 
     public static void reprofile(HotSpotResolvedJavaMethod method) {
--- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -71,10 +71,10 @@
         boolean hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
         Asserts.assertFalse(hasNeverInlineDirective, "Unexpected initial " +
                 "value of property 'hasNeverInlineDirective'");
-        CompilerToVMHelper.setNotInlineableOrCompileable(method);
+        CompilerToVMHelper.setNotInlinableOrCompilable(method);
         hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
         Asserts.assertTrue(hasNeverInlineDirective, aMethod
-                + " : hasNeverInlineDirective is false even after setNotInlineableOrCompileable'");
+                + " : hasNeverInlineDirective is false even after setNotInlinableOrCompilable'");
     }
 
     private static List<Executable> createTestCases() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/linkage/OSRWithBadOperandStack.jasm	Thu Nov 16 12:15:55 2017 +0000
@@ -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.
+ *
+ */
+
+public class compiler/linkage/OSRWithBadOperandStack version 52:0 {
+    public static Method m1:"()I" stack 1 locals 0 {
+        iconst_0;
+        ireturn;
+    }
+
+    public static Method m2:"(Ljava/lang/Object;)V" stack 1 locals 1 {
+        return;
+    }
+
+    public static Method test:"()V" stack 2 locals 1 {
+        iconst_0;
+        istore_0;
+        Loop: stack_frame_type append;
+        locals_map int;
+        iload_0;
+        // This should fail with "java.lang.VerifyError: Bad type on operand stack Exception"
+        // because m1 returns an integer and m2 takes an Object.
+        invokestatic Method compiler/linkage/OSRWithBadOperandStack."m1":"()I";
+        invokestatic Method compiler/linkage/OSRWithBadOperandStack."m2":"(Ljava/lang/Object;)V";
+        iinc 0, 1;
+        ldc 100000;
+        if_icmple Loop;
+        return;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/linkage/TestLinkageErrorInGenerateOopMap.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8190797
+ * @summary Test OSR compilation with bad operand stack.
+ * @library /test/lib /
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @compile OSRWithBadOperandStack.jasm
+ * @run driver compiler.linkage.TestLinkageErrorInGenerateOopMap
+ */
+
+package compiler.linkage;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestLinkageErrorInGenerateOopMap {
+
+    public static void main(String args[]) throws Exception {
+        if (args.length == 0) {
+            // Spawn new VM instance to execute test
+            String[] flags = {"-noverify", "-XX:-TieredCompilation",
+                              "-XX:CompileCommand=dontinline,compiler/linkage/OSRWithBadOperandStack.m*",
+                              "compiler.linkage.TestLinkageErrorInGenerateOopMap", "run"};
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+            OutputAnalyzer out = new OutputAnalyzer(pb.start());
+            if (out.getExitValue() != 0) {
+                // OSR compilation should exit with an error during OopMap verification
+                // because a LinkageError cannot be thrown from a compiler thread.
+                out.shouldContain("fatal error: Illegal class file encountered");
+            }
+        } else {
+            // Execute test
+            OSRWithBadOperandStack.test();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+
+/* @test
+ * @bug 8167409
+ * @run main/othervm/native -Xcomp compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs
+ */
+package compiler.runtime.criticalnatives.argumentcorruption;
+public class CheckLongArgs {
+    static {
+        System.loadLibrary("CNCheckLongArgs");
+    }
+    static native void m1(long a1, long a2, long a3, long a4,  long a5, long a6, long a7, long a8, byte[] result);
+    static native void m2(long a1, int[] a2, long a3, int[] a4, long a5, int[] a6, long a7, int[] a8, long a9, byte[] result);
+    public static void main(String args[]) throws Exception {
+        test();
+    }
+    private static void test() throws Exception {
+        int[] l1 = { 1111, 2222, 3333 };
+        int[] l2 = { 4444, 5555, 6666 };
+        int[] l3 = { 7777, 8888, 9999 };
+        int[] l4 = { 1010, 2020, 3030 };
+        byte[] result = { -1 };
+        m1(1111111122222222L, 3333333344444444L, 5555555566666666L, 7777777788888888L, 9999999900000000L, 1212121234343434L,
+           5656565678787878L, 9090909012121212L, result);
+        check(result[0]);
+        result[0] = -1;
+        m2(1111111122222222L, l1, 3333333344444444L, l2, 5555555566666666L, l3, 7777777788888888L, l4, 9999999900000000L, result);
+        check(result[0]);
+    }
+    private static void check(byte result) throws Exception {
+        if (result != 2) {
+            if (result == 1) {
+              throw new Exception("critical native arguments mismatch");
+            }
+            throw new Exception("critical native lookup failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/argumentcorruption/libCNCheckLongArgs.c	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,30 @@
+#include "jni.h"
+JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m1
+  (jlong a1, jlong a2, jlong a3, jlong a4, jlong a5, jlong a6, jlong a7, jlong a8,jint result_length,jbyte* result) {
+
+  if (a1 != 1111111122222222LL || a2 != 3333333344444444LL || a3 != 5555555566666666LL || a4 != 7777777788888888LL ||
+      a5 != 9999999900000000LL || a6 != 1212121234343434LL || a7 != 5656565678787878LL || a8 != 9090909012121212LL ||
+      result_length != 1 || result[0] != -1) {
+    result[0] = 1;
+  } else {
+    result[0] = 2;
+  }
+}
+
+JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m2
+  (jlong a1, jint a2_length, jint* a2, jlong a3, jint a4_length, jint* a4, jlong a5, jint a6_length, jint* a6, jlong a7,
+   jint a8_length, jint* a8, jlong a9, jint result_length, jbyte* result) {
+  if (a1 != 1111111122222222LL || a2_length != 3 || a2[0] != 1111 || a3 != 3333333344444444LL || a4_length != 3 || a4[0] != 4444 ||
+      a5 != 5555555566666666LL || a6_length != 3 || a6[0] != 7777 || a7 != 7777777788888888LL || a8_length != 3 || a8[0] != 1010 || a9 != 9999999900000000LL ||
+      result_length != 1 || result[0] != -1) {
+    result[0] = 1;
+  } else {
+    result[0] = 2;
+  }
+}
+
+JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m1
+  (JNIEnv * env, jclass jclazz, jlong a3, jlong a4, jlong a5, jlong a6, jlong a7, jlong a8, jlong a9, jlong a10, jbyteArray result) {}
+
+JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m2
+  (JNIEnv * env, jclass jclazz, jlong a3, jintArray a4, jlong a5, jintArray a6, jlong a7, jintArray a8, jlong a9, jintArray a10, jlong a11, jbyteArray result) {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/LookUp.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+
+/* @test
+ * @bug 8167408
+ * @run main/othervm/native -Xcomp compiler.runtime.criticalnatives.lookup.LookUp
+ */
+package compiler.runtime.criticalnatives.lookup;
+public class LookUp {
+    static {
+        System.loadLibrary("CNLookUp");
+    }
+    static native void m1(byte a1, long a2, char a3, int a4,  float a5, double a6, byte[] result);
+    static native void m2(int a1, int[] a2, long a3, long[] a4, float a5,float[] a6, double a7, double[] a8, byte result[]);
+    public static void main(String args[]) throws Exception {
+        test();
+    }
+    private static void test() throws Exception {
+        int[] l1 = { 1111, 2222, 3333 };
+        long[] l2 = { 4444L, 5555L, 6666L };
+        float[] l3 = { 7777.0F, 8888.0F, 9999.0F };
+        double[] l4 = { 4545.0D, 5656.0D, 6767.0D };
+        byte[] result = { -1 };
+        m1((byte)0xA, 4444444455555555L, 'A', 12345678, 343434.0F, 6666666677777777.0D, result);
+        check(result[0]);
+        result[0] = -1;
+        m2(12345678, l1, 4444444455555555L, l2, 343434.0F, l3, 6666666677777777.0D, l4, result);
+        check(result[0]);
+    }
+    private static void check(byte result) throws Exception {
+        if (result != 2) {
+            if (result == 1) {
+              throw new Exception("critical native arguments mismatch");
+            }
+            throw new Exception("critical native lookup failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/runtime/criticalnatives/lookup/libCNLookUp.c	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,35 @@
+#include "jni.h"
+JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_lookup_LookUp_m1
+  (jbyte a1, jlong a2, jchar a3, jint a4, jfloat a5, jdouble a6, jint result_length, jbyte* result) {
+  jint l1 = (jint) a5;
+  jlong l2 = (jlong) a6;
+
+  if (a1 != 0xA || a2 != 4444444455555555LL || a3 != 0x41 || a4 != 12345678 || l1 != 343434 || l2 != 6666666677777777LL ||
+      result_length != 1 || result[0] != -1) {
+    result[0] = 1;
+  } else {
+    result[0] = 2;
+  }
+}
+
+JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_lookup_LookUp_m2
+  (jint a1, jint a2_length, jint* a2, jlong a3, jint a4_length, jlong* a4, jfloat a5, jint a6_length, jfloat* a6, jdouble a7,
+   jint a8_length, jdouble* a8, jint result_length, jbyte* result) {
+  jint l1 = (jint) a5;
+  jlong l2 = (jlong) a7;
+
+  if (a1 != 12345678 || a2_length != 3 || a2[0] != 1111 || a3 != 4444444455555555LL || a4_length != 3 || a4[0] != 4444 ||
+      l1 != 343434 ||  a6_length != 3 ||  7777 != (jint)a6[0] || l2 != 6666666677777777LL || a8_length != 3 || 4545 != (jlong)a8[0] ||
+      result_length != 1 || result[0] != -1) {
+    result[0] = 1;
+  } else {
+    result[0] = 2;
+  }
+}
+
+JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_lookup_LookUp_m1
+  (JNIEnv * env, jclass jclazz, jbyte a3, jlong a4, jchar a5, jint a6, jfloat a7, jdouble a8, jbyteArray result) {}
+
+JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_lookup_LookUp_m2
+  (JNIEnv * env, jclass jclazz, jint a3, jintArray a4, jlong a5, jlongArray a6, jfloat a7, jfloatArray a8, jdouble a9, jdoubleArray a10, jbyteArray result) {}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/unsafe/TestSplitIf.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8186125
+ * @summary cast before unsafe access moved in dominating null check null path causes crash
+ * @modules java.base/jdk.internal.misc:+open
+ *
+ * @run main/othervm -XX:-BackgroundCompilation TestSplitIf
+ *
+ */
+
+import jdk.internal.misc.Unsafe;
+import java.lang.reflect.Field;
+
+public class TestSplitIf {
+
+    static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe();
+    static final long F_OFFSET;
+
+    static class A {
+        int f;
+        A(int f) {
+            this.f = f;
+        }
+    }
+
+    static {
+        try {
+            Field fField = A.class.getDeclaredField("f");
+            F_OFFSET = UNSAFE.objectFieldOffset(fField);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static int test(A a1, A a2, boolean flag1) {
+        boolean flag2;
+        int f = 0;
+        A a = null;
+        if (flag1) {
+            flag2 = true;
+            a = a1;
+        } else {
+            flag2 = false;
+            a = a2;
+        }
+        if (flag2) {
+            f = UNSAFE.getInt(a, F_OFFSET);
+        } else {
+            f = UNSAFE.getInt(a, F_OFFSET);
+        }
+        return f;
+    }
+
+    static public void main(String[] args) {
+        A a = new A(0x42);
+        for (int i = 0; i < 20000; i++) {
+            test(a, a, (i % 2) == 0);
+        }
+    }
+
+}
--- a/test/hotspot/jtreg/gc/g1/TestGreyReclaimedHumongousObjects.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/g1/TestGreyReclaimedHumongousObjects.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,7 @@
 
 /*
  * @test TestGreyReclaimedHumongousObjects.java
- * @bug 8069367
+ * @bug 8069367 8185278
  * @requires vm.gc.G1
  * @summary Test handling of marked but unscanned reclaimed humongous objects.
  * @key gc
--- a/test/hotspot/jtreg/gc/logging/TestPrintReferences.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/logging/TestPrintReferences.java	Thu Nov 16 12:15:55 2017 +0000
@@ -137,15 +137,21 @@
   //      Actual value:  SoftReference(5.55) = phase1(1.85) + phase2(1.85) + phase3(1.85)
   //      Log value:     SoftReference(5.6) = phase1(1.9) + phase2(1.9) + phase3(1.9)
   //      When checked:  5.6 < 5.7 (sum of phase1~3)
-  public static boolean approximatelyEqual(BigDecimal phaseTime, BigDecimal sumOfSubPhasesTime, BigDecimal tolerance) {
-    BigDecimal abs = phaseTime.subtract(sumOfSubPhasesTime).abs();
-
-    int result = abs.compareTo(tolerance);
+  // Because of this we need method to verify that our measurements and calculations are valid.
+  public static boolean greaterThanOrApproximatelyEqual(BigDecimal phaseTime, BigDecimal sumOfSubPhasesTime, BigDecimal tolerance) {
+    if (phaseTime.compareTo(sumOfSubPhasesTime) >= 0) {
+      // phaseTime is greater than or equal.
+      return true;
+    }
 
-    // result == -1, abs is less than tolerance.
-    // result == 0,  abs is equal to tolerance.
-    // result == 1,  abs is greater than tolerance.
-    return (result != 1);
+    BigDecimal diff = sumOfSubPhasesTime.subtract(phaseTime);
+    if (diff.compareTo(tolerance) <= 0) {
+      // Difference is within tolerance, so approximately equal.
+      return true;
+    }
+
+    // sumOfSubPhasesTime is greater than phaseTime and not within tolerance.
+    return false;
   }
 
   public static BigDecimal checkPhaseTime(String refType) {
@@ -160,7 +166,7 @@
 
     // If there are 3 sub-phases, we should allow 0.1 tolerance.
     final BigDecimal toleranceFor3SubPhases = BigDecimal.valueOf(0.1);
-    if (!approximatelyEqual(phaseTime, sumOfSubPhasesTime, toleranceFor3SubPhases)) {
+    if (!greaterThanOrApproximatelyEqual(phaseTime, sumOfSubPhasesTime, toleranceFor3SubPhases)) {
       throw new RuntimeException(refType +" time(" + phaseTime +
                                  "ms) is less than the sum(" + sumOfSubPhasesTime + "ms) of each phases");
     }
@@ -181,7 +187,7 @@
 
     // If there are 4 sub-phases, we should allow 0.2 tolerance.
     final BigDecimal toleranceFor4SubPhases = BigDecimal.valueOf(0.2);
-    if (!approximatelyEqual(refProcTime, sumOfSubPhasesTime, toleranceFor4SubPhases)) {
+    if (!greaterThanOrApproximatelyEqual(refProcTime, sumOfSubPhasesTime, toleranceFor4SubPhases)) {
       throw new RuntimeException("Reference Processing time(" + refProcTime + "ms) is less than the sum("
                                  + sumOfSubPhasesTime + "ms) of each phases");
     }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGC.java	Thu Nov 16 12:15:55 2017 +0000
@@ -103,6 +103,8 @@
 }
 
 public class TestSystemGC {
+    private static long endTime;
+
     private static final int numGroups = 7;
     private static final int numGCsPerGroup = 4;
 
@@ -133,8 +135,11 @@
 
         for (int i = 0; i < numGroups; i++) {
             for (int j = 0; j < numGCsPerGroup; j++) {
-                System.gc();
-                ThreadUtils.sleep(getDelayMS(i));
+               System.gc();
+               if (System.currentTimeMillis() >= endTime) {
+                   return;
+               }
+               ThreadUtils.sleep(getDelayMS(i));
             }
         }
     }
@@ -159,7 +164,7 @@
     }
 
     private static void runAllPhases() {
-        for (int i = 0; i < 4; i++) {
+        for (int i = 0; i < 4 && System.currentTimeMillis() < endTime; i++) {
             SystemGCTask gcTask =
                 (i % 2 == 1) ? createSystemGCTask(numGroups / 3) : null;
             ShortLivedAllocationTask shortTask =
@@ -181,12 +186,15 @@
         }
     }
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            throw new IllegalArgumentException("Must specify timeout in seconds as first argument");
+        }
+        int timeout = Integer.parseInt(args[0]) * 1000;
+        System.out.println("Running with timeout of " + timeout + "ms");
+        endTime = System.currentTimeMillis() + timeout;
         // First allocate the long lived objects and then run all phases.
         populateLongLived();
         runAllPhases();
-        if (args.length > 0 && args[0].equals("long")) {
-            runAllPhases();
-        }
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithCMS.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithCMS
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.ConcMarkSweep
  * @summary Stress the CMS GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseConcMarkSweepGC TestSystemGCWithCMS 270
  */
 public class TestSystemGCWithCMS {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithG1.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithG1
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.G1
  * @summary Stress the G1 GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseG1GC TestSystemGCWithG1 270
  */
 public class TestSystemGCWithG1 {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithParallel.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithParallel
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.Parallel
  * @summary Stress the Parallel GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel
+ * @run main/othervm/timeout=300 -Xlog:gc=info -Xmx512m -XX:+UseParallelGC TestSystemGCWithParallel 270
  */
 public class TestSystemGCWithParallel {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithSerial.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,14 +24,15 @@
 
 /*
  * @test TestSystemGCWithSerial
+ * @bug 8190703
  * @key gc
  * @key stress
  * @requires vm.gc.Serial
  * @summary Stress the Serial GC full GC by allocating objects of different lifetimes concurrently with System.gc().
- * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UseSerialGC TestSystemGCWithSerial 270
  */
 public class TestSystemGCWithSerial {
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);
     }
 }
--- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Thu Nov 16 12:15:55 2017 +0000
@@ -216,6 +216,9 @@
             case "CMSPrecleanDenominator":
                 option.addPrepend("-XX:CMSPrecleanNumerator=" + ((new Integer(option.getMin())) - 1));
                 break;
+            case "G1RefProcDrainInterval":
+                option.addPrepend("-XX:+ExplicitGCInvokesConcurrent");
+                break;
             case "InitialTenuringThreshold":
                 option.addPrepend("-XX:MaxTenuringThreshold=" + option.getMax());
                 break;
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Thu Nov 16 12:15:55 2017 +0000
@@ -91,5 +91,6 @@
     public static void main(String[] args) throws Throwable {
         testDeprecated(DEPRECATED_OPTIONS);  // Make sure that each deprecated option is mentioned in the output.
         testDeprecatedDiagnostic("UnsyncloadClass", "false");
+        testDeprecatedDiagnostic("IgnoreUnverifiableClassesDuringDump", "false");
     }
 }
--- a/test/hotspot/jtreg/runtime/CommandLine/VMOptionWarning.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMOptionWarning.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -36,9 +36,9 @@
 
 public class VMOptionWarning {
     public static void main(String[] args) throws Exception {
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+PredictedLoadedClassCount", "-version");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+AlwaysSafeConstructors", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Error: VM option 'PredictedLoadedClassCount' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.");
+        output.shouldContain("Error: VM option 'AlwaysSafeConstructors' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.");
 
         if (Platform.isDebugBuild()) {
             System.out.println("Skip the rest of the tests on debug builds since diagnostic, develop, and notproduct options are available on debug builds.");
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java	Thu Nov 16 12:15:55 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -44,7 +44,6 @@
 
         String msg = "Test Succeeded";
 
-        // Execute the VM so that a
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
            "-XX:-TransmitErrorReport",
            "-XX:-CreateCoredumpOnCrash",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoadClass/TestResize.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8184765
+ * @summary make sure the SystemDictionary gets resized when load factor is too high
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @compile TriggerResize.java
+ * @run driver TestResize
+ */
+
+import java.lang.ProcessBuilder;
+import java.lang.Process;
+import jdk.test.lib.process.ProcessTools;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Scanner;
+
+public class TestResize {
+
+  static double MAX_LOAD_FACTOR = 5.0; // see _resize_load_trigger in dictionary.cpp
+
+  static int getInt(String string) {
+    int start = 0;
+    for (int i = 0; i < string.length(); i++) {
+      if (!Character.isDigit(string.charAt(i))) {
+        start++;
+      } else {
+        break;
+      }
+    }
+    int end = start;
+    for (int i = end; i < string.length(); i++) {
+      if (Character.isDigit(string.charAt(i))) {
+        end++;
+      } else {
+        break;
+      }
+    }
+    return Integer.parseInt(string.substring(start, end));
+  }
+
+  static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
+    pb.redirectErrorStream(true);
+    Process process = pb.start();
+    BufferedReader rd = new BufferedReader(new InputStreamReader(process.getInputStream()));
+    String line = rd.readLine();
+    while (line != null) {
+      if (line.startsWith("Java dictionary (")) {
+        // ex. "Java dictionary (table_size=107, classes=6)"
+        // ex. "Java dictionary (table_size=20201, classes=50002)"
+        Scanner scanner = new Scanner(line);
+        scanner.next();
+        scanner.next();
+        int table_size = getInt(scanner.next());
+        int classes = getInt(scanner.next());
+        scanner.close();
+
+        double loadFactor = (double)classes / (double)table_size;
+        if (loadFactor > MAX_LOAD_FACTOR) {
+          throw new RuntimeException("Load factor too high, expected MAX "+MAX_LOAD_FACTOR+", got "+loadFactor);
+        } else {
+          System.out.println("PASS table_size:"+table_size+", classes:"+classes+" OK");
+        }
+      }
+      line = rd.readLine();
+    }
+    int retval = process.waitFor();
+    if (retval != 0) {
+      throw new RuntimeException("Error: test returned non-zero value");
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintSystemDictionaryAtExit",
+                                                              "TriggerResize",
+                                                              "50000");
+    analyzeOutputOn(pb);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoadClass/TriggerResize.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+import java.lang.ClassLoader;
+
+public class TriggerResize extends ClassLoader
+{
+  static private int[] DATA = // bytes for "class TestCase00000 {}"
+  {
+    -54,    -2,   -70,   -66,     0,     0,     0,    52,    0,     13, //   0
+     10,     0,     3,     0,    10,     7,     0,    11,    7,      0, //  10
+     12,     1,     0,     6,    60,   105,   110,   105,  116,     62, //  20
+      1,     0,     3,    40,    41,    86,     1,     0,     4,    67, //  30
+    111,   100,   101,     1,     0,    15,    76,   105,   110,   101, //  40
+     78,   117,   109,    98,   101,   114,    84,    97,    98,   108, //  50
+    101,     1,     0,    10,    83,   111,   117,   114,    99,   101, //  60
+     70,   105,   108,   101,     1,     0,    18,    84,   101,   115, //  70
+    116,    67,    97,   115,   101,    48,    48,    48,    48,    48, //  80
+     46,   106,    97,   118,    97,    12,     0,     4,     0,     5, //  90
+      1,     0,    13,    84,   101,   115,   116,    67,    97,   115, // 100
+    101,    48,    48,    48,    48,    48,     1,     0,    16,   106, // 110
+     97,   118,    97,    47,   108,    97,   110,   103,    47,    79, // 120
+     98,   106,   101,    99,   116,     0,    32,     0,     2,     0, // 130
+      3,     0,     0,     0,     0,     0,     1,     0,     0,     0, // 140
+      4,     0,     5,     0,     1,     0,     6,     0,     0,     0, // 150
+     29,     0,     1,     0,     1,     0,     0,     0,     5,    42, // 160
+    -73,     0,     1,   -79,     0,     0,     0,     1,     0,     7, // 170
+      0,     0,     0,     6,     0,     1,     0,     0,     0,     1, // 180
+      0,     1,     0,     8,     0,     0,     0,     2,     0,     9  // 190
+  };
+
+  static private int INDEX1 = 85;
+  static private int INDEX2 = 111;
+  static private int BASE = 48;
+
+  public TriggerResize()
+  {
+    super();
+  }
+
+  public void load(int index)
+  {
+    byte[] bytes = new byte[TriggerResize.DATA.length];
+    for (int i=0; i<bytes.length; i++)
+    {
+      bytes[i] = (byte)TriggerResize.DATA[i];
+    }
+
+    // replace id "00000" in TestCase00000 to generate new class on the fly
+    {
+      int byte1 = index % 10;
+      int byte2 = index / 10 % 10;
+      int byte3 = index / 100 % 10;
+      int byte4 = index / 1000 % 10;
+      int byte5 = index / 10000 % 10;
+
+      bytes[INDEX1+0] = bytes[INDEX2+0] = (byte)(BASE+byte5);
+      bytes[INDEX1+1] = bytes[INDEX2+1] = (byte)(BASE+byte4);
+      bytes[INDEX1+2] = bytes[INDEX2+2] = (byte)(BASE+byte3);
+      bytes[INDEX1+3] = bytes[INDEX2+3] = (byte)(BASE+byte2);
+      bytes[INDEX1+4] = bytes[INDEX2+4] = (byte)(BASE+byte1);
+    }
+
+    Class generatedClass = defineClass(bytes, 0, bytes.length);
+    resolveClass(generatedClass);
+  }
+
+  public static void main(String args[]) throws Exception
+  {
+    int count = 0;
+    if (args.length >= 1) {
+      Integer i = new Integer(args[0]);
+      count = i.intValue();
+    }
+
+    TriggerResize test = new TriggerResize();
+    for (int i = 0; i <= count; i++)
+    {
+      test.load(i);
+    }
+
+    // trigger safepoint to resize the SystemDictionary if needed
+    System.gc();
+  }
+}
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,6 @@
 
 package sun.hotspot.tools.ctw;
 
-
 import java.io.IOException;
 import java.nio.file.FileVisitOption;
 import java.nio.file.Files;
@@ -67,8 +66,7 @@
         for (String c : Utils.classNameToFileName(classname).split("/")) {
             path = path.resolve(c);
         }
-        if (!path.toFile()
-                 .exists()) {
+        if (!Files.exists(path)) {
             return null;
         }
         try {
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,7 +24,6 @@
 package sun.hotspot.tools.ctw;
 
 import java.io.IOException;
-import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,14 +23,13 @@
 
 package sun.hotspot.tools.ctw;
 
+import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
-import jdk.internal.jimage.ImageLocation;
 
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Arrays;
-import java.util.concurrent.Executor;
 import java.util.stream.Stream;
 
 /**
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,9 +23,10 @@
 
 package sun.hotspot.tools.ctw;
 
+import java.io.IOException;
+import java.io.PrintStream;
 import java.lang.management.ManagementFactory;
 
-import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 
@@ -39,20 +40,23 @@
     static PrintStream OUT = System.out;
     static final PrintStream ERR = System.err;
     /**
-     * Entry point. Compiles classes in {@code paths}
+     * Entry point. Compiles classes in {@code targets}
      *
-     * @param paths paths to jar/zip, dir contains classes, or to .lst file
-     *              contains list of classes to compile
+     * @param targets each element can be either
+     *                'modules:&lt;comma separated list of modules to compile&gt'
+     *                 or path to jimage file
+     *                 or path to jar/zip, dir contains classes
+     *                 or path to .lst file contains list of classes to compile
      */
-    public static void main(String[] paths) {
-        if (paths.length == 0) {
-            throw new IllegalArgumentException("Expect a path to a compile target.");
+    public static void main(String[] targets) {
+        if (targets.length == 0) {
+            throw new IllegalArgumentException("Expect a compile target.");
         }
         String logfile = Utils.LOG_FILE;
         PrintStream os = null;
         if (logfile != null) {
             try {
-                os = new PrintStream(Files.newOutputStream(Paths.get(logfile)));
+                os = new PrintStream(Files.newOutputStream(Paths.get(logfile)), true);
             } catch (IOException io) {
             }
         }
@@ -74,7 +78,7 @@
             ExecutorService executor = createExecutor();
             long start = System.currentTimeMillis();
             try {
-                Arrays.stream(paths)
+                Arrays.stream(targets)
                       .map(PathHandler::create)
                       .flatMap(List::stream)
                       .forEach(p -> {
@@ -87,10 +91,10 @@
             } finally {
                 await(executor);
             }
-            CompileTheWorld.OUT.printf("Done (%d classes, %d methods, %d ms)%n",
+            CompileTheWorld.OUT.println(String.format("Done (%d classes, %d methods, %d ms)",
                     PathHandler.getProcessedClassCount(),
                     Compiler.getMethodCount(),
-                    System.currentTimeMillis() - start);
+                    System.currentTimeMillis() - start));
             passed = true;
         } catch (Throwable t){
             t.printStackTrace(ERR);
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -100,8 +100,8 @@
                 }
             }
         } catch (Throwable t) {
-            CompileTheWorld.OUT.printf("[%d]\t%s\tWARNING preloading failed : %s%n",
-                    id, className, t);
+            CompileTheWorld.OUT.println(String.format("[%d]\t%s\tWARNING preloading failed : %s",
+                    id, className, t));
             t.printStackTrace(CompileTheWorld.ERR);
         }
     }
@@ -113,8 +113,8 @@
             try {
                 WHITE_BOX.enqueueInitializerForCompilation(aClass, i);
             } catch (Throwable t) {
-                CompileTheWorld.OUT.printf("[%d]\t%s::<clinit>\tERROR at level %d : %s%n",
-                        id, aClass.getName(), i, t);
+                CompileTheWorld.OUT.println(String.format("[%d]\t%s::<clinit>\tERROR at level %d : %s",
+                        id, aClass.getName(), i, t));
                 t.printStackTrace(CompileTheWorld.ERR);
             }
         }
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java	Thu Nov 16 12:15:55 2017 +0000
@@ -35,8 +35,6 @@
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 import java.util.regex.Pattern;
@@ -62,19 +60,27 @@
     }
 
     private final List<Throwable> errors;
+    private final String target;
     private final Path targetPath;
     private final String targetName;
 
     private CtwRunner(String target) {
-        if (target.equals("modules")) {
+        if (target.startsWith("modules")) {
             targetPath = Paths
                     .get(Utils.TEST_JDK)
                     .resolve("lib")
-                    .resolve(target);
+                    .resolve("modules");
+            if (target.equals("modules")){
+                target = targetPath.toString();
+            }
+            targetName = target.replace(':', '_')
+                               .replace('.', '_')
+                               .replace(',', '_');
         } else {
             targetPath = Paths.get(target).toAbsolutePath();
+            targetName = targetPath.getFileName().toString();
         }
-        targetName = targetPath.getFileName().toString();
+        this.target = target;
         errors = new ArrayList<>();
     }
 
@@ -104,7 +110,7 @@
         long classStart = 0L;
         long classCount = classCount();
         Asserts.assertGreaterThan(classCount, 0L,
-                targetPath + " does not have any classes");
+                target + "(at " + targetPath + ") does not have any classes");
         boolean done = false;
         while (!done) {
             String[] cmd = cmd(classStart);
@@ -138,7 +144,7 @@
                                 + "] != classCount[" + classCount + "]"));
                     } else {
                         System.out.println("Executed CTW for all " + classCount
-                                + " classes in " + targetPath);
+                                + " classes in " + target + "(at " + targetPath + ")");
                     }
                     done = true;
                 } else {
@@ -162,7 +168,7 @@
     }
 
     private long classCount() {
-        List<PathHandler> phs = PathHandler.create(targetPath.toString());
+        List<PathHandler> phs = PathHandler.create(target);
         long result = phs.stream()
                          .mapToLong(PathHandler::classCount)
                          .sum();
@@ -215,7 +221,7 @@
                 "-XX:CompileCommand=exclude,java/lang/invoke/MethodHandle.*",
                 // CTW entry point
                 CompileTheWorld.class.getName(),
-                targetPath.toString(),
+                target,
         };
     }
 
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Thu Nov 16 12:15:55 2017 +0000
@@ -24,9 +24,12 @@
 package sun.hotspot.tools.ctw;
 
 import java.io.Closeable;
+import java.net.URI;
+import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -35,6 +38,7 @@
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 /**
@@ -121,6 +125,15 @@
             path = matcher.group(1);
             path = path.isEmpty() ? "." : path;
             return ClassPathJarInDirEntry.create(Paths.get(path));
+        } else if (path.startsWith("modules:")) {
+            Path modules = FileSystems.getFileSystem(URI.create("jrt:/"))
+                                      .getPath("modules");
+            return Arrays.stream(path.substring("modules:".length())
+                                     .split(","))
+                         .map(modules::resolve)
+                         .map(ClassPathDirEntry::new)
+                         .map(PathHandler::new)
+                         .collect(Collectors.toList());
         } else {
             path = path.isEmpty() ? "." : path;
             Path p = Paths.get(path);
@@ -180,7 +193,9 @@
      */
     public final void process(Executor executor) {
         CompileTheWorld.OUT.println(entry.description());
-        entry.classes().forEach(s -> processClass(s, executor));
+        entry.classes()
+             .distinct()
+             .forEach(s -> processClass(s, executor));
     }
 
     /**
@@ -209,12 +224,12 @@
             Class<?> aClass;
             Thread.currentThread().setContextClassLoader(entry.loader());
             try {
-                CompileTheWorld.OUT.printf("[%d]\t%s%n", id, name);
+                CompileTheWorld.OUT.println(String.format("[%d]\t%s", id, name));
                 aClass = entry.loader().loadClass(name);
                 Compiler.compileClass(aClass, id, executor);
             } catch (Throwable e) {
-                CompileTheWorld.OUT.printf("[%d]\t%s\tWARNING skipped: %s%n",
-                        id, name, e);
+                CompileTheWorld.OUT.println(String.format("[%d]\t%s\tWARNING skipped: %s",
+                        id, name, e));
                 e.printStackTrace(CompileTheWorld.ERR);
             }
         }
--- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Thu Nov 16 12:15:55 2017 +0000
@@ -193,10 +193,11 @@
      * @param filename tested filename
      */
     public static boolean isClassFile(String filename) {
-        // If the filename has a period after removing '.class', it's not valid class file
         return endsWithIgnoreCase(filename, CLASSFILE_EXT)
-                && (filename.indexOf('.')
-                == (filename.length() - CLASSFILE_EXT.length()));
+                // skip all module-info.class files
+                && !(filename.substring(filename.lastIndexOf('/') + 1,
+                                        filename.lastIndexOf('.'))
+                             .equals("module-info"));
     }
 
     /**
--- a/test/jdk/ProblemList.txt	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/jdk/ProblemList.txt	Thu Nov 16 12:15:55 2017 +0000
@@ -174,6 +174,8 @@
 
 java/net/DatagramSocket/SendDatagramToBadAddress.java           7143960 macosx-all
 
+java/net/httpclient/websocket/ConnectionHandover.java           8188895 windows-all
+
 ############################################################################
 
 # jdk_nio
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/ClassSpecializerTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -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.
+ */
+
+/* @test
+ * @summary Smoke-test class specializer, used to create BoundMethodHandle classes
+ * @compile/module=java.base java/lang/invoke/ClassSpecializerHelper.java
+ * @run testng/othervm/timeout=250 -ea -esa ClassSpecializerTest
+ */
+
+// Useful diagnostics to try:
+//   -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true
+//   -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true
+
+
+import org.testng.annotations.*;
+import java.lang.invoke.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static java.lang.invoke.ClassSpecializerHelper.*;
+
+
+public class ClassSpecializerTest {
+    @Test
+    public void testFindSpecies() throws Throwable {
+        System.out.println("testFindSpecies");
+        System.out.println("test = " + SPEC_TEST);
+        ArrayList<Object> args = new ArrayList<>();
+        for (int key = 0; key <= Kind.MAX_KEY; key++) {
+            Kind k = SpecTest.kind(key);
+            System.out.println("k = " + k);
+            MethodHandle mh = k.factory();
+            System.out.println("k.f = " + mh);
+            args.clear();
+            for (Class<?> pt : mh.type().parameterList()) {
+                args.add(coughUpA(pt));
+            }
+            args.set(0, key * 1000 + 42);
+            Frob f = (Frob) mh.invokeWithArguments(args.toArray());
+            assert(f.kind() == k);
+            System.out.println("k.f(...) = " + f.toString());
+            List<Object> l = f.asList();
+            System.out.println("f.l = " + l);
+            args.subList(0,1).clear();  // drop label
+            assert(args.equals(l));
+        }
+    }
+    private static Object coughUpA(Class<?> pt) throws Throwable {
+        if (pt == String.class)  return "foo";
+        if (pt.isArray()) return java.lang.reflect.Array.newInstance(pt.getComponentType(), 2);
+        if (pt == Integer.class)  return 42;
+        if (pt == Double.class)  return 3.14;
+        if (pt.isAssignableFrom(List.class))
+            return Arrays.asList("hello", "world", "from", pt.getSimpleName());
+        return MethodHandles.zero(pt).invoke();
+    }
+    public static void main(String... av) throws Throwable {
+        System.out.println("TEST: ClassSpecializerTest");
+        new ClassSpecializerTest().testFindSpecies();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/java.base/java/lang/invoke/ClassSpecializerHelper.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,155 @@
+/*
+ * 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 java.lang.invoke;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * Helper class, injected into java.lang.invoke,
+ * that bridges to the private ClassSpecializer mechanism.
+ */
+
+public interface ClassSpecializerHelper {
+    interface Frob {
+        Kind kind();
+        int label();
+        List<Object> asList();
+    }
+    abstract class FrobImpl implements Frob {
+        private final int label;
+        public FrobImpl(int label) {
+            this.label = label;
+        }
+        public int label() { return label; }
+        @Override public abstract Kind kind();
+
+        public String toString() {
+            final StringBuilder buf = new StringBuilder();
+            buf.append("Frob[label=").append(label);
+            final Kind k = kind();
+            if (k != null) {
+                for (MethodHandle mh : k.getters()) {
+                    Object x = "?";
+                    try {
+                        x = mh.invoke(this);
+                    } catch (Throwable ex) {
+                        x = "<<"+ex.getMessage()+">>";
+                    }
+                    buf.append(", ").append(x);
+                }
+            }
+            buf.append("]");
+            return buf.toString();
+        }
+
+        public List<Object> asList() {
+            final List<MethodHandle> getters = kind().getters();
+            ArrayList<Object> res = new ArrayList<>(getters.size());
+            for (MethodHandle getter : getters) {
+                try {
+                    res.add(getter.invoke(this));
+                } catch (Throwable ex) {
+                    throw new AssertionError(ex);
+                }
+            }
+            return res;
+        }
+    }
+
+    public static class Kind extends ClassSpecializer<Frob, Byte, Kind>.SpeciesData {
+        public Kind(SpecTest outer, Byte key) {
+            outer.super(key);
+        }
+
+        public MethodHandle factory() {
+            return super.factory();
+        }
+
+        public List<MethodHandle> getters() {
+            return super.getters();
+        }
+
+        private static final List<Class<?>> FIELD_TYPES
+                = Arrays.asList(String.class, float.class, Double.class, boolean.class, Object[].class, Object.class);
+
+        public static int MAX_KEY = FIELD_TYPES.size();
+
+        @Override
+        protected List<Class<?>> deriveFieldTypes(Byte key) {
+            return FIELD_TYPES.subList(0, key);
+        }
+
+        @Override
+        protected Class<? extends Frob> deriveSuperClass() {
+            return FrobImpl.class;
+        }
+
+        @Override
+        protected MethodHandle deriveTransformHelper(MemberName transform, int whichtm) {
+            throw new AssertionError();
+        }
+
+        @Override
+        protected <X> List<X> deriveTransformHelperArguments(MemberName transform, int whichtm, List<X> args, List<X> fields) {
+            throw new AssertionError();
+        }
+    }
+
+    class SpecTest extends ClassSpecializer<Frob, Byte, Kind> {
+        private static final MemberName SPECIES_DATA_ACCESSOR;
+        static {
+            try {
+                SPECIES_DATA_ACCESSOR = MethodHandles.publicLookup()
+                    .resolveOrFail(REF_invokeVirtual, FrobImpl.class, "kind", MethodType.methodType(Kind.class));
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError("Bootstrap link error", ex);
+            }
+        }
+
+        public SpecTest() {
+            super(Frob.class, Byte.class, Kind.class,
+                    MethodType.methodType(void.class, int.class),
+                    SPECIES_DATA_ACCESSOR,
+                    "KIND",
+                    Arrays.asList());
+        }
+
+        @Override
+        protected Kind newSpeciesData(Byte key) {
+            return new Kind(this, key);
+        }
+
+        public static Kind kind(int key) {
+            return (Kind) SPEC_TEST.findSpecies((byte)key);
+        }
+    }
+
+    static final SpecTest SPEC_TEST = new SpecTest();
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/management/RuntimeMXBean/ProcessIdTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8044122
+ * @summary check the correctness of process ID returned by RuntimeMXBean.getPid()
+ * @run main ProcessIdTest
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.ProcessHandle;
+
+public class ProcessIdTest {
+    public static void main(String args[]) {
+        RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
+        long mbeanPid = mbean.getPid();
+        long pid = ProcessHandle.current().pid();
+        long pid1 = Long.parseLong(mbean.getName().split("@")[0]);
+        if(mbeanPid != pid || mbeanPid != pid1) {
+            throw new RuntimeException("Incorrect process ID returned");
+        }
+
+        System.out.println("Test Passed");
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/stream/CustomFJPoolTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,154 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Tests stream execution in a custom ForkJoinPool
+ * @bug 8190974
+ * @run testng/othervm CustomFJPoolTest
+ * @run testng/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 CustomFJPoolTest
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.Comparator;
+import java.util.Spliterator;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class CustomFJPoolTest {
+
+    // A Spliterator that counts the number of spliterators created
+    // including itself, thus the count starts at 1
+    static class SplitCountingSpliterator<T> implements Spliterator<T> {
+        final Spliterator<T> s;
+        final AtomicInteger nsplits;
+
+        // Top-level constructor
+        public SplitCountingSpliterator(Spliterator<T> s) {
+            this.s = s;
+            nsplits = new AtomicInteger(1);
+        }
+
+        // Splitting constructor
+        SplitCountingSpliterator(Spliterator<T> s, AtomicInteger nsplits) {
+            this.s = s;
+            this.nsplits = nsplits;
+        }
+
+        int splits() {
+            return nsplits.get();
+        }
+
+        @Override
+
+        public boolean tryAdvance(Consumer<? super T> action) {
+            return s.tryAdvance(action);
+        }
+
+        @Override
+        public void forEachRemaining(Consumer<? super T> action) {
+            s.forEachRemaining(action);
+        }
+
+        @Override
+        public Spliterator<T> trySplit() {
+            var split = s.trySplit();
+            if (split != null) {
+                nsplits.incrementAndGet();
+                return new SplitCountingSpliterator<>(split, nsplits);
+            }
+            else {
+                return null;
+            }
+        }
+
+        @Override
+        public long estimateSize() {
+            return s.estimateSize();
+        }
+
+        @Override
+        public long getExactSizeIfKnown() {
+            return s.getExactSizeIfKnown();
+        }
+
+        @Override
+        public int characteristics() {
+            return s.characteristics();
+        }
+
+        @Override
+        public boolean hasCharacteristics(int characteristics) {
+            return s.hasCharacteristics(characteristics);
+        }
+
+        @Override
+        public Comparator<? super T> getComparator() {
+            return s.getComparator();
+        }
+    }
+
+    public void testCustomPools() throws Exception {
+        int splitsForP1 = countSplits(new ForkJoinPool(1));
+        int splitsForP2 = countSplits(new ForkJoinPool(2));
+        assertEquals(splitsForP2, splitsForP1 * 2);
+
+        int commonParallelism = ForkJoinPool.getCommonPoolParallelism();
+        if (commonParallelism > 1 && commonParallelism < 128) {
+            int splitsForPHalfC = countSplits(new ForkJoinPool(commonParallelism / 2));
+            int splitsForPC = countSplits(ForkJoinPool.commonPool());
+
+            assertTrue(splitsForPHalfC < splitsForPC);
+            assertEquals(splitsForPC / splitsForPHalfC,
+                         nearestPowerOfTwo(commonParallelism) / nearestPowerOfTwo(commonParallelism / 2));
+        }
+    }
+
+    static int countSplits(ForkJoinPool fjp) throws Exception {
+        // The number of splits will be equivalent to the number of leaf nodes
+        // and will be a power of 2
+        var fInteger = fjp.submit(() -> {
+            var s = IntStream.range(0, 1024).boxed().parallel().spliterator();
+            var cs = new SplitCountingSpliterator<>(s);
+            StreamSupport.stream(cs, true).forEach(e -> {});
+            return cs.splits();
+        });
+        return fInteger.get();
+    }
+
+    static int nearestPowerOfTwo(int i) {
+        return (i & (i - 1)) == 0
+               ? i
+               : 1 << (32 - Integer.numberOfLeadingZeros(i));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/multireleasejar/CheckRuntimeVersion.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class CheckRuntimeVersion {
+    public static void main(String... args) {
+        int version = Integer.parseInt(args[0]);
+        if (Runtime.version().major() != version) {
+            throw new RuntimeException(version + " != current runtime version "
+                + Runtime.version());
+        }
+
+        Set<String> expected = Arrays.stream(args, 1, args.length)
+                                     .collect(Collectors.toSet());
+        Set<String> modules = ModuleFinder.ofSystem().findAll().stream()
+            .map(ModuleReference::descriptor)
+            .map(ModuleDescriptor::name)
+            .collect(Collectors.toSet());
+
+        if (!modules.equals(expected)) {
+            throw new RuntimeException("Expected: " + expected +
+                " observable modules: " + modules);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/multireleasejar/JLinkMRJavaBaseVersionTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8177471
+ * @summary  jlink should use the version from java.base.jmod to find modules
+ * @modules java.base/jdk.internal.module
+ * @library /test/lib
+ * @build jdk.test.lib.process.* CheckRuntimeVersion
+ * @run testng/othervm JLinkMRJavaBaseVersionTest
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.internal.module.ModulePath;
+import jdk.test.lib.process.ProcessTools;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class JLinkMRJavaBaseVersionTest {
+    private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+            .orElseThrow(() -> new RuntimeException("jar tool not found"));
+    private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac")
+            .orElseThrow(() -> new RuntimeException("javac tool not found"));
+    private static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+            .orElseThrow(() -> new RuntimeException("jlink tool not found"));
+
+    private static final Path javaHome = Paths.get(System.getProperty("java.home"));
+
+    // resource text for version 9
+    private byte[] resource9 = ("9 resource file").getBytes();
+    // resource text for current version
+    private byte[] resource = (Runtime.version().major() + " resource file").getBytes();
+
+    static Path getJmods() {
+        Path jmods = Paths.get(System.getProperty("java9.home", javaHome.toString())).resolve("jmods");
+        if (Files.notExists(jmods)) {
+            throw new RuntimeException(jmods + " not found");
+        }
+        return jmods;
+    }
+
+    @BeforeClass
+    public void initialize() throws IOException {
+        Path srcdir = Paths.get(System.getProperty("test.src"));
+
+        // create class files from source
+        Path base = srcdir.resolve("base");
+        Path mr9 = Paths.get("mr9");
+        javac(base, mr9, base.toString());
+
+        // current version
+        Path rt = srcdir.resolve("rt");
+        Path rtmods = Paths.get("rtmods");
+        javac(rt, rtmods, rt.toString());
+
+        // build multi-release jar file with different module-info.class
+        String[] args = {
+                "-cf", "m1.jar",
+                "-C", rtmods.resolve("m1").toString(), ".",
+                "--release ", "9",
+                "-C", mr9.resolve("m1").toString(), "."
+
+        };
+        JAR_TOOL.run(System.out, System.err, args);
+    }
+
+    private void javac(Path source, Path destination, String srcpath) throws IOException {
+        String[] args = Stream.concat(
+                Stream.of("-d", destination.toString(), "--release", "9",
+                          "--module-source-path", srcpath),
+                Files.walk(source)
+                     .map(Path::toString)
+                     .filter(s -> s.endsWith(".java"))
+        ).toArray(String[]::new);
+        int rc = JAVAC_TOOL.run(System.out, System.err, args);
+        Assert.assertEquals(rc, 0);
+    }
+
+    @Test
+    public void basicTest() throws Throwable {
+        if (Files.notExists(javaHome.resolve("lib").resolve("modules"))) {
+            // exploded image
+            return;
+        }
+
+        Runtime.Version version = targetRuntimeVersion();
+        System.out.println("Testing jlink with " + getJmods() + " of target version " + version);
+
+        // use jlink to build image from multi-release jar
+        jlink("m1.jar", "myimage");
+
+        // validate runtime image
+        Path java = Paths.get("myimage", "bin", "java");
+        ProcessTools.executeProcess(java.toString(), "-m", "m1/p.Main");
+
+        // validate the image linked with the proper MR version
+
+        if (version.equalsIgnoreOptional(Runtime.version())) {
+            ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
+                                        "CheckRuntimeVersion", String.valueOf(version.major()),
+                                        "java.base", "java.logging", "m1")
+                .shouldHaveExitValue(0);
+        } else {
+            ProcessTools.executeProcess(java.toString(), "-cp", System.getProperty("test.classes"),
+                                        "CheckRuntimeVersion", String.valueOf(version.major()),
+                                        "java.base", "m1")
+                .shouldHaveExitValue(0);
+        }
+    }
+
+    private Runtime.Version targetRuntimeVersion() {
+        ModuleReference mref = ModulePath.of(Runtime.version(), true, getJmods())
+            .find("java.base")
+            .orElseThrow(() -> new RuntimeException("java.base not found from " + getJmods()));
+
+        return Runtime.Version.parse(mref.descriptor().version().get().toString());
+    }
+
+    private void jlink(String jar, String image) {
+        List<String> args = List.of("--output", image,
+                                    "--add-modules", "m1",
+                                    "--module-path",
+                                    getJmods().toString() + File.pathSeparator + jar);
+        System.out.println("jlink " + args.stream().collect(Collectors.joining(" ")));
+        int exitCode = JLINK_TOOL.run(System.out, System.err, args.toArray(new String[0]));
+        Assert.assertEquals(exitCode, 0);
+    }
+}
--- a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java	Thu Nov 16 12:15:55 2017 +0000
@@ -21,6 +21,8 @@
  * questions.
  */
 
+import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Collection;
 import java.util.List;
@@ -74,11 +76,30 @@
                     classFilesForSpecies(GenerateJLIClassesPlugin.defaultSpecies()),
                     List.of());
 
+        // Check that --generate-jli-classes=@file works as intended
+        Path baseFile = Files.createTempFile("base", "trace");
+        String species = "LLLLLLLLLLLLLLLLLLL";
+        String fileString = "[SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_" + species + " (salvaged)\n";
+        Files.write(baseFile, fileString.getBytes(Charset.defaultCharset()));
+        result = JImageGenerator.getJLinkTask()
+                .modulePath(helper.defaultModulePath())
+                .output(helper.createNewImageDir("generate-jli-file"))
+                .option("--generate-jli-classes=@" + baseFile.toString())
+                .addMods("java.base")
+                .call();
+
+        image = result.assertSuccess();
+
+        JImageValidator.validate(
+            image.resolve("lib").resolve("modules"),
+                    classFilesForSpecies(List.of(species)), // species should be in the image
+                    classFilesForSpecies(List.of(species.substring(1)))); // but not it's immediate parent
     }
 
     private static List<String> classFilesForSpecies(Collection<String> species) {
         return species.stream()
-                .map(s -> "/java.base/java/lang/invoke/BoundMethodHandle$Species_" + s + ".class")
+                .map(s -> "/java.base/java/lang/invoke/BoundMethodHandle$Species_"
+                        + GenerateJLIClassesPlugin.expandSignature(s) + ".class")
                 .collect(Collectors.toList());
     }
 }
--- a/test/jtreg-ext/requires/VMProps.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/jtreg-ext/requires/VMProps.java	Thu Nov 16 12:15:55 2017 +0000
@@ -347,7 +347,6 @@
             isSupported = checkDockerSupport();
         } catch (Exception e) {
             isSupported = false;
-            System.err.println("dockerSupport() threw exception: " + e);
         }
 
         return (isSupported) ? "true" : "false";
--- a/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4934778 4777599 6553182 8146427 8146475 8175055
+ * @bug      4934778 4777599 6553182 8146427 8146475 8175055 8185371
  * @summary  Make sure that -help, -helpfile and -nohelp options work correctly.
  * @author   jamieh
  * @library ../lib
@@ -161,6 +161,7 @@
                 "-sourcetab ",
                 "-keywords ",
                 "-stylesheetfile ",
+                "--add-stylesheet ",
                 "-docencoding ",
                 "-html4 ",
                 "-html5 ",
--- a/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java	Thu Nov 16 12:15:55 2017 +0000
@@ -23,8 +23,9 @@
 
 /*
  * @test
- * @bug      4749567 8071982 8175200 8186332
- * @summary  Test the output for -header, -footer, -nooverview, -nodeprecatedlist, -nonavbar, -notree, -stylesheetfile options.
+ * @bug      4749567 8071982 8175200 8186332 8185371
+ * @summary  Test the output for -header, -footer, -nooverview, -nodeprecatedlist, -nonavbar, -notree,
+ *           -stylesheetfile, --main-stylesheet, --add-stylesheet options.
  * @author   Bhavesh Patel
  * @library  ../lib
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -118,6 +119,64 @@
     }
 
     @Test
+    void testStylesheetFileAltOption() {
+        javadoc("-d", "out-stylesheet-file",
+                "--main-stylesheet", new File(testSrc, "custom-stylesheet.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("custom-stylesheet.css", true, "Custom javadoc style sheet");
+        checkOutput("pkg/Foo.html", true, "<link rel=\"stylesheet\" type=\"text/css\" "
+                + "href=\"../custom-stylesheet.css\" title=\"Style\">");
+    }
+
+    @Test
+    void testAdditionalStylesheetFile() {
+        javadoc("-d", "out-additional-css",
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-1.css").getAbsolutePath(),
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-2.css").getAbsolutePath(),
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-3.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("additional-stylesheet-1.css", true, "Additional javadoc style sheet 1");
+        checkOutput("additional-stylesheet-2.css", true, "Additional javadoc style sheet 2");
+        checkOutput("additional-stylesheet-3.css", true, "Additional javadoc style sheet 3");
+        checkOutput("pkg/Foo.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-1.css\" title=\"Style\">\n"
+                + "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-2.css\" title=\"Style\">\n"
+                + "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-3.css\" title=\"Style\">");
+    }
+
+    @Test
+    void testInvalidStylesheetFile() {
+        javadoc("-d", "out-invalid-css",
+                "--main-stylesheet", new File(testSrc, "custom-stylesheet-1.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.ERROR);
+
+        checkOutput(Output.OUT, true,
+                "javadoc: error - File not found:",
+                "custom-stylesheet-1.css");
+    }
+
+    @Test
+    void testInvalidAdditionalStylesheetFiles() {
+        javadoc("-d", "out-invalid-additional-css",
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-4.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.ERROR);
+
+        checkOutput(Output.OUT, true,
+                "javadoc: error - File not found:",
+                "additional-stylesheet-4.css");
+    }
+
+    @Test
     void testLinkSource() {
         javadoc("-d", "out-9",
                 "-linksource",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-1.css	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 1 */
+
+body {
+    background-color:#f8f8ff;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-2.css	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 2 */
+
+.subNav {
+    background-color:#fafad2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-3.css	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 3 */
+
+a:link, a:visited {
+    color:#8b0000;
+}
--- a/test/lib/sun/hotspot/WhiteBox.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/lib/sun/hotspot/WhiteBox.java	Thu Nov 16 12:15:55 2017 +0000
@@ -525,6 +525,7 @@
   public native boolean areSharedStringsIgnored();
   public native boolean isCDSIncludedInVmBuild();
   public native Object  getResolvedReferences(Class<?> c);
+  public native boolean areOpenArchiveHeapObjectsMapped();
 
   // Compiler Directive
   public native int addCompilerDirective(String compDirect);
--- a/test/make/TestCopyFiles.gmk	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/make/TestCopyFiles.gmk	Thu Nov 16 12:15:55 2017 +0000
@@ -44,6 +44,7 @@
 DEST_DIR := $(OUTPUT_DIR)/dest
 
 $(OUTPUT_DIR)/_src_created: $(DEPS)
+	$(RM) -r $(DEST_DIR)
 	$(RM) -r $(SRC_DIR)
 	$(MKDIR) -p $(SRC_DIR)
 	$(MKDIR) -p $(SRC_DIR)/foo
@@ -51,7 +52,7 @@
 	$(TOUCH) $(SRC_DIR)/foo/foofile
 	$(TOUCH) "$(SRC_DIR)/foo/foo file"
         # Spaces in directories only works with gnu make 4.0 or later
-        ifeq (4.0, $(firstword $(sort 4.0 $(MAKE_VERSION))))
+        ifeq (4.0dfd, $(firstword $(sort 4.0 $(MAKE_VERSION))))
 	  $(MKDIR) -p "$(SRC_DIR)/foo bar"
 	  $(TOUCH) "$(SRC_DIR)/foo bar/foobarfile"
 	  $(TOUCH) "$(SRC_DIR)/foo bar/foo bar file"
@@ -65,15 +66,32 @@
     FILES := $(call CacheFind, $(SRC_DIR)), \
 ))
 
+# Optionally define a rule that deletes all the target files after the makefile
+# has been parsed. GNU make has specific problems with this in combination with
+# spaces in directory names.
+ifeq ($(DELETE_FIRST), true)
+  delete-targets:
+	$(RM) -r $(DEST_DIR)
+	$(ECHO) '$(DEST_DIR)/foo' '$(wildcard $(DEST_DIR)/foo)'
+
+  $(COPY_1): delete-targets
+endif
+
 do-copy1: $(COPY_1)
 
 run-test1: $(OUTPUT_DIR)/_src_created
+	$(ECHO) "Copy 1 first time"
 	+$(MAKE) -f $(THIS_FILE) do-copy1
 	$(DIFF) -r $(SRC_DIR) $(DEST_DIR)
+        # Rerun the copy a second time, with the targets present at make parse
+        # time, but then deleted by a prerequisite rule.
+	$(ECHO) "Copy 1 second time"
+	+$(MAKE) -f $(THIS_FILE) do-copy1 DELETE_FIRST=true
+	$(DIFF) -r $(SRC_DIR) $(DEST_DIR)
 
 TEST_TARGETS += run-test1
 
-.PHONY: do-copy1 run-test1
+.PHONY: do-copy1 run-test1 delete-targets
 
 ################################################################################
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8191306.js	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8191306 Math.abs corner case with optimistic typing
+ *
+ * @test
+ * @run
+ */
+
+print(Math.abs(-2147483648))
+print(Math.abs(java.lang.Integer.MIN_VALUE))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8191306.js.EXPECTED	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,2 @@
+2147483648
+2147483648
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/nosecurity/es6/JDK-8185119.js	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8185119: Uninitialized const when using multiple threads
+ *
+ * @test
+ * @option --language=es6
+ * @run
+ */
+
+function f() {
+    let a;
+    const b = {};
+    b.crash; // b is sometimes undefined
+
+    function c() {
+        a; b;
+    }
+}
+
+let count = new java.util.concurrent.atomic.AtomicInteger();
+
+let T = Java.extend(Java.type('java.lang.Thread'), {
+    run: function() {
+        for (let j = 0; j < 100; j++) {
+            f();
+        }
+        count.getAndIncrement();
+    }
+});
+
+const threads = [new T(), new T(), new T(), new T()];
+threads.forEach(t => t.start());
+threads.forEach(t => t.join());
+
+Assert.assertEquals(count.intValue(), 4);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/src/jdk/nashorn/api/scripting/test/JDK_8068741_Test.java	Thu Nov 16 12:15:55 2017 +0000
@@ -0,0 +1,60 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.api.scripting.test;
+
+import javax.script.ScriptEngineFactory;
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @run testng jdk.nashorn.api.scripting.test.JDK_8068741_Test
+ * @bug 8068741
+ * @summary javax.script.ScriptEngineFactory.getMethodCallSyntax() spec allows null passed as an object
+ */
+public class JDK_8068741_Test {
+    @Test
+    public void testGetMethodCallSyntax() {
+        ScriptEngineFactory fac = new NashornScriptEngineFactory();
+        checkThrowsNPE(() -> fac.getMethodCallSyntax(null, "foo"));
+        checkThrowsNPE(() -> fac.getMethodCallSyntax("obj", null));
+        checkThrowsNPE(() -> fac.getMethodCallSyntax("obj", "foo", (String[])null));
+        checkThrowsNPE(() -> fac.getMethodCallSyntax("obj", "foo", null, "xyz"));
+        checkThrowsNPE(() -> fac.getMethodCallSyntax("obj", "foo", "xyz", null));
+    }
+
+    private void checkThrowsNPE(Runnable r) {
+        boolean gotNPE = false;
+        try {
+            r.run();
+        } catch (NullPointerException npe) {
+            gotNPE = true;
+            System.err.println("Got NPE as expected: " + npe);
+        }
+        Assert.assertTrue(gotNPE);
+    }
+}
--- a/test/nashorn/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java	Thu Nov 16 10:29:18 2017 +0000
+++ b/test/nashorn/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java	Thu Nov 16 12:15:55 2017 +0000
@@ -47,6 +47,10 @@
                 final Object o2 = mi2.getInstance();
                 if (o1 instanceof ITest && o2 instanceof ITest) {
                     return ((ITest)o1).getTestName().compareTo(((ITest)o2).getTestName());
+                } else if (o1 instanceof ITest) {
+                    return 1;
+                } else if (o2 instanceof ITest) {
+                    return -1;
                 }
                 // something else, don't care about the order
                 return 0;