Merge
authorprr
Mon, 10 Oct 2016 13:31:48 -0700
changeset 41411 31882abda8b5
parent 41410 ef26c8e40f1e (current diff)
parent 41378 62969f0fb9c5 (diff)
child 41412 4d1d88a4f815
Merge
jdk/make/Import.gmk
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ModuleNameReader.java
--- a/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -380,3 +380,4 @@
 e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135
 1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136
 9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137
+d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138
--- a/.hgtags-top-repo	Mon Oct 03 14:10:40 2016 -0700
+++ b/.hgtags-top-repo	Mon Oct 10 13:31:48 2016 -0700
@@ -380,3 +380,4 @@
 82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
 3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136
 d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137
+67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
--- a/common/autoconf/buildjdk-spec.gmk.in	Mon Oct 03 14:10:40 2016 -0700
+++ b/common/autoconf/buildjdk-spec.gmk.in	Mon Oct 10 13:31:48 2016 -0700
@@ -33,6 +33,7 @@
 CC := @BUILD_CC@
 CXX := @BUILD_CXX@
 LD := @BUILD_LD@
+LDCXX := @BUILD_LDCXX@
 AS := @BUILD_AS@
 NM := @BUILD_NM@
 AR := @BUILD_AR@
--- a/common/autoconf/generated-configure.sh	Mon Oct 03 14:10:40 2016 -0700
+++ b/common/autoconf/generated-configure.sh	Mon Oct 10 13:31:48 2016 -0700
@@ -687,7 +687,6 @@
 MSVCP_DLL
 MSVCR_DLL
 LIBCXX
-STATIC_CXX_SETTING
 FIXPATH_DETACH_FLAG
 FIXPATH
 BUILD_GTEST
@@ -5092,7 +5091,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1474894604
+DATE_WHEN_GENERATED=1475218974
 
 ###############################################################################
 #
@@ -53087,49 +53086,10 @@
 
 
   if test "x$OPENJDK_TARGET_OS" = xlinux; then
-    # Test if -lstdc++ works.
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dynamic link of stdc++ is possible" >&5
-$as_echo_n "checking if dynamic link of stdc++ is possible... " >&6; }
-    ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-    OLD_CXXFLAGS="$CXXFLAGS"
-    CXXFLAGS="$CXXFLAGS -lstdc++"
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
-  has_dynamic_libstdcxx=yes
-else
-  has_dynamic_libstdcxx=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-    CXXFLAGS="$OLD_CXXFLAGS"
-    ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_dynamic_libstdcxx" >&5
-$as_echo "$has_dynamic_libstdcxx" >&6; }
-
     # Test if stdc++ can be linked statically.
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking if static link of stdc++ is possible" >&5
 $as_echo_n "checking if static link of stdc++ is possible... " >&6; }
-    STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic"
+    STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc"
     ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -53137,9 +53097,7 @@
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
     OLD_LIBS="$LIBS"
-    OLD_CXX="$CXX"
     LIBS="$STATIC_STDCXX_FLAGS"
-    CXX="$CC"
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -53159,7 +53117,6 @@
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
     LIBS="$OLD_LIBS"
-    CXX="$OLD_CXX"
     ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -53169,59 +53126,34 @@
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_static_libstdcxx" >&5
 $as_echo "$has_static_libstdcxx" >&6; }
 
-    if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
-      as_fn_error $? "Cannot link to stdc++, neither dynamically nor statically!" "$LINENO" 5
-    fi
-
     if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
       as_fn_error $? "Static linking of libstdc++ was not possible!" "$LINENO" 5
     fi
 
-    if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
-      as_fn_error $? "Dynamic linking of libstdc++ was not possible!" "$LINENO" 5
-    fi
-
     # If dynamic was requested, it's available since it would fail above otherwise.
     # If dynamic wasn't requested, go with static unless it isn't available.
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
 $as_echo_n "checking how to link with libstdc++... " >&6; }
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
-      LIBCXX="$LIBCXX -lstdc++"
-      # To help comparisons with old build, put stdc++ first in JVM_LIBS
-      JVM_LIBS="-lstdc++ $JVM_LIBS"
-      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
-      # just use the same setting as for the TARGET toolchain.
-      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
-      LDCXX="$CXX"
-      STATIC_CXX_SETTING="STATIC_CXX=false"
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
+        ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
 $as_echo "dynamic" >&6; }
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
-      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
-      # To help comparisons with old build, put stdc++ first in JVM_LIBS
-      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
       # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
       # just use the same setting as for the TARGET toolchain.
-      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
-      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
-      LDCXX="$CC"
-      STATIC_CXX_SETTING="STATIC_CXX=true"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
 $as_echo "static" >&6; }
     fi
   fi
 
-
   # libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so)
   if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then
     LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
   fi
 
-  # TODO better (platform agnostic) test
-  if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then
-    LIBCXX="-lstdc++"
-  fi
 
 
   # Setup Windows runtime dlls
--- a/common/autoconf/lib-std.m4	Mon Oct 03 14:10:40 2016 -0700
+++ b/common/autoconf/lib-std.m4	Mon Oct 10 13:31:48 2016 -0700
@@ -45,84 +45,44 @@
   )
 
   if test "x$OPENJDK_TARGET_OS" = xlinux; then
-    # Test if -lstdc++ works.
-    AC_MSG_CHECKING([if dynamic link of stdc++ is possible])
-    AC_LANG_PUSH(C++)
-    OLD_CXXFLAGS="$CXXFLAGS"
-    CXXFLAGS="$CXXFLAGS -lstdc++"
-    AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
-        [has_dynamic_libstdcxx=yes],
-        [has_dynamic_libstdcxx=no])
-    CXXFLAGS="$OLD_CXXFLAGS"
-    AC_LANG_POP(C++)
-    AC_MSG_RESULT([$has_dynamic_libstdcxx])
-
     # Test if stdc++ can be linked statically.
     AC_MSG_CHECKING([if static link of stdc++ is possible])
-    STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic"
+    STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc"
     AC_LANG_PUSH(C++)
     OLD_LIBS="$LIBS"
-    OLD_CXX="$CXX"
     LIBS="$STATIC_STDCXX_FLAGS"
-    CXX="$CC"
     AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
         [has_static_libstdcxx=yes],
         [has_static_libstdcxx=no])
     LIBS="$OLD_LIBS"
-    CXX="$OLD_CXX"
     AC_LANG_POP(C++)
     AC_MSG_RESULT([$has_static_libstdcxx])
 
-    if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
-      AC_MSG_ERROR([Cannot link to stdc++, neither dynamically nor statically!])
-    fi
-
     if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
       AC_MSG_ERROR([Static linking of libstdc++ was not possible!])
     fi
 
-    if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
-      AC_MSG_ERROR([Dynamic linking of libstdc++ was not possible!])
-    fi
-
     # If dynamic was requested, it's available since it would fail above otherwise.
     # If dynamic wasn't requested, go with static unless it isn't available.
     AC_MSG_CHECKING([how to link with libstdc++])
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
-      LIBCXX="$LIBCXX -lstdc++"
-      # To help comparisons with old build, put stdc++ first in JVM_LIBS
-      JVM_LIBS="-lstdc++ $JVM_LIBS"
-      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
-      # just use the same setting as for the TARGET toolchain.
-      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
-      LDCXX="$CXX"
-      STATIC_CXX_SETTING="STATIC_CXX=false"
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
+        || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
       AC_MSG_RESULT([dynamic])
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
-      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
-      # To help comparisons with old build, put stdc++ first in JVM_LIBS
-      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
       # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
       # just use the same setting as for the TARGET toolchain.
-      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
-      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
-      LDCXX="$CC"
-      STATIC_CXX_SETTING="STATIC_CXX=true"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
       AC_MSG_RESULT([static])
     fi
   fi
-  AC_SUBST(STATIC_CXX_SETTING)
 
   # libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so)
   if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then
     LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
   fi
 
-  # TODO better (platform agnostic) test
-  if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then
-    LIBCXX="-lstdc++"
-  fi
   AC_SUBST(LIBCXX)
 
   # Setup Windows runtime dlls
--- a/corba/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/corba/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -380,3 +380,4 @@
 094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
 aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136
 258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137
+27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
--- a/corba/make/gensrc/Gensrc-java.corba.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/corba/make/gensrc/Gensrc-java.corba.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -38,7 +38,7 @@
     SRC := $(CORBA_TOPDIR)/make/src/classes, \
     BIN := $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes))
 
-TOOL_LOGUTIL_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes \
+TOOL_LOGUTIL_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes \
     build.tools.logutil.MC
 
 $(eval $(call SetupJavaCompilation,BUILD_IDLJ, \
@@ -50,7 +50,7 @@
     EXCLUDE_FILES := ResourceBundleUtil.java module-info.java))
 
 # Force the language to english for predictable source code generation.
-TOOL_IDLJ_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/idlj_classes \
+TOOL_IDLJ_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/idlj_classes \
     -Duser.language=en com.sun.tools.corba.se.idl.toJavaPortable.Compile
 
 ################################################################################
--- a/hotspot/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -540,3 +540,4 @@
 3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
 a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
 dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
+fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
--- a/hotspot/make/lib/CompileGtest.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/make/lib/CompileGtest.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -55,7 +55,7 @@
 # Disabling switch warning for clang because of test source.
 
 $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
-    TOOLCHAIN := $(JVM_TOOLCHAIN), \
+    TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
     LIBRARY := jvm, \
     OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
     OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
@@ -95,7 +95,7 @@
 ################################################################################
 
 $(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \
-    TOOLCHAIN := $(JVM_TOOLCHAIN), \
+    TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
     PROGRAM := gtestLauncher, \
     OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
     EXTRA_FILES := $(GTEST_LAUNCHER_SRC), \
--- a/hotspot/make/lib/CompileJvm.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/make/lib/CompileJvm.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -143,13 +143,6 @@
   JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp
 endif
 
-ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), )
-  # On macosx, aix and solaris we have to link with the C++ compiler
-  JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX
-else
-  JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT
-endif
-
 ifeq ($(OPENJDK_TARGET_CPU), x86)
   JVM_EXCLUDE_PATTERNS += x86_64
 else ifeq ($(OPENJDK_TARGET_CPU), x86_64)
@@ -194,7 +187,7 @@
 # Now set up the actual compilation of the main hotspot native library
 
 $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
-    TOOLCHAIN := $(JVM_TOOLCHAIN), \
+    TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
     LIBRARY := jvm, \
     OUTPUT_DIR := $(JVM_OUTPUTDIR), \
     SRC := $(JVM_SRC_DIRS), \
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Mon Oct 10 13:31:48 2016 -0700
@@ -68,6 +68,7 @@
     Type type            = db.lookupType("InstanceKlass");
     arrayKlasses         = new MetadataField(type.getAddressField("_array_klasses"), 0);
     methods              = type.getAddressField("_methods");
+    defaultMethods       = type.getAddressField("_default_methods");
     methodOrdering       = type.getAddressField("_method_ordering");
     localInterfaces      = type.getAddressField("_local_interfaces");
     transitiveInterfaces = type.getAddressField("_transitive_interfaces");
@@ -128,6 +129,7 @@
 
   private static MetadataField arrayKlasses;
   private static AddressField  methods;
+  private static AddressField  defaultMethods;
   private static AddressField  methodOrdering;
   private static AddressField  localInterfaces;
   private static AddressField  transitiveInterfaces;
@@ -335,6 +337,20 @@
   // Accessors for declared fields
   public Klass     getArrayKlasses()        { return (Klass)        arrayKlasses.getValue(this); }
   public MethodArray  getMethods()              { return new MethodArray(methods.getValue(getAddress())); }
+
+  public MethodArray  getDefaultMethods() {
+    if (defaultMethods != null) {
+      Address addr = defaultMethods.getValue(getAddress());
+      if ((addr != null) && (addr.getAddressAt(0) != null)) {
+        return new MethodArray(addr);
+      } else {
+        return null;
+      }
+    } else {
+      return null;
+    }
+  }
+
   public KlassArray   getLocalInterfaces()      { return new KlassArray(localInterfaces.getValue(getAddress())); }
   public KlassArray   getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
   public int       getJavaFieldsCount()     { return                (int) javaFieldsCount.getValue(this); }
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1358,7 +1358,7 @@
   if (!Universe::is_module_initialized() &&
       !ModuleEntryTable::javabase_defined() &&
       mod_entry == NULL) {
-    mod_entry = ModuleEntryTable::javabase_module();
+    mod_entry = ModuleEntryTable::javabase_moduleEntry();
   }
 
   // The module must be a named module
@@ -1708,7 +1708,7 @@
     if (jb_module == NULL) {
       vm_exit_during_initialization("Unable to create ModuleEntry for java.base");
     }
-    ModuleEntryTable::set_javabase_module(jb_module);
+    ModuleEntryTable::set_javabase_moduleEntry(jb_module);
   }
 }
 
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -773,6 +773,41 @@
   InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK);
 }
 
+// Set the java.lang.reflect.Module module field in the java_lang_Class mirror
+void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Handle module, TRAPS) {
+  if (module.is_null()) {
+    // During startup, the module may be NULL only if java.base has not been defined yet.
+    // Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
+    // for java.base is known.
+    assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
+    MutexLocker m1(Module_lock, THREAD);
+    // Keep list of classes needing java.base module fixup
+    if (!ModuleEntryTable::javabase_defined()) {
+      if (fixup_module_field_list() == NULL) {
+        GrowableArray<Klass*>* list =
+          new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
+        set_fixup_module_field_list(list);
+      }
+      k->class_loader_data()->inc_keep_alive();
+      fixup_module_field_list()->push(k());
+    } else {
+      // java.base was defined at some point between calling create_mirror()
+      // and obtaining the Module_lock, patch this particular class with java.base.
+      ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
+      assert(javabase_entry != NULL && javabase_entry->module() != NULL,
+             "Setting class module field, java.base should be defined");
+      Handle javabase_handle(THREAD, JNIHandles::resolve(javabase_entry->module()));
+      set_module(mirror(), javabase_handle());
+    }
+  } else {
+    assert(Universe::is_module_initialized() ||
+           (ModuleEntryTable::javabase_defined() &&
+            (module() == JNIHandles::resolve(ModuleEntryTable::javabase_moduleEntry()->module()))),
+           "Incorrect java.lang.reflect.Module specification while creating mirror");
+    set_module(mirror(), module());
+  }
+}
+
 void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
                                     Handle module, Handle protection_domain, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
@@ -835,25 +870,13 @@
     set_class_loader(mirror(), class_loader());
 
     // set the module field in the java_lang_Class instance
-    // This may be null during bootstrap but will get fixed up later on.
-    set_module(mirror(), module());
+    set_mirror_module_field(k, mirror, module, THREAD);
 
     // Setup indirection from klass->mirror last
     // after any exceptions can happen during allocations.
     if (!k.is_null()) {
       k->set_java_mirror(mirror());
     }
-
-    // Keep list of classes needing java.base module fixup.
-    if (!ModuleEntryTable::javabase_defined()) {
-      if (fixup_module_field_list() == NULL) {
-        GrowableArray<Klass*>* list =
-          new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
-        set_fixup_module_field_list(list);
-      }
-      k->class_loader_data()->inc_keep_alive();
-      fixup_module_field_list()->push(k());
-    }
   } else {
     if (fixup_mirror_list() == NULL) {
       GrowableArray<Klass*>* list =
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -219,6 +219,7 @@
   static void set_class_loader(oop java_class, oop class_loader);
   static void set_component_mirror(oop java_class, oop comp_mirror);
   static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
+  static void set_mirror_module_field(KlassHandle K, Handle mirror, Handle module, TRAPS);
  public:
   static void compute_offsets();
 
--- a/hotspot/src/share/vm/classfile/klassFactory.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -25,12 +25,85 @@
 #include "precompiled.hpp"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/klassFactory.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "prims/jvmtiEnvBase.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
 #include "trace/traceMacros.hpp"
 
+// called during initial loading of a shared class
+instanceKlassHandle KlassFactory::check_shared_class_file_load_hook(
+                                          instanceKlassHandle ik,
+                                          Symbol* class_name,
+                                          Handle class_loader,
+                                          Handle protection_domain, TRAPS) {
+#if INCLUDE_CDS && INCLUDE_JVMTI
+  assert(ik.not_null(), "sanity");
+  assert(ik()->is_shared(), "expecting a shared class");
+
+  if (JvmtiExport::should_post_class_file_load_hook()) {
+    assert(THREAD->is_Java_thread(), "must be JavaThread");
+
+    // Post the CFLH
+    JvmtiCachedClassFileData* cached_class_file = NULL;
+    JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data();
+    assert(archived_class_data != NULL, "shared class has no archived class data");
+    unsigned char* ptr =
+        VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data);
+    unsigned char* end_ptr =
+        ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data);
+    unsigned char* old_ptr = ptr;
+    JvmtiExport::post_class_file_load_hook(class_name,
+                                           class_loader,
+                                           protection_domain,
+                                           &ptr,
+                                           &end_ptr,
+                                           &cached_class_file);
+    if (old_ptr != ptr) {
+      // JVMTI agent has modified class file data.
+      // Set new class file stream using JVMTI agent modified class file data.
+      ClassLoaderData* loader_data =
+        ClassLoaderData::class_loader_data(class_loader());
+      int path_index = ik->shared_classpath_index();
+      SharedClassPathEntry* ent =
+        (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
+      ClassFileStream* stream = new ClassFileStream(ptr,
+                                                    end_ptr - ptr,
+                                                    ent->_name,
+                                                    ClassFileStream::verify);
+      ClassFileParser parser(stream,
+                             class_name,
+                             loader_data,
+                             protection_domain,
+                             NULL,
+                             NULL,
+                             ClassFileParser::BROADCAST, // publicity level
+                             CHECK_NULL);
+      instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
+                                                                CHECK_NULL);
+      if (cached_class_file != NULL) {
+        new_ik->set_cached_class_file(cached_class_file);
+      }
+
+      if (class_loader.is_null()) {
+        ResourceMark rm;
+        ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
+      }
+
+      return new_ik;
+    }
+  }
+#endif
+
+  return NULL;
+}
+
+
 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
                                                    Symbol* name,
                                                    ClassLoaderData* loader_data,
@@ -97,7 +170,6 @@
                                                      const InstanceKlass* host_klass,
                                                      GrowableArray<Handle>* cp_patches,
                                                      TRAPS) {
-
   assert(stream != NULL, "invariant");
   assert(loader_data != NULL, "invariant");
   assert(THREAD->is_Java_thread(), "must be a JavaThread");
@@ -142,5 +214,27 @@
 
   TRACE_KLASS_CREATION(result, parser, THREAD);
 
+#if INCLUDE_CDS && INCLUDE_JVMTI
+  if (DumpSharedSpaces) {
+    assert(cached_class_file == NULL, "Sanity");
+    // Archive the class stream data into the optional data section
+    JvmtiCachedClassFileData *p;
+    int len;
+    const unsigned char *bytes;
+    // event based tracing might set cached_class_file
+    if ((bytes = result->get_cached_class_file_bytes()) != NULL) {
+      len = result->get_cached_class_file_len();
+    } else {
+      len = stream->length();
+      bytes = stream->buffer();
+    }
+    p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc(
+                    offset_of(JvmtiCachedClassFileData, data) + len);
+    p->length = len;
+    memcpy(p->data, bytes, len);
+    result->set_archived_class_data(p);
+  }
+#endif
+
   return result;
 }
--- a/hotspot/src/share/vm/classfile/klassFactory.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/klassFactory.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -75,6 +75,12 @@
                                                 const InstanceKlass* host_klass,
                                                 GrowableArray<Handle>* cp_patches,
                                                 TRAPS);
+ public:
+  static instanceKlassHandle check_shared_class_file_load_hook(
+                                          instanceKlassHandle ik,
+                                          Symbol* class_name,
+                                          Handle class_loader,
+                                          Handle protection_domain, TRAPS);
 };
 
 #endif // SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -92,7 +92,7 @@
   // read java.base.  If either of these conditions
   // hold, readability has been established.
   if (!this->is_named() ||
-      (m == ModuleEntryTable::javabase_module())) {
+      (m == ModuleEntryTable::javabase_moduleEntry())) {
     return true;
   }
 
@@ -358,16 +358,27 @@
   }
 
   // Set java.lang.reflect.Module, version and location for java.base
-  ModuleEntry* jb_module = javabase_module();
+  ModuleEntry* jb_module = javabase_moduleEntry();
   assert(jb_module != NULL, "java.base ModuleEntry not defined");
-  jb_module->set_module(boot_loader_data->add_handle(module_handle));
   jb_module->set_version(version);
   jb_module->set_location(location);
+  // Once java.base's ModuleEntry _module field is set with the known
+  // java.lang.reflect.Module, java.base is considered "defined" to the VM.
+  jb_module->set_module(boot_loader_data->add_handle(module_handle));
+
   // Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
   java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
+
+  // Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module.
+  patch_javabase_entries(module_handle);
 }
 
+// Within java.lang.Class instances there is a java.lang.reflect.Module field
+// that must be set with the defining module.  During startup, prior to java.base's
+// definition, classes needing their module field set are added to the fixup_module_list.
+// Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
 void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
+  assert(Module_lock->owned_by_self(), "should have the Module_lock");
   if (module_handle.is_null()) {
     fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
   }
@@ -389,9 +400,7 @@
   for (int i = 0; i < list_length; i++) {
     Klass* k = list->at(i);
     assert(k->is_klass(), "List should only hold classes");
-    Thread* THREAD = Thread::current();
-    KlassHandle kh(THREAD, k);
-    java_lang_Class::fixup_module_field(kh, module_handle);
+    java_lang_Class::fixup_module_field(KlassHandle(k), module_handle);
     k->class_loader_data()->dec_keep_alive();
   }
 
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -78,11 +78,11 @@
     _must_walk_reads = false;
   }
 
-  Symbol*          name() const          { return literal(); }
-  void             set_name(Symbol* n)   { set_literal(n); }
+  Symbol*          name() const                        { return literal(); }
+  void             set_name(Symbol* n)                 { set_literal(n); }
 
-  jobject          module() const        { return _module; }
-  void             set_module(jobject j) { _module = j; }
+  jobject          module() const                      { return _module; }
+  void             set_module(jobject j)               { _module = j; }
 
   // The shared ProtectionDomain reference is set once the VM loads a shared class
   // originated from the current Module. The referenced ProtectionDomain object is
@@ -217,13 +217,13 @@
 
   // Special handling for unnamed module, one per class loader's ModuleEntryTable
   void create_unnamed_module(ClassLoaderData* loader_data);
-  ModuleEntry* unnamed_module()                           { return _unnamed_module; }
+  ModuleEntry* unnamed_module()                                { return _unnamed_module; }
 
   // Special handling for java.base
-  static ModuleEntry* javabase_module()                   { return _javabase_module; }
-  static void set_javabase_module(ModuleEntry* java_base) { _javabase_module = java_base; }
-  static bool javabase_defined()                          { return ((_javabase_module != NULL) &&
-                                                                    (_javabase_module->module() != NULL)); }
+  static ModuleEntry* javabase_moduleEntry()                   { return _javabase_module; }
+  static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
+  static bool javabase_defined()                               { return ((_javabase_module != NULL) &&
+                                                                         (_javabase_module->module() != NULL)); }
   static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
   static void patch_javabase_entries(Handle module_handle);
 
--- a/hotspot/src/share/vm/classfile/modules.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/modules.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -206,7 +206,7 @@
   assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table");
 
   // Ensure java.base's ModuleEntry has been created
-  assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base");
+  assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for java.base");
 
   bool duplicate_javabase = false;
   {
@@ -226,7 +226,7 @@
       for (int x = 0; x < pkg_list->length(); x++) {
         // Some of java.base's packages were added early in bootstrapping, ignore duplicates.
         if (package_table->lookup_only(pkg_list->at(x)) == NULL) {
-          pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_module());
+          pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry());
           assert(pkg != NULL, "Unable to create a java.base package entry");
         }
         // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
@@ -255,9 +255,6 @@
     log_trace(modules)("define_javabase_module(): creation of package %s for module java.base",
                        (pkg_list->at(x))->as_C_string());
   }
-
-  // Patch any previously loaded classes' module field with java.base's jlr.Module.
-  ModuleEntryTable::patch_javabase_entries(module_handle);
 }
 
 void Modules::define_module(jobject module, jstring version,
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1210,16 +1210,12 @@
 
 instanceKlassHandle SystemDictionary::load_shared_class(
                  Symbol* class_name, Handle class_loader, TRAPS) {
-  // Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
-  // is enabled since posting CFLH is not supported when loading shared class.
-  if (!JvmtiExport::should_post_class_file_load_hook()) {
-    instanceKlassHandle ik (THREAD, find_shared_class(class_name));
-    // Make sure we only return the boot class for the NULL classloader.
-    if (ik.not_null() &&
-        ik->is_shared_boot_class() && class_loader.is_null()) {
-      Handle protection_domain;
-      return load_shared_class(ik, class_loader, protection_domain, THREAD);
-    }
+  instanceKlassHandle ik (THREAD, find_shared_class(class_name));
+  // Make sure we only return the boot class for the NULL classloader.
+  if (ik.not_null() &&
+      ik->is_shared_boot_class() && class_loader.is_null()) {
+    Handle protection_domain;
+    return load_shared_class(ik, class_loader, protection_domain, THREAD);
   }
   return instanceKlassHandle();
 }
@@ -1303,11 +1299,6 @@
                                                         Handle class_loader,
                                                         Handle protection_domain, TRAPS) {
   instanceKlassHandle nh = instanceKlassHandle(); // null Handle
-  if (JvmtiExport::should_post_class_file_load_hook()) {
-    // Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
-    // is enabled since posting CFLH is not supported when loading shared class.
-    return nh;
-  }
 
   if (ik.not_null()) {
     Symbol* class_name = ik->name();
@@ -1358,6 +1349,14 @@
       }
     }
 
+    instanceKlassHandle new_ik = KlassFactory::check_shared_class_file_load_hook(
+        ik, class_name, class_loader, protection_domain, CHECK_(nh));
+    if (new_ik.not_null()) {
+      // The class is changed by CFLH. Return the new class. The shared class is
+      // not used.
+      return new_ik;
+    }
+
     // Adjust methods to recover missing data.  They need addresses for
     // interpreter entry points and their default native method address
     // must be reset.
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1366,22 +1366,25 @@
      return false;
   }
   assert(prefix != NULL && prefix != BUSY, "Error");
-  size_t i = 1;
   oop cur = prefix;
-  while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
-    i++; cur = cur->list_ptr_from_klass();
+  for (size_t i = 1; i < objsFromOverflow; ++i) {
+    oop next = cur->list_ptr_from_klass();
+    if (next == NULL) break;
+    cur = next;
   }
+  assert(cur != NULL, "Loop postcondition");
 
   // Reattach remaining (suffix) to overflow list
-  if (cur->klass_or_null() == NULL) {
+  oop suffix = cur->list_ptr_from_klass();
+  if (suffix == NULL) {
     // Write back the NULL in lieu of the BUSY we wrote
     // above and it is still the same value.
     if (_overflow_list == BUSY) {
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
     }
   } else {
-    assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
-    oop suffix = cur->list_ptr_from_klass();       // suffix will be put back on global list
+    assert(suffix != BUSY, "Error");
+    // suffix will be put back on global list
     cur->set_klass_to_list_ptr(NULL);     // break off suffix
     // It's possible that the list is still in the empty(busy) state
     // we left it in a short while ago; in that case we may be
@@ -1401,8 +1404,10 @@
       // Too bad, someone else got in in between; we'll need to do a splice.
       // Find the last item of suffix list
       oop last = suffix;
-      while (last->klass_or_null() != NULL) {
-        last = last->list_ptr_from_klass();
+      while (true) {
+        oop next = last->list_ptr_from_klass();
+        if (next == NULL) break;
+        last = next;
       }
       // Atomically prepend suffix to current overflow list
       observed_overflow_list = _overflow_list;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1479,7 +1479,7 @@
                               "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
                               capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
 
-    expand(expand_bytes);
+    expand(expand_bytes, _workers);
 
     // No expansion, now see if we want to shrink
   } else if (capacity_after_gc > maximum_desired_capacity) {
@@ -1599,7 +1599,7 @@
                             word_size * HeapWordSize);
 
 
-  if (expand(expand_bytes)) {
+  if (expand(expand_bytes, _workers)) {
     _hrm.verify_optional();
     _verifier->verify_region_sets_optional();
     return attempt_allocation_at_safepoint(word_size,
@@ -1609,7 +1609,7 @@
   return NULL;
 }
 
-bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) {
+bool G1CollectedHeap::expand(size_t expand_bytes, WorkGang* pretouch_workers, double* expand_time_ms) {
   size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
   aligned_expand_bytes = align_size_up(aligned_expand_bytes,
                                        HeapRegion::GrainBytes);
@@ -1626,7 +1626,7 @@
   uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
   assert(regions_to_expand > 0, "Must expand by at least one region");
 
-  uint expanded_by = _hrm.expand_by(regions_to_expand);
+  uint expanded_by = _hrm.expand_by(regions_to_expand, pretouch_workers);
   if (expand_time_ms != NULL) {
     *expand_time_ms = (os::elapsedTime() - expand_heap_start_time_sec) * MILLIUNITS;
   }
@@ -1927,7 +1927,7 @@
   _cmThread = _cm->cmThread();
 
   // Now expand into the initial heap size.
-  if (!expand(init_byte_size)) {
+  if (!expand(init_byte_size, _workers)) {
     vm_shutdown_during_initialization("Failed to allocate initial heap.");
     return JNI_ENOMEM;
   }
@@ -3165,7 +3165,6 @@
 
         assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table.");
 
-        _cm->note_start_of_gc();
         // We call this after finalize_cset() to
         // ensure that the CSet has been finalized.
         _cm->verify_no_cset_oops();
@@ -3241,7 +3240,7 @@
             // No need for an ergo logging here,
             // expansion_amount() does this when it returns a value > 0.
             double expand_ms;
-            if (!expand(expand_bytes, &expand_ms)) {
+            if (!expand(expand_bytes, _workers, &expand_ms)) {
               // We failed to expand the heap. Cannot do anything about it.
             }
             g1_policy()->phase_times()->record_expand_heap_time(expand_ms);
@@ -3251,7 +3250,6 @@
         // We redo the verification but now wrt to the new CSet which
         // has just got initialized after the previous CSet was freed.
         _cm->verify_no_cset_oops();
-        _cm->note_end_of_gc();
 
         // This timing is only used by the ergonomics to handle our pause target.
         // It is unclear why this should not include the full pause. We will
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -557,7 +557,7 @@
   // Returns true if the heap was expanded by the requested amount;
   // false otherwise.
   // (Rounds up to a HeapRegion boundary.)
-  bool expand(size_t expand_bytes, double* expand_time_ms = NULL);
+  bool expand(size_t expand_bytes, WorkGang* pretouch_workers = NULL, double* expand_time_ms = NULL);
 
   // Returns the PLAB statistics for a given destination.
   inline G1EvacStats* alloc_buffer_stats(InCSetState dest);
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -133,129 +133,184 @@
 }
 
 G1CMMarkStack::G1CMMarkStack() :
-  _reserved_space(),
+  _max_chunk_capacity(0),
   _base(NULL),
-  _capacity(0),
-  _saved_index((size_t)AllBits),
+  _chunk_capacity(0),
+  _out_of_memory(false),
   _should_expand(false) {
   set_empty();
 }
 
 bool G1CMMarkStack::resize(size_t new_capacity) {
   assert(is_empty(), "Only resize when stack is empty.");
-  assert(new_capacity <= MarkStackSizeMax,
-         "Trying to resize stack to " SIZE_FORMAT " elements when the maximum is " SIZE_FORMAT, new_capacity, MarkStackSizeMax);
-
-  size_t reservation_size = ReservedSpace::allocation_align_size_up(new_capacity * sizeof(oop));
-
-  ReservedSpace rs(reservation_size);
-  if (!rs.is_reserved()) {
-    log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " elements and size " SIZE_FORMAT "B.", new_capacity, reservation_size);
+  assert(new_capacity <= _max_chunk_capacity,
+         "Trying to resize stack to " SIZE_FORMAT " chunks when the maximum is " SIZE_FORMAT, new_capacity, _max_chunk_capacity);
+
+  OopChunk* new_base = MmapArrayAllocator<OopChunk, mtGC>::allocate_or_null(new_capacity);
+
+  if (new_base == NULL) {
+    log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", new_capacity, new_capacity * sizeof(OopChunk));
     return false;
   }
-
-  VirtualSpace vs;
-
-  if (!vs.initialize(rs, rs.size())) {
-    rs.release();
-    log_warning(gc)("Failed to commit memory for new overflow mark stack of size " SIZE_FORMAT "B.", rs.size());
-    return false;
+  // Release old mapping.
+  if (_base != NULL) {
+    MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
   }
 
-  assert(vs.committed_size() == rs.size(), "Failed to commit all of the mark stack.");
-
-  // Release old mapping.
-  _reserved_space.release();
-
-  // Save new mapping for future unmapping.
-  _reserved_space = rs;
-
-  MemTracker::record_virtual_memory_type((address)_reserved_space.base(), mtGC);
-
-  _base = (oop*) vs.low();
-  _capacity = new_capacity;
+  _base = new_base;
+  _chunk_capacity = new_capacity;
   set_empty();
   _should_expand = false;
 
   return true;
 }
 
-bool G1CMMarkStack::allocate(size_t capacity) {
-  return resize(capacity);
+size_t G1CMMarkStack::capacity_alignment() {
+  return (size_t)lcm(os::vm_allocation_granularity(), sizeof(OopChunk)) / sizeof(void*);
+}
+
+bool G1CMMarkStack::initialize(size_t initial_capacity, size_t max_capacity) {
+  guarantee(_max_chunk_capacity == 0, "G1CMMarkStack already initialized.");
+
+  size_t const OopChunkSizeInVoidStar = sizeof(OopChunk) / sizeof(void*);
+
+  _max_chunk_capacity = (size_t)align_size_up(max_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
+  size_t initial_chunk_capacity = (size_t)align_size_up(initial_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
+
+  guarantee(initial_chunk_capacity <= _max_chunk_capacity,
+            "Maximum chunk capacity " SIZE_FORMAT " smaller than initial capacity " SIZE_FORMAT,
+            _max_chunk_capacity,
+            initial_chunk_capacity);
+
+  log_debug(gc)("Initialize mark stack with " SIZE_FORMAT " chunks, maximum " SIZE_FORMAT,
+                initial_chunk_capacity, _max_chunk_capacity);
+
+  return resize(initial_chunk_capacity);
 }
 
 void G1CMMarkStack::expand() {
   // Clear expansion flag
   _should_expand = false;
 
-  if (_capacity == MarkStackSizeMax) {
-    log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " elements.", _capacity);
+  if (_chunk_capacity == _max_chunk_capacity) {
+    log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " chunks.", _chunk_capacity);
     return;
   }
-  size_t old_capacity = _capacity;
+  size_t old_capacity = _chunk_capacity;
   // Double capacity if possible
-  size_t new_capacity = MIN2(old_capacity * 2, MarkStackSizeMax);
+  size_t new_capacity = MIN2(old_capacity * 2, _max_chunk_capacity);
 
   if (resize(new_capacity)) {
-    log_debug(gc)("Expanded marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
+    log_debug(gc)("Expanded mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
                   old_capacity, new_capacity);
   } else {
-    log_warning(gc)("Failed to expand marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
+    log_warning(gc)("Failed to expand mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
                     old_capacity, new_capacity);
   }
 }
 
 G1CMMarkStack::~G1CMMarkStack() {
   if (_base != NULL) {
-    _base = NULL;
-    _reserved_space.release();
-  }
-}
-
-void G1CMMarkStack::par_push_arr(oop* buffer, size_t n) {
-  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-  size_t start = _index;
-  size_t next_index = start + n;
-  if (next_index > _capacity) {
-    _overflow = true;
-    return;
-  }
-  // Otherwise.
-  _index = next_index;
-  for (size_t i = 0; i < n; i++) {
-    size_t ind = start + i;
-    assert(ind < _capacity, "By overflow test above.");
-    _base[ind] = buffer[i];
+    MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
   }
 }
 
-bool G1CMMarkStack::par_pop_arr(oop* buffer, size_t max, size_t* n) {
-  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-  size_t index = _index;
-  if (index == 0) {
-    *n = 0;
+void G1CMMarkStack::add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem) {
+  elem->next = *list;
+  *list = elem;
+}
+
+void G1CMMarkStack::add_chunk_to_chunk_list(OopChunk* elem) {
+  MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
+  add_chunk_to_list(&_chunk_list, elem);
+  _chunks_in_chunk_list++;
+}
+
+void G1CMMarkStack::add_chunk_to_free_list(OopChunk* elem) {
+  MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
+  add_chunk_to_list(&_free_list, elem);
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_list(OopChunk* volatile* list) {
+  OopChunk* result = *list;
+  if (result != NULL) {
+    *list = (*list)->next;
+  }
+  return result;
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_chunk_list() {
+  MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
+  OopChunk* result = remove_chunk_from_list(&_chunk_list);
+  if (result != NULL) {
+    _chunks_in_chunk_list--;
+  }
+  return result;
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_free_list() {
+  MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
+  return remove_chunk_from_list(&_free_list);
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::allocate_new_chunk() {
+  // This dirty read of _hwm is okay because we only ever increase the _hwm in parallel code.
+  // Further this limits _hwm to a value of _chunk_capacity + #threads, avoiding
+  // wraparound of _hwm.
+  if (_hwm >= _chunk_capacity) {
+    return NULL;
+  }
+
+  size_t cur_idx = Atomic::add(1, &_hwm) - 1;
+  if (cur_idx >= _chunk_capacity) {
+    return NULL;
+  }
+
+  OopChunk* result = ::new (&_base[cur_idx]) OopChunk;
+  result->next = NULL;
+  return result;
+}
+
+bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) {
+  // Get a new chunk.
+  OopChunk* new_chunk = remove_chunk_from_free_list();
+
+  if (new_chunk == NULL) {
+    // Did not get a chunk from the free list. Allocate from backing memory.
+    new_chunk = allocate_new_chunk();
+  }
+
+  if (new_chunk == NULL) {
+    _out_of_memory = true;
     return false;
-  } else {
-    size_t k = MIN2(max, index);
-    size_t new_ind = index - k;
-    for (size_t j = 0; j < k; j++) {
-      buffer[j] = _base[new_ind + j];
-    }
-    _index = new_ind;
-    *n = k;
-    return true;
   }
+
+  Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop));
+
+  add_chunk_to_chunk_list(new_chunk);
+
+  return true;
 }
 
-void G1CMMarkStack::note_start_of_gc() {
-  assert(_saved_index == (size_t)AllBits, "note_start_of_gc()/end_of_gc() calls bracketed incorrectly");
-  _saved_index = _index;
+bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) {
+  OopChunk* cur = remove_chunk_from_chunk_list();
+
+  if (cur == NULL) {
+    return false;
+  }
+
+  Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop));
+
+  add_chunk_to_free_list(cur);
+  return true;
 }
 
-void G1CMMarkStack::note_end_of_gc() {
-  guarantee(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
-
-  _saved_index = (size_t)AllBits;
+void G1CMMarkStack::set_empty() {
+  _chunks_in_chunk_list = 0;
+  _hwm = 0;
+  clear_out_of_memory();
+  _chunk_list = NULL;
+  _free_list = NULL;
 }
 
 G1CMRootRegions::G1CMRootRegions() :
@@ -483,9 +538,8 @@
     }
   }
 
-  if (!_global_mark_stack.allocate(MarkStackSize)) {
+  if (!_global_mark_stack.initialize(MarkStackSize, MarkStackSizeMax)) {
     vm_exit_during_initialization("Failed to allocate initial concurrent mark overflow mark stack.");
-    return;
   }
 
   _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
@@ -1695,10 +1749,10 @@
     // oop closures will set the has_overflown flag if we overflow the
     // global marking stack.
 
-    assert(_global_mark_stack.overflow() || _global_mark_stack.is_empty(),
-            "mark stack should be empty (unless it overflowed)");
-
-    if (_global_mark_stack.overflow()) {
+    assert(_global_mark_stack.is_out_of_memory() || _global_mark_stack.is_empty(),
+            "Mark stack should be empty (unless it is out of memory)");
+
+    if (_global_mark_stack.is_out_of_memory()) {
       // This should have been done already when we tried to push an
       // entry on to the global mark stack. But let's do it again.
       set_has_overflown();
@@ -2343,49 +2397,54 @@
 }
 
 void G1CMTask::move_entries_to_global_stack() {
-  // local array where we'll store the entries that will be popped
-  // from the local queue
-  oop buffer[global_stack_transfer_size];
-
-  int n = 0;
+  // Local array where we'll store the entries that will be popped
+  // from the local queue.
+  oop buffer[G1CMMarkStack::OopsPerChunk];
+
+  size_t n = 0;
   oop obj;
-  while (n < global_stack_transfer_size && _task_queue->pop_local(obj)) {
+  while (n < G1CMMarkStack::OopsPerChunk && _task_queue->pop_local(obj)) {
     buffer[n] = obj;
     ++n;
   }
+  if (n < G1CMMarkStack::OopsPerChunk) {
+    buffer[n] = NULL;
+  }
 
   if (n > 0) {
-    // we popped at least one entry from the local queue
-
-    if (!_cm->mark_stack_push(buffer, n)) {
+    if (!_cm->mark_stack_push(buffer)) {
       set_has_aborted();
     }
   }
 
-  // this operation was quite expensive, so decrease the limits
+  // This operation was quite expensive, so decrease the limits.
   decrease_limits();
 }
 
-void G1CMTask::get_entries_from_global_stack() {
-  // local array where we'll store the entries that will be popped
+bool G1CMTask::get_entries_from_global_stack() {
+  // Local array where we'll store the entries that will be popped
   // from the global stack.
-  oop buffer[global_stack_transfer_size];
-  size_t n;
-  _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n);
-  assert(n <= global_stack_transfer_size,
-         "we should not pop more than the given limit");
-  if (n > 0) {
-    // yes, we did actually pop at least one entry
-    for (size_t i = 0; i < n; ++i) {
-      bool success = _task_queue->push(buffer[i]);
-      // We only call this when the local queue is empty or under a
-      // given target limit. So, we do not expect this push to fail.
-      assert(success, "invariant");
+  oop buffer[G1CMMarkStack::OopsPerChunk];
+
+  if (!_cm->mark_stack_pop(buffer)) {
+    return false;
+  }
+
+  // We did actually pop at least one entry.
+  for (size_t i = 0; i < G1CMMarkStack::OopsPerChunk; ++i) {
+    oop elem = buffer[i];
+    if (elem == NULL) {
+      break;
     }
+    bool success = _task_queue->push(elem);
+    // We only call this when the local queue is empty or under a
+    // given target limit. So, we do not expect this push to fail.
+    assert(success, "invariant");
   }
 
-  // this operation was quite expensive, so decrease the limits
+  // This operation was quite expensive, so decrease the limits
   decrease_limits();
+  return true;
 }
 
 void G1CMTask::drain_local_queue(bool partially) {
@@ -2429,20 +2488,21 @@
 
   // Decide what the target size is, depending whether we're going to
   // drain it partially (so that other tasks can steal if they run out
-  // of things to do) or totally (at the very end).  Notice that,
-  // because we move entries from the global stack in chunks or
-  // because another task might be doing the same, we might in fact
-  // drop below the target. But, this is not a problem.
-  size_t target_size;
+  // of things to do) or totally (at the very end).
+  // Notice that when draining the global mark stack partially, due to the racyness
+  // of the mark stack size update we might in fact drop below the target. But,
+  // this is not a problem.
+  // In case of total draining, we simply process until the global mark stack is
+  // totally empty, disregarding the size counter.
   if (partially) {
-    target_size = _cm->partial_mark_stack_size_target();
+    size_t const target_size = _cm->partial_mark_stack_size_target();
+    while (!has_aborted() && _cm->mark_stack_size() > target_size) {
+      if (get_entries_from_global_stack()) {
+        drain_local_queue(partially);
+      }
+    }
   } else {
-    target_size = 0;
-  }
-
-  if (_cm->mark_stack_size() > target_size) {
-    while (!has_aborted() && _cm->mark_stack_size() > target_size) {
-      get_entries_from_global_stack();
+    while (!has_aborted() && get_entries_from_global_stack()) {
       drain_local_queue(partially);
     }
   }
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -149,42 +149,98 @@
 //
 // Stores oops in a huge buffer in virtual memory that is always fully committed.
 // Resizing may only happen during a STW pause when the stack is empty.
+//
+// Memory is allocated on a "chunk" basis, i.e. a set of oops. For this, the mark
+// stack memory is split into evenly sized chunks of oops. Users can only
+// add or remove entries on that basis.
+// Chunks are filled in increasing address order. Not completely filled chunks
+// have a NULL element as a terminating element.
+//
+// Every chunk has a header containing a single pointer element used for memory
+// management. This wastes some space, but is negligible (< .1% with current sizing).
+//
+// Memory management is done using a mix of tracking a high water-mark indicating
+// that all chunks at a lower address are valid chunks, and a singly linked free
+// list connecting all empty chunks.
 class G1CMMarkStack VALUE_OBJ_CLASS_SPEC {
-  ReservedSpace _reserved_space; // Space currently reserved for the mark stack.
+public:
+  // Number of oops that can fit in a single chunk.
+  static const size_t OopsPerChunk = 1024 - 1 /* One reference for the next pointer */;
+private:
+  struct OopChunk {
+    OopChunk* next;
+    oop data[OopsPerChunk];
+  };
+
+  size_t _max_chunk_capacity;    // Maximum number of OopChunk elements on the stack.
+
+  OopChunk* _base;               // Bottom address of allocated memory area.
+  size_t _chunk_capacity;        // Current maximum number of OopChunk elements.
 
-  oop* _base;                    // Bottom address of allocated memory area.
-  size_t _capacity;              // Maximum number of elements.
-  size_t _index;                 // One more than last occupied index.
+  char _pad0[DEFAULT_CACHE_LINE_SIZE];
+  OopChunk* volatile _free_list;  // Linked list of free chunks that can be allocated by users.
+  char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*)];
+  OopChunk* volatile _chunk_list; // List of chunks currently containing data.
+  volatile size_t _chunks_in_chunk_list;
+  char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*) - sizeof(size_t)];
+
+  volatile size_t _hwm;          // High water mark within the reserved space.
+  char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
+
+  // Allocate a new chunk from the reserved memory, using the high water mark. Returns
+  // NULL if out of memory.
+  OopChunk* allocate_new_chunk();
 
-  size_t _saved_index;           // Value of _index saved at start of GC to detect mark stack modifications during that time.
+  volatile bool _out_of_memory;
 
-  bool  _overflow;
+  // Atomically add the given chunk to the list.
+  void add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem);
+  // Atomically remove and return a chunk from the given list. Returns NULL if the
+  // list is empty.
+  OopChunk* remove_chunk_from_list(OopChunk* volatile* list);
+
+  void add_chunk_to_chunk_list(OopChunk* elem);
+  void add_chunk_to_free_list(OopChunk* elem);
+
+  OopChunk* remove_chunk_from_chunk_list();
+  OopChunk* remove_chunk_from_free_list();
+
   bool  _should_expand;
 
   // Resizes the mark stack to the given new capacity. Releases any previous
   // memory if successful.
   bool resize(size_t new_capacity);
 
-  bool stack_modified() const { return _index != _saved_index; }
  public:
   G1CMMarkStack();
   ~G1CMMarkStack();
 
-  bool allocate(size_t capacity);
+  // Alignment and minimum capacity of this mark stack in number of oops.
+  static size_t capacity_alignment();
+
+  // Allocate and initialize the mark stack with the given number of oops.
+  bool initialize(size_t initial_capacity, size_t max_capacity);
 
-  // Pushes the first "n" elements of the given buffer on the stack.
-  void par_push_arr(oop* buffer, size_t n);
+  // Pushes the given buffer containing at most OopsPerChunk elements on the mark
+  // stack. If less than OopsPerChunk elements are to be pushed, the array must
+  // be terminated with a NULL.
+  // Returns whether the buffer contents were successfully pushed to the global mark
+  // stack.
+  bool par_push_chunk(oop* buffer);
 
-  // Moves up to max elements from the stack into the given buffer. Returns
-  // the number of elements pushed, and false if the array has been empty.
-  // Returns true if the buffer contains at least one element.
-  bool par_pop_arr(oop* buffer, size_t max, size_t* n);
+  // Pops a chunk from this mark stack, copying them into the given buffer. This
+  // chunk may contain up to OopsPerChunk elements. If there are less, the last
+  // element in the array is a NULL pointer.
+  bool par_pop_chunk(oop* buffer);
 
-  bool is_empty() const { return _index == 0; }
-  size_t capacity() const  { return _capacity; }
+  // Return whether the chunk list is empty. Racy due to unsynchronized access to
+  // _chunk_list.
+  bool is_empty() const { return _chunk_list == NULL; }
 
-  bool overflow() const { return _overflow; }
-  void clear_overflow() { _overflow = false; }
+  size_t capacity() const  { return _chunk_capacity; }
+
+  bool is_out_of_memory() const { return _out_of_memory; }
+  void clear_out_of_memory() { _out_of_memory = false; }
 
   bool should_expand() const { return _should_expand; }
   void set_should_expand(bool value) { _should_expand = value; }
@@ -192,20 +248,15 @@
   // Expand the stack, typically in response to an overflow condition
   void expand();
 
-  size_t size() const { return _index; }
-
-  void set_empty() { _index = 0; clear_overflow(); }
-
-  // Record the current index.
-  void note_start_of_gc();
+  // Return the approximate number of oops on this mark stack. Racy due to
+  // unsynchronized access to _chunks_in_chunk_list.
+  size_t size() const { return _chunks_in_chunk_list * OopsPerChunk; }
 
-  // Make sure that we have not added any entries to the stack during GC.
-  void note_end_of_gc();
+  void set_empty();
 
-  // Apply fn to each oop in the mark stack, up to the bound recorded
-  // via one of the above "note" functions.  The mark stack must not
+  // Apply Fn to every oop on the mark stack. The mark stack must not
   // be modified while iterating.
-  template<typename Fn> void iterate(Fn fn);
+  template<typename Fn> void iterate(Fn fn) const PRODUCT_RETURN;
 };
 
 // Root Regions are regions that are not empty at the beginning of a
@@ -278,7 +329,6 @@
   friend class G1CMDrainMarkingStackClosure;
   friend class G1CMBitMapClosure;
   friend class G1CMConcurrentMarkingTask;
-  friend class G1CMMarkStack;
   friend class G1CMRemarkTask;
   friend class G1CMTask;
 
@@ -479,22 +529,20 @@
 public:
   // Manipulation of the global mark stack.
   // The push and pop operations are used by tasks for transfers
-  // between task-local queues and the global mark stack, and use
-  // locking for concurrency safety.
-  bool mark_stack_push(oop* arr, size_t n) {
-    _global_mark_stack.par_push_arr(arr, n);
-    if (_global_mark_stack.overflow()) {
+  // between task-local queues and the global mark stack.
+  bool mark_stack_push(oop* arr) {
+    if (!_global_mark_stack.par_push_chunk(arr)) {
       set_has_overflown();
       return false;
     }
     return true;
   }
-  void mark_stack_pop(oop* arr, size_t max, size_t* n) {
-    _global_mark_stack.par_pop_arr(arr, max, n);
+  bool mark_stack_pop(oop* arr) {
+    return _global_mark_stack.par_pop_chunk(arr);
   }
   size_t mark_stack_size()                { return _global_mark_stack.size(); }
   size_t partial_mark_stack_size_target() { return _global_mark_stack.capacity()/3; }
-  bool mark_stack_overflow()              { return _global_mark_stack.overflow(); }
+  bool mark_stack_overflow()              { return _global_mark_stack.is_out_of_memory(); }
   bool mark_stack_empty()                 { return _global_mark_stack.is_empty(); }
 
   G1CMRootRegions* root_regions() { return &_root_regions; }
@@ -599,16 +647,6 @@
   // read-only, so use this carefully!
   void clearRangePrevBitmap(MemRegion mr);
 
-  // Notify data structures that a GC has started.
-  void note_start_of_gc() {
-    _global_mark_stack.note_start_of_gc();
-  }
-
-  // Notify data structures that a GC is finished.
-  void note_end_of_gc() {
-    _global_mark_stack.note_end_of_gc();
-  }
-
   // Verify that there are no CSet oops on the stacks (taskqueues /
   // global mark stack) and fingers (global / per-task).
   // If marking is not in progress, it's a no-op.
@@ -670,10 +708,7 @@
     // references reaches this limit
     refs_reached_period           = 384,
     // Initial value for the hash seed, used in the work stealing code
-    init_hash_seed                = 17,
-    // How many entries will be transferred between global stack and
-    // local queues at once.
-    global_stack_transfer_size    = 1024
+    init_hash_seed                = 17
   };
 
   uint                        _worker_id;
@@ -858,9 +893,10 @@
   // It pushes an object on the local queue.
   inline void push(oop obj);
 
-  // These two move entries to/from the global stack.
+  // Move entries to the global stack.
   void move_entries_to_global_stack();
-  void get_entries_from_global_stack();
+  // Move entries from the global stack, return true if we were successful to do so.
+  bool get_entries_from_global_stack();
 
   // It pops and scans objects from the local queue. If partially is
   // true, then it stops when the queue size is of a given limit. If
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -89,14 +89,28 @@
 
 #undef check_mark
 
+#ifndef PRODUCT
 template<typename Fn>
-inline void G1CMMarkStack::iterate(Fn fn) {
+inline void G1CMMarkStack::iterate(Fn fn) const {
   assert_at_safepoint(true);
-  assert(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
-  for (size_t i = 0; i < _index; ++i) {
-    fn(_base[i]);
+
+  size_t num_chunks = 0;
+
+  OopChunk* cur = _chunk_list;
+  while (cur != NULL) {
+    guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
+
+    for (size_t i = 0; i < OopsPerChunk; ++i) {
+      if (cur->data[i] == NULL) {
+        break;
+      }
+      fn(cur->data[i]);
+    }
+    cur = cur->next;
+    num_chunks++;
   }
 }
+#endif
 
 // It scans an object and visits its children.
 inline void G1CMTask::scan_object(oop obj) { process_grey_object<true>(obj); }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -34,7 +34,6 @@
 class G1ConcurrentMark;
 class DirtyCardToOopClosure;
 class G1CMBitMap;
-class G1CMMarkStack;
 class G1ParScanThreadState;
 class G1CMTask;
 class ReferenceProcessor;
--- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -24,8 +24,10 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1PageBasedVirtualSpace.hpp"
+#include "gc/shared/workgroup.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/bitMap.inline.hpp"
@@ -177,7 +179,7 @@
   guarantee(start_page < end_page,
             "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
 
-  os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page));
+  os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size);
 }
 
 bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) {
@@ -198,9 +200,6 @@
   }
   _committed.set_range(start_page, end_page);
 
-  if (AlwaysPreTouch) {
-    pretouch_internal(start_page, end_page);
-  }
   return zero_filled;
 }
 
@@ -227,6 +226,53 @@
   _committed.clear_range(start_page, end_page);
 }
 
+class G1PretouchTask : public AbstractGangTask {
+private:
+  char* volatile _cur_addr;
+  char* const _start_addr;
+  char* const _end_addr;
+  size_t const _page_size;
+public:
+  G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
+    AbstractGangTask("G1 PreTouch",
+                     Universe::is_fully_initialized() ? GCId::current_raw() :
+                                                        // During VM initialization there is
+                                                        // no GC cycle that this task can be
+                                                        // associated with.
+                                                        GCId::undefined()),
+    _cur_addr(start_address),
+    _start_addr(start_address),
+    _end_addr(end_address),
+    _page_size(page_size) {
+  }
+
+  virtual void work(uint worker_id) {
+    size_t const actual_chunk_size = MAX2(chunk_size(), _page_size);
+    while (true) {
+      char* touch_addr = (char*)Atomic::add_ptr((intptr_t)actual_chunk_size, (volatile void*) &_cur_addr) - actual_chunk_size;
+      if (touch_addr < _start_addr || touch_addr >= _end_addr) {
+        break;
+      }
+      char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char)));
+      os::pretouch_memory(touch_addr, end_addr, _page_size);
+    }
+  }
+
+  static size_t chunk_size() { return PreTouchParallelChunkSize; }
+};
+
+void G1PageBasedVirtualSpace::pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang) {
+  guarantee(pretouch_gang != NULL, "No pretouch gang specified.");
+
+  size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size));
+
+  uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers());
+  G1PretouchTask cl(page_start(start_page), bounded_end_addr(start_page + size_in_pages), _page_size);
+  log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.",
+                      cl.name(), num_workers, num_chunks, size_in_pages * _page_size);
+  pretouch_gang->run_task(&cl, num_workers);
+}
+
 bool G1PageBasedVirtualSpace::contains(const void* p) const {
   return _low_boundary <= (const char*) p && (const char*) p < _high_boundary;
 }
--- a/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -30,6 +30,8 @@
 #include "memory/virtualspace.hpp"
 #include "utilities/bitMap.hpp"
 
+class WorkGang;
+
 // Virtual space management helper for a virtual space with an OS page allocation
 // granularity.
 // (De-)Allocation requests are always OS page aligned by passing a page index
@@ -117,6 +119,8 @@
   // Uncommit the given area of pages starting at start being size_in_pages large.
   void uncommit(size_t start_page, size_t size_in_pages);
 
+  void pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang = NULL);
+
   // Initialize the given reserved space with the given base address and the size
   // actually used.
   // Prefer to commit in page_size chunks.
--- a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -66,8 +66,12 @@
     guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity");
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions) {
-    bool zero_filled = _storage.commit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
+  virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
+    size_t const start_page = (size_t)start_idx * _pages_per_region;
+    bool zero_filled = _storage.commit(start_page, num_regions * _pages_per_region);
+    if (AlwaysPreTouch) {
+      _storage.pretouch(start_page, num_regions * _pages_per_region, pretouch_gang);
+    }
     _commit_map.set_range(start_idx, start_idx + num_regions);
     fire_on_commit(start_idx, num_regions, zero_filled);
   }
@@ -110,19 +114,38 @@
     _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_size_up(rs.size(), page_size)), page_size);
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions) {
+  virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
+    size_t const NoPage = ~(size_t)0;
+
+    size_t first_committed = NoPage;
+    size_t num_committed = 0;
+
+    bool all_zero_filled = true;
+
     for (uint i = start_idx; i < start_idx + num_regions; i++) {
       assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i);
       size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
+
       bool zero_filled = false;
       if (old_refcount == 0) {
+        if (first_committed == NoPage) {
+          first_committed = idx;
+          num_committed = 1;
+        } else {
+          num_committed++;
+        }
         zero_filled = _storage.commit(idx, 1);
       }
+      all_zero_filled &= zero_filled;
+
       _refcounts.set_by_index(idx, old_refcount + 1);
       _commit_map.set_bit(i);
-      fire_on_commit(i, 1, zero_filled);
     }
+    if (AlwaysPreTouch && num_committed > 0) {
+      _storage.pretouch(first_committed, num_committed, pretouch_gang);
+    }
+    fire_on_commit(start_idx, num_regions, all_zero_filled);
   }
 
   virtual void uncommit_regions(uint start_idx, size_t num_regions) {
--- a/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -29,6 +29,8 @@
 #include "memory/allocation.hpp"
 #include "utilities/debug.hpp"
 
+class WorkGang;
+
 class G1MappingChangedListener VALUE_OBJ_CLASS_SPEC {
  public:
   // Fired after commit of the memory, i.e. the memory this listener is registered
@@ -68,7 +70,7 @@
     return _commit_map.at(idx);
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions = 1) = 0;
+  virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0;
   virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
 
   // Creates an appropriate G1RegionToSpaceMapper for the given parameters.
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -353,35 +353,6 @@
 }
 
 HeapWord*
-HeapRegion::object_iterate_mem_careful(MemRegion mr,
-                                                 ObjectClosure* cl) {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  // We used to use "block_start_careful" here.  But we're actually happy
-  // to update the BOT while we do this...
-  HeapWord* cur = block_start(mr.start());
-  mr = mr.intersection(used_region());
-  if (mr.is_empty()) return NULL;
-  // Otherwise, find the obj that extends onto mr.start().
-
-  assert(cur <= mr.start()
-         && (oop(cur)->klass_or_null() == NULL ||
-             cur + oop(cur)->size() > mr.start()),
-         "postcondition of block_start");
-  oop obj;
-  while (cur < mr.end()) {
-    obj = oop(cur);
-    if (obj->klass_or_null() == NULL) {
-      // Ran into an unparseable point.
-      return cur;
-    } else if (!g1h->is_obj_dead(obj)) {
-      cl->do_object(obj);
-    }
-    cur += block_size(cur);
-  }
-  return NULL;
-}
-
-HeapWord*
 HeapRegion::
 oops_on_card_seq_iterate_careful(MemRegion mr,
                                  FilterOutOfRegionClosure* cl,
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -653,17 +653,6 @@
     }
   }
 
-  // Requires that "mr" be entirely within the region.
-  // Apply "cl->do_object" to all objects that intersect with "mr".
-  // If the iteration encounters an unparseable portion of the region,
-  // or if "cl->abort()" is true after a closure application,
-  // terminate the iteration and return the address of the start of the
-  // subregion that isn't done.  (The two can be distinguished by querying
-  // "cl->abort()".)  Return of "NULL" indicates that the iteration
-  // completed.
-  HeapWord*
-  object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
-
   // filter_young: if true and the region is a young region then we
   // skip the iteration.
   // card_ptr: if not NULL, and we decide that the card is not young
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -72,22 +72,22 @@
   return g1h->new_heap_region(hrm_index, mr);
 }
 
-void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
+void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
   guarantee(num_regions > 0, "Must commit more than zero regions");
   guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
 
   _num_committed += (uint)num_regions;
 
-  _heap_mapper->commit_regions(index, num_regions);
+  _heap_mapper->commit_regions(index, num_regions, pretouch_gang);
 
   // Also commit auxiliary data
-  _prev_bitmap_mapper->commit_regions(index, num_regions);
-  _next_bitmap_mapper->commit_regions(index, num_regions);
+  _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
+  _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
 
-  _bot_mapper->commit_regions(index, num_regions);
-  _cardtable_mapper->commit_regions(index, num_regions);
+  _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
+  _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
 
-  _card_counts_mapper->commit_regions(index, num_regions);
+  _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
 }
 
 void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
@@ -117,9 +117,9 @@
   _card_counts_mapper->uncommit_regions(start, num_regions);
 }
 
-void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
+void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
   guarantee(num_regions > 0, "No point in calling this for zero regions");
-  commit_regions(start, num_regions);
+  commit_regions(start, num_regions, pretouch_gang);
   for (uint i = start; i < start + num_regions; i++) {
     if (_regions.get_by_index(i) == NULL) {
       HeapRegion* new_hr = new_heap_region(i);
@@ -163,11 +163,11 @@
   return MemoryUsage(0, used_sz, committed_sz, committed_sz);
 }
 
-uint HeapRegionManager::expand_by(uint num_regions) {
-  return expand_at(0, num_regions);
+uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
+  return expand_at(0, num_regions, pretouch_workers);
 }
 
-uint HeapRegionManager::expand_at(uint start, uint num_regions) {
+uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
   if (num_regions == 0) {
     return 0;
   }
@@ -181,7 +181,7 @@
   while (expanded < num_regions &&
          (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
     uint to_expand = MIN2(num_regions - expanded, num_last_found);
-    make_regions_available(idx_last_found, to_expand);
+    make_regions_available(idx_last_found, to_expand, pretouch_workers);
     expanded += to_expand;
     cur = idx_last_found + num_last_found + 1;
   }
--- a/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,6 +34,7 @@
 class HeapRegionClosure;
 class HeapRegionClaimer;
 class FreeRegionList;
+class WorkGang;
 
 class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
  protected:
@@ -94,10 +95,10 @@
   HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
   HeapWord* heap_end() const {return _regions.end_address_mapped(); }
 
-  void make_regions_available(uint index, uint num_regions = 1);
+  void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL);
 
   // Pass down commit calls to the VirtualSpace.
-  void commit_regions(uint index, size_t num_regions = 1);
+  void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL);
   void uncommit_regions(uint index, size_t num_regions = 1);
 
   // Notify other data structures about change in the heap layout.
@@ -209,12 +210,12 @@
   // HeapRegions, or re-use existing ones. Returns the number of regions the
   // sequence was expanded by. If a HeapRegion allocation fails, the resulting
   // number of regions might be smaller than what's desired.
-  uint expand_by(uint num_regions);
+  uint expand_by(uint num_regions, WorkGang* pretouch_workers = NULL);
 
   // Makes sure that the regions from start to start+num_regions-1 are available
   // for allocation. Returns the number of regions that were committed to achieve
   // this.
-  uint expand_at(uint start, uint num_regions);
+  uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers = NULL);
 
   // Find a contiguous set of empty regions of length num. Returns the start index of
   // that set, or G1_NO_HRM_INDEX.
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -304,9 +304,6 @@
   inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
   inline static oop class_allocate(KlassHandle klass, int size, TRAPS);
 
-  inline static void post_allocation_install_obj_klass(KlassHandle klass,
-                                                       oop obj);
-
   // Raw memory allocation facilities
   // The obj and array allocate methods are covers for these methods.
   // mem_allocate() should never be
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.inline.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -41,14 +41,22 @@
 // Inline allocation implementations.
 
 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
-                                                 HeapWord* obj) {
-  post_allocation_setup_no_klass_install(klass, obj);
-  post_allocation_install_obj_klass(klass, oop(obj));
+                                                 HeapWord* obj_ptr) {
+  post_allocation_setup_no_klass_install(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
+#if ! INCLUDE_ALL_GCS
+  obj->set_klass(klass());
+#else
+  // Need a release store to ensure array/class length, mark word, and
+  // object zeroing are visible before setting the klass non-NULL, for
+  // concurrent collectors.
+  obj->release_set_klass(klass());
+#endif
 }
 
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                           HeapWord* objPtr) {
-  oop obj = (oop)objPtr;
+                                                           HeapWord* obj_ptr) {
+  oop obj = (oop)obj_ptr;
 
   assert(obj != NULL, "NULL object pointer");
   if (UseBiasedLocking && (klass() != NULL)) {
@@ -59,18 +67,6 @@
   }
 }
 
-void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
-                                                   oop obj) {
-  // These asserts are kind of complicated because of klassKlass
-  // and the beginning of the world.
-  assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
-  assert(klass() == NULL || klass()->is_klass(), "not a klass");
-  assert(obj != NULL, "NULL object pointer");
-  obj->set_klass(klass());
-  assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
-         "missing klass");
-}
-
 // Support for jvmti and dtrace
 inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
   // support low memory notifications (no-op if not enabled)
@@ -88,25 +84,26 @@
 }
 
 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
-                                              HeapWord* obj,
+                                              HeapWord* obj_ptr,
                                               int size) {
-  post_allocation_setup_common(klass, obj);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
   assert(Universe::is_bootstrapping() ||
-         !((oop)obj)->is_array(), "must not be an array");
+         !obj->is_array(), "must not be an array");
   // notify jvmti and dtrace
-  post_allocation_notify(klass, (oop)obj, size);
+  post_allocation_notify(klass, obj, size);
 }
 
 void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
-                                                HeapWord* obj,
+                                                HeapWord* obj_ptr,
                                                 int size) {
-  // Set oop_size field before setting the _klass field
-  // in post_allocation_setup_common() because the klass field
-  // indicates that the object is parsable by concurrent GC.
-  oop new_cls = (oop)obj;
+  // Set oop_size field before setting the _klass field because a
+  // non-NULL _klass field indicates that the object is parsable by
+  // concurrent GC.
+  oop new_cls = (oop)obj_ptr;
   assert(size > 0, "oop_size must be positive.");
   java_lang_Class::set_oop_size(new_cls, size);
-  post_allocation_setup_common(klass, obj);
+  post_allocation_setup_common(klass, obj_ptr);
   assert(Universe::is_bootstrapping() ||
          !new_cls->is_array(), "must not be an array");
   // notify jvmti and dtrace
@@ -114,15 +111,15 @@
 }
 
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
-                                                HeapWord* obj,
+                                                HeapWord* obj_ptr,
                                                 int length) {
-  // Set array length before setting the _klass field
-  // in post_allocation_setup_common() because the klass field
-  // indicates that the object is parsable by concurrent GC.
+  // Set array length before setting the _klass field because a
+  // non-NULL klass field indicates that the object is parsable by
+  // concurrent GC.
   assert(length >= 0, "length should be non-negative");
-  ((arrayOop)obj)->set_length(length);
-  post_allocation_setup_common(klass, obj);
-  oop new_obj = (oop)obj;
+  ((arrayOop)obj_ptr)->set_length(length);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop new_obj = (oop)obj_ptr;
   assert(new_obj->is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, new_obj, new_obj->size());
--- a/hotspot/src/share/vm/gc/shared/workgroup.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/gc/shared/workgroup.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -62,7 +62,12 @@
   AbstractGangTask(const char* name) :
     _name(name),
     _gc_id(GCId::current_raw())
- {}
+  {}
+
+  AbstractGangTask(const char* name, const uint gc_id) :
+    _name(name),
+    _gc_id(gc_id)
+  {}
 
   // The abstract work method.
   // The argument tells you which member of the gang you are.
--- a/hotspot/src/share/vm/memory/allocation.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -738,6 +738,7 @@
   static size_t size_for(size_t length);
 
  public:
+  static E* allocate_or_null(size_t length);
   static E* allocate(size_t length);
   static void free(E* addr, size_t length);
 };
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -153,6 +153,24 @@
 }
 
 template <class E, MEMFLAGS F>
+E* MmapArrayAllocator<E, F>::allocate_or_null(size_t length) {
+  size_t size = size_for(length);
+  int alignment = os::vm_allocation_granularity();
+
+  char* addr = os::reserve_memory(size, NULL, alignment, F);
+  if (addr == NULL) {
+    return NULL;
+  }
+
+  if (os::commit_memory(addr, size, !ExecMem, "Allocator (commit)")) {
+    return (E*)addr;
+  } else {
+    os::release_memory(addr, size);
+    return NULL;
+  }
+}
+
+template <class E, MEMFLAGS F>
 E* MmapArrayAllocator<E, F>::allocate(size_t length) {
   size_t size = size_for(length);
   int alignment = os::vm_allocation_granularity();
--- a/hotspot/src/share/vm/memory/filemap.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -649,7 +649,7 @@
 
 // Memory map a region in the address space.
 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode",
-                                            "String1", "String2" };
+                                            "String1", "String2", "OptionalData" };
 
 char* FileMapInfo::map_region(int i) {
   assert(!MetaspaceShared::is_string_region(i), "sanity");
--- a/hotspot/src/share/vm/memory/filemap.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -252,10 +252,27 @@
   bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
   void print_shared_spaces() NOT_CDS_RETURN;
 
+  // The ro+rw+md+mc spaces size
+  static size_t core_spaces_size() {
+    return align_size_up((SharedReadOnlySize + SharedReadWriteSize +
+                          SharedMiscDataSize + SharedMiscCodeSize),
+                          os::vm_allocation_granularity());
+  }
+
+  // The estimated optional space size.
+  //
+  // Currently the optional space only has archived class bytes.
+  // The core_spaces_size is the size of all class metadata, which is a good
+  // estimate of the total class bytes to be archived. Only the portion
+  // containing data is written out to the archive and mapped at runtime.
+  // There is no memory waste due to unused portion in optional space.
+  static size_t optional_space_size() {
+    return core_spaces_size();
+  }
+
+  // Total shared_spaces size includes the ro, rw, md, mc and od spaces
   static size_t shared_spaces_size() {
-    return align_size_up(SharedReadOnlySize + SharedReadWriteSize +
-                         SharedMiscDataSize + SharedMiscCodeSize,
-                         os::vm_allocation_granularity());
+    return core_spaces_size() + optional_space_size();
   }
 
   // Stop CDS sharing and unmap CDS regions.
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -3172,36 +3172,28 @@
       address cds_address = NULL;
       FileMapInfo* mapinfo = new FileMapInfo();
 
-      if (JvmtiExport::should_post_class_file_load_hook()) {
-        // Currently CDS does not support JVMTI CFLH when loading shared class.
-        // If JvmtiExport::should_post_class_file_load_hook is already enabled,
-        // just disable UseSharedSpaces.
-        FileMapInfo::fail_continue("Tool agent requires sharing to be disabled.");
-        delete mapinfo;
-      } else {
-        // Open the shared archive file, read and validate the header. If
-        // initialization fails, shared spaces [UseSharedSpaces] are
-        // disabled and the file is closed.
-        // Map in spaces now also
-        if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
-          cds_total = FileMapInfo::shared_spaces_size();
-          cds_address = (address)mapinfo->header()->region_addr(0);
+      // Open the shared archive file, read and validate the header. If
+      // initialization fails, shared spaces [UseSharedSpaces] are
+      // disabled and the file is closed.
+      // Map in spaces now also
+      if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
+        cds_total = FileMapInfo::shared_spaces_size();
+        cds_address = (address)mapinfo->header()->region_addr(0);
 #ifdef _LP64
-          if (using_class_space()) {
-            char* cds_end = (char*)(cds_address + cds_total);
-            cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
-            // If UseCompressedClassPointers is set then allocate the metaspace area
-            // above the heap and above the CDS area (if it exists).
-            allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
-            // Map the shared string space after compressed pointers
-            // because it relies on compressed class pointers setting to work
-            mapinfo->map_string_regions();
-          }
+        if (using_class_space()) {
+          char* cds_end = (char*)(cds_address + cds_total);
+          cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
+          // If UseCompressedClassPointers is set then allocate the metaspace area
+          // above the heap and above the CDS area (if it exists).
+          allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
+          // Map the shared string space after compressed pointers
+          // because it relies on compressed class pointers setting to work
+          mapinfo->map_string_regions();
+        }
 #endif // _LP64
-        } else {
-          assert(!mapinfo->is_open() && !UseSharedSpaces,
-                 "archive file not closed or shared spaces not disabled.");
-        }
+      } else {
+        assert(!mapinfo->is_open() && !UseSharedSpaces,
+               "archive file not closed or shared spaces not disabled.");
       }
     }
 #endif // INCLUDE_CDS
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -65,6 +65,7 @@
 size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
 SharedMiscRegion MetaspaceShared::_mc;
 SharedMiscRegion MetaspaceShared::_md;
+SharedMiscRegion MetaspaceShared::_od;
 
 void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size,  SharedSpaceType space_type) {
   _vs.initialize(rs, committed_byte_size);
@@ -93,16 +94,24 @@
   assert(DumpSharedSpaces, "dump time only");
   _shared_rs = rs;
 
-  // Split up and initialize the misc code and data spaces
+  size_t core_spaces_size = FileMapInfo::core_spaces_size();
   size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
-  ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size);
-  ReservedSpace misc_section = _shared_rs->last_part(metadata_size);
+
+  // Split into the core and optional sections
+  ReservedSpace core_data = _shared_rs->first_part(core_spaces_size);
+  ReservedSpace optional_data = _shared_rs->last_part(core_spaces_size);
 
-  // Now split into misc sections.
+  // The RO/RW and the misc sections
+  ReservedSpace shared_ro_rw = core_data.first_part(metadata_size);
+  ReservedSpace misc_section = core_data.last_part(metadata_size);
+
+  // Now split the misc code and misc data sections.
   ReservedSpace md_rs   = misc_section.first_part(SharedMiscDataSize);
   ReservedSpace mc_rs   = misc_section.last_part(SharedMiscDataSize);
+
   _md.initialize(md_rs, SharedMiscDataSize, SharedMiscData);
-  _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData);
+  _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscCode);
+  _od.initialize(optional_data, metadata_size, SharedOptional);
 }
 
 // Read/write a data stream for restoring/preserving metadata pointers and
@@ -521,6 +530,7 @@
   GrowableArray<Klass*> *_class_promote_order;
   VirtualSpace _md_vs;
   VirtualSpace _mc_vs;
+  VirtualSpace _od_vs;
   GrowableArray<MemRegion> *_string_regions;
 
 public:
@@ -598,15 +608,19 @@
   remove_unshareable_in_classes();
   tty->print_cr("done. ");
 
-  // Set up the share data and shared code segments.
+  // Set up the misc data, misc code and optional data segments.
   _md_vs = *MetaspaceShared::misc_data_region()->virtual_space();
   _mc_vs = *MetaspaceShared::misc_code_region()->virtual_space();
+  _od_vs = *MetaspaceShared::optional_data_region()->virtual_space();
   char* md_low = _md_vs.low();
   char* md_top = MetaspaceShared::misc_data_region()->alloc_top();
   char* md_end = _md_vs.high();
   char* mc_low = _mc_vs.low();
   char* mc_top = MetaspaceShared::misc_code_region()->alloc_top();
   char* mc_end = _mc_vs.high();
+  char* od_low = _od_vs.low();
+  char* od_top = MetaspaceShared::optional_data_region()->alloc_top();
+  char* od_end = _od_vs.high();
 
   // Reserve space for the list of Klass*s whose vtables are used
   // for patching others as needed.
@@ -661,28 +675,32 @@
   const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
   const size_t md_alloced = md_end-md_low;
   const size_t mc_alloced = mc_end-mc_low;
+  const size_t od_alloced = od_end-od_low;
   const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced
-                             + ss_bytes;
+                             + ss_bytes + od_alloced;
 
   // Occupied size of each space.
   const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t md_bytes = size_t(md_top - md_low);
   const size_t mc_bytes = size_t(mc_top - mc_low);
+  const size_t od_bytes = size_t(od_top - od_low);
 
   // Percent of total size
-  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes;
+  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes + od_bytes;
   const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
   const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
   const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
   const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
   const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0;
+  const double od_t_perc = od_bytes / double(total_bytes) * 100.0;
 
   // Percent of fullness of each space
   const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
   const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
   const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
   const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
+  const double od_u_perc = od_bytes / double(od_alloced) * 100.0;
   const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
 
 #define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT
@@ -691,6 +709,7 @@
   tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low));
   tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low));
   tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes,   100.0,     p2i(ss_low));
+  tty->print_cr(fmt_space, "od", od_bytes, od_t_perc, od_alloced, od_u_perc, p2i(od_low));
   tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
@@ -734,6 +753,10 @@
                           SharedMiscCodeSize,
                           true, true);
     mapinfo->write_string_regions(_string_regions);
+    mapinfo->write_region(MetaspaceShared::od, _od_vs.low(),
+                          pointer_delta(od_top, _od_vs.low(), sizeof(char)),
+                          pointer_delta(od_end, _od_vs.low(), sizeof(char)),
+                          true, false);
   }
 
   mapinfo->close();
@@ -1049,8 +1072,6 @@
 
 
 // Map shared spaces at requested addresses and return if succeeded.
-// Need to keep the bounds of the ro and rw space for the Metaspace::contains
-// call, or is_in_shared_space.
 bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
   size_t image_alignment = mapinfo->alignment();
 
@@ -1068,6 +1089,7 @@
   char* _rw_base = NULL;
   char* _md_base = NULL;
   char* _mc_base = NULL;
+  char* _od_base = NULL;
 
   // Map each shared region
   if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
@@ -1078,6 +1100,8 @@
       mapinfo->verify_region_checksum(md) &&
       (_mc_base = mapinfo->map_region(mc)) != NULL &&
       mapinfo->verify_region_checksum(mc) &&
+      (_od_base = mapinfo->map_region(od)) != NULL &&
+      mapinfo->verify_region_checksum(od) &&
       (image_alignment == (size_t)max_alignment()) &&
       mapinfo->validate_classpath_entry_table()) {
     // Success (no need to do anything)
@@ -1089,6 +1113,7 @@
     if (_rw_base != NULL) mapinfo->unmap_region(rw);
     if (_md_base != NULL) mapinfo->unmap_region(md);
     if (_mc_base != NULL) mapinfo->unmap_region(mc);
+    if (_od_base != NULL) mapinfo->unmap_region(od);
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -132,6 +132,7 @@
   // Used only during dumping.
   static SharedMiscRegion _md;
   static SharedMiscRegion _mc;
+  static SharedMiscRegion _od;
  public:
   enum {
     vtbl_list_size         = DEFAULT_VTBL_LIST_SIZE,
@@ -148,7 +149,10 @@
     max_strings = 2, // max number of string regions in string space
     num_non_strings = 4, // number of non-string regions
     first_string = num_non_strings, // index of first string region
-    n_regions = max_strings + num_non_strings // total number of regions
+    // The optional data region is the last region.
+    // Currently it only contains class file data.
+    od = max_strings + num_non_strings,
+    n_regions = od + 1 // total number of regions
   };
 
   // Accessor functions to save shared space created for metadata, which has
@@ -222,9 +226,10 @@
   static int count_class(const char* classlist_file);
   static void estimate_regions_size() NOT_CDS_RETURN;
 
-  // Allocate a block of memory from the "mc" or "md" regions.
+  // Allocate a block of memory from the "mc", "md", or "od" regions.
   static char* misc_code_space_alloc(size_t num_bytes) {  return _mc.alloc(num_bytes); }
   static char* misc_data_space_alloc(size_t num_bytes) {  return _md.alloc(num_bytes); }
+  static char* optional_data_space_alloc(size_t num_bytes) { return _od.alloc(num_bytes); }
 
   static address cds_i2i_entry_code_buffers(size_t total_size);
 
@@ -243,5 +248,9 @@
     assert(DumpSharedSpaces, "used during dumping only");
     return &_md;
   }
+  static SharedMiscRegion* optional_data_region() {
+    assert(DumpSharedSpaces, "used during dumping only");
+    return &_od;
+  }
 };
 #endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -41,6 +41,7 @@
 #include "memory/heapInspection.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/fieldStreams.hpp"
@@ -1972,11 +1973,6 @@
     m->remove_unshareable_info();
   }
 
-  // cached_class_file might be pointing to a malloc'ed buffer allocated by
-  // event-based tracing code at CDS dump time. It's not usable at runtime
-  // so let's clear it.
-  set_cached_class_file(NULL);
-
   // do array classes also.
   array_klasses_do(remove_unshareable_in_class);
 }
@@ -2070,6 +2066,7 @@
 }
 
 void InstanceKlass::release_C_heap_structures() {
+  assert(!this->is_shared(), "should not be called for a shared class");
 
   // Can't release the constant pool here because the constant pool can be
   // deallocated separately from the InstanceKlass for default methods and
@@ -2250,8 +2247,8 @@
         // the java.base module.  If a non-java.base package is erroneously placed
         // in the java.base module it will be caught later when java.base
         // is defined by ModuleEntryTable::verify_javabase_packages check.
-        assert(ModuleEntryTable::javabase_module() != NULL, "java.base module is NULL");
-        _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_module());
+        assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "java.base module is NULL");
+        _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_moduleEntry());
       } else {
         assert(loader_data->modules()->unnamed_module() != NULL, "unnamed module is NULL");
         _package_entry = loader_data->packages()->lookup(pkg_name,
@@ -3653,6 +3650,15 @@
 }
 
 #if INCLUDE_JVMTI
+JvmtiCachedClassFileData* InstanceKlass::get_cached_class_file() {
+  if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+    // Ignore the archived class stream data
+    return NULL;
+  } else {
+    return _cached_class_file;
+  }
+}
+
 jint InstanceKlass::get_cached_class_file_len() {
   return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
 }
@@ -3660,4 +3666,15 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
+
+#if INCLUDE_CDS
+JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() {
+  assert(this->is_shared(), "class should be shared");
+  if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+    return _cached_class_file;
+  } else {
+    return NULL;
+  }
+}
 #endif
+#endif
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -783,7 +783,7 @@
   void set_cached_class_file(JvmtiCachedClassFileData *data) {
     _cached_class_file = data;
   }
-  JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
+  JvmtiCachedClassFileData * get_cached_class_file();
   jint get_cached_class_file_len();
   unsigned char * get_cached_class_file_bytes();
 
@@ -795,6 +795,13 @@
     return _jvmti_cached_class_field_map;
   }
 
+#if INCLUDE_CDS
+  void set_archived_class_data(JvmtiCachedClassFileData* data) {
+    _cached_class_file = data;
+  }
+
+  JvmtiCachedClassFileData * get_archived_class_data();
+#endif // INCLUDE_CDS
 #else // INCLUDE_JVMTI
 
   static void purge_previous_versions(InstanceKlass* ik) { return; };
--- a/hotspot/src/share/vm/oops/klass.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -530,7 +530,7 @@
       InstanceKlass* ik = (InstanceKlass*) k;
       module_entry = ik->module();
     } else {
-      module_entry = ModuleEntryTable::javabase_module();
+      module_entry = ModuleEntryTable::javabase_moduleEntry();
     }
     // Obtain java.lang.reflect.Module, if available
     Handle module_handle(THREAD, ((module_entry != NULL) ? JNIHandles::resolve(module_entry->module()) : (oop)NULL));
--- a/hotspot/src/share/vm/oops/oop.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -87,6 +87,7 @@
   inline narrowKlass* compressed_klass_addr();
 
   inline void set_klass(Klass* k);
+  inline void release_set_klass(Klass* k);
 
   // For klass field compression
   inline int klass_gap() const;
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -129,10 +129,14 @@
   return &_metadata._compressed_klass;
 }
 
+#define CHECK_SET_KLASS(k)                                                \
+  do {                                                                    \
+    assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass");      \
+    assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \
+  } while (0)
+
 void oopDesc::set_klass(Klass* k) {
-  // since klasses are promoted no store check is needed
-  assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
-  assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
+  CHECK_SET_KLASS(k);
   if (UseCompressedClassPointers) {
     *compressed_klass_addr() = Klass::encode_klass_not_null(k);
   } else {
@@ -140,6 +144,18 @@
   }
 }
 
+void oopDesc::release_set_klass(Klass* k) {
+  CHECK_SET_KLASS(k);
+  if (UseCompressedClassPointers) {
+    OrderAccess::release_store(compressed_klass_addr(),
+                               Klass::encode_klass_not_null(k));
+  } else {
+    OrderAccess::release_store_ptr(klass_addr(), k);
+  }
+}
+
+#undef CHECK_SET_KLASS
+
 int oopDesc::klass_gap() const {
   return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
 }
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -72,7 +72,7 @@
   null_loader_data->add_class(ak);
 
   // Call complete_create_array_klass after all instance variables have been initialized.
-  complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_module(), CHECK_NULL);
+  complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL);
 
   return ak;
 }
@@ -347,7 +347,7 @@
 
 // A TypeArrayKlass is an array of a primitive type, its defining module is java.base
 ModuleEntry* TypeArrayKlass::module() const {
-  return ModuleEntryTable::javabase_module();
+  return ModuleEntryTable::javabase_moduleEntry();
 }
 
 PackageEntry* TypeArrayKlass::package() const {
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -272,6 +272,31 @@
 
 // Get/PutObject must be special-cased, since it works with handles.
 
+// We could be accessing the referent field in a reference
+// object. If G1 is enabled then we need to register non-null
+// referent with the SATB barrier.
+
+#if INCLUDE_ALL_GCS
+static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
+  if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
+    Klass* k = o->klass();
+    if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
+      assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
+      return true;
+    }
+  }
+  return false;
+}
+#endif
+
+static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
+#if INCLUDE_ALL_GCS
+  if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
+    G1SATBCardTableModRefBS::enqueue(v);
+  }
+#endif
+}
+
 // These functions allow a null base pointer with an arbitrary address.
 // But if the base pointer is non-null, the offset should make some sense.
 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
@@ -286,34 +311,9 @@
     v = *(oop*)index_oop_from_field_offset_long(p, offset);
   }
 
-  jobject ret = JNIHandles::make_local(env, v);
-
-#if INCLUDE_ALL_GCS
-  // We could be accessing the referent field in a reference
-  // object. If G1 is enabled then we need to register non-null
-  // referent with the SATB barrier.
-  if (UseG1GC) {
-    bool needs_barrier = false;
+  ensure_satb_referent_alive(p, offset, v);
 
-    if (ret != NULL) {
-      if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
-        oop o = JNIHandles::resolve(obj);
-        Klass* k = o->klass();
-        if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
-          assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
-          needs_barrier = true;
-        }
-      }
-    }
-
-    if (needs_barrier) {
-      oop referent = JNIHandles::resolve(ret);
-      G1SATBCardTableModRefBS::enqueue(referent);
-    }
-  }
-#endif // INCLUDE_ALL_GCS
-
-  return ret;
+  return JNIHandles::make_local(env, v);
 } UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
@@ -344,6 +344,8 @@
     (void)const_cast<oop&>(v = *(volatile oop*) addr);
   }
 
+  ensure_satb_referent_alive(p, offset, v);
+
   OrderAccess::acquire();
   return JNIHandles::make_local(env, v);
 } UNSAFE_END
--- a/hotspot/src/share/vm/runtime/globals.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1596,6 +1596,10 @@
   product(bool, AlwaysPreTouch, false,                                      \
           "Force all freshly committed pages to be pre-touched")            \
                                                                             \
+  product(size_t, PreTouchParallelChunkSize, 1 * G,                         \
+          "Per-thread chunk size for parallel memory pre-touch.")           \
+          range(1, SIZE_MAX / 2)                                            \
+                                                                            \
   product_pd(size_t, CMSYoungGenPerWorker,                                  \
           "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -77,6 +77,8 @@
 Mutex*   DirtyCardQ_FL_lock           = NULL;
 Monitor* DirtyCardQ_CBL_mon           = NULL;
 Mutex*   Shared_DirtyCardQ_lock       = NULL;
+Mutex*   MarkStackFreeList_lock       = NULL;
+Mutex*   MarkStackChunkList_lock      = NULL;
 Mutex*   ParGCRareEvent_lock          = NULL;
 Mutex*   DerivedPointerTableGC_lock   = NULL;
 Mutex*   Compile_lock                 = NULL;
@@ -194,6 +196,9 @@
 
     def(StringDedupQueue_lock      , Monitor, leaf,        true,  Monitor::_safepoint_check_never);
     def(StringDedupTable_lock      , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
+
+    def(MarkStackFreeList_lock     , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
+    def(MarkStackChunkList_lock    , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
   }
   def(ParGCRareEvent_lock          , Mutex  , leaf     ,   true,  Monitor::_safepoint_check_sometimes);
   def(DerivedPointerTableGC_lock   , Mutex,   leaf,        true,  Monitor::_safepoint_check_never);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -81,7 +81,8 @@
 extern Mutex*   Shared_DirtyCardQ_lock;          // Lock protecting dirty card
                                                  // queue shared by
                                                  // non-Java threads.
-                                                 // (see option ExplicitGCInvokesConcurrent)
+extern Mutex*   MarkStackFreeList_lock;          // Protects access to the global mark stack free list.
+extern Mutex*   MarkStackChunkList_lock;         // Protects access to the global mark stack chunk list.
 extern Mutex*   ParGCRareEvent_lock;             // Synchronizes various (rare) parallel GC ops.
 extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
 extern Monitor* MethodCompileQueue_lock;         // a lock held when method compilations are enqueued, dequeued
--- a/hotspot/src/share/vm/runtime/os.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1705,8 +1705,8 @@
   return res;
 }
 
-void os::pretouch_memory(void* start, void* end) {
-  for (volatile char *p = (char*)start; p < (char*)end; p += os::vm_page_size()) {
+void os::pretouch_memory(void* start, void* end, size_t page_size) {
+  for (volatile char *p = (char*)start; p < (char*)end; p += page_size) {
     *p = 0;
   }
 }
--- a/hotspot/src/share/vm/runtime/os.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -324,7 +324,7 @@
   // to make the OS back the memory range with actual memory.
   // Current implementation may not touch the last page if unaligned addresses
   // are passed.
-  static void   pretouch_memory(void* start, void* end);
+  static void   pretouch_memory(void* start, void* end, size_t page_size = vm_page_size());
 
   enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
   static bool   protect_memory(char* addr, size_t bytes, ProtType prot,
--- a/hotspot/src/share/vm/utilities/debug.cpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Mon Oct 10 13:31:48 2016 -0700
@@ -282,6 +282,12 @@
 }
 
 void report_out_of_shared_space(SharedSpaceType shared_space) {
+  if (shared_space == SharedOptional) {
+    // The estimated shared_optional_space size is large enough
+    // for all class bytes.  It should not run out of space.
+    ShouldNotReachHere();
+  }
+
   static const char* name[] = {
     "shared read only space",
     "shared read write space",
--- a/hotspot/src/share/vm/utilities/debug.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/utilities/debug.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -271,7 +271,8 @@
   SharedReadOnly,
   SharedReadWrite,
   SharedMiscData,
-  SharedMiscCode
+  SharedMiscCode,
+  SharedOptional
 };
 
 void report_out_of_shared_space(SharedSpaceType space_type);
--- a/hotspot/src/share/vm/utilities/hashtable.inline.hpp	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/src/share/vm/utilities/hashtable.inline.hpp	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -79,8 +79,8 @@
 
 
 template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEntry<F>* l) {
-  // Warning: Preserve store ordering.  The SystemDictionary is read
-  //          without locks.  The new SystemDictionaryEntry must be
+  // Warning: Preserve store ordering.  The PackageEntryTable, ModuleEntryTable and
+  //          SystemDictionary are read without locks.  The new entry must be
   //          complete before other threads can be allowed to see it
   //          via a store to _buckets[index].
   OrderAccess::release_store_ptr(&_entry, l);
@@ -88,8 +88,8 @@
 
 
 template <MEMFLAGS F> inline BasicHashtableEntry<F>* HashtableBucket<F>::get_entry() const {
-  // Warning: Preserve load ordering.  The SystemDictionary is read
-  //          without locks.  The new SystemDictionaryEntry must be
+  // Warning: Preserve load ordering.  The PackageEntryTable, ModuleEntryTable and
+  //          SystemDictionary are read without locks.  The new entry must be
   //          complete before other threads can be allowed to see it
   //          via a store to _buckets[index].
   return (BasicHashtableEntry<F>*) OrderAccess::load_ptr_acquire(&_entry);
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Mon Oct 10 13:31:48 2016 -0700
@@ -110,10 +110,6 @@
         excludeTestMaxRange("OldSize");
         excludeTestMaxRange("ParallelGCThreads");
 
-        excludeTestMaxRange("CompilerThreadStackSize");
-        excludeTestMaxRange("ThreadStackSize");
-        excludeTestMaxRange("VMThreadStackSize");
-
         /*
          * Remove parameters controlling the code cache. As these
          * parameters have implications on the physical memory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+// This class contains common test utilities for CDS testing
+public class CDSTestUtils {
+
+    // check result of 'dump' operation
+    public static void checkDump(OutputAnalyzer output, String... extraMatches)
+        throws Exception {
+
+        output.shouldContain("Loading classes to share");
+        output.shouldHaveExitValue(0);
+
+        for (String match : extraMatches) {
+            output.shouldContain(match);
+        }
+    }
+
+
+    // check the output for indication that mapping of the archive failed
+    public static boolean isUnableToMap(OutputAnalyzer output) {
+        String outStr = output.getOutput();
+        if ((output.getExitValue() == 1) && (
+            outStr.contains("Unable to reserve shared space at required address") ||
+            outStr.contains("Unable to map ReadOnly shared space at required address") ||
+            outStr.contains("Unable to map ReadWrite shared space at required address") ||
+            outStr.contains("Unable to map MiscData shared space at required address") ||
+            outStr.contains("Unable to map MiscCode shared space at required address") ||
+            outStr.contains("Unable to map shared string space at required address") ||
+            outStr.contains("Could not allocate metaspace at a compatible address") ||
+            outStr.contains("Unable to allocate shared string space: range is not within java heap") ))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    // check result of 'exec' operation, that is when JVM is run using the archive
+    public static void checkExec(OutputAnalyzer output, String... extraMatches) throws Exception {
+        if (isUnableToMap(output)) {
+            System.out.println("Unable to map shared archive: test did not complete; assumed PASS");
+            return;
+        }
+        output.shouldContain("sharing");
+        output.shouldHaveExitValue(0);
+
+        for (String match : extraMatches) {
+            output.shouldContain(match);
+        }
+    }
+
+
+    // get the file object for the test artifact
+    private static File getTestArtifactFile(String prefix, String name) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        return new File(dir, prefix + name);
+    }
+
+
+    // create file containing the specified class list
+    public static File makeClassList(String testCaseName, String classes[])
+        throws Exception {
+
+        File classList = getTestArtifactFile(testCaseName, "test.classlist");
+        FileOutputStream fos = new FileOutputStream(classList);
+        PrintStream ps = new PrintStream(fos);
+
+        addToClassList(ps, classes);
+
+        ps.close();
+        fos.close();
+
+        return classList;
+    }
+
+
+    private static void addToClassList(PrintStream ps, String classes[])
+        throws IOException
+    {
+        if (classes != null) {
+            for (String s : classes) {
+                ps.println(s);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class Implementor implements Interface {
+    public static void main(String[] args) {
+        System.out.println("Implementor: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // from interface
+        (new Implementor()).printString();
+        // from implementor
+        System.out.println(TransformUtil.ChildCheckPattern +
+                           TransformUtil.BeforePattern);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public interface Interface {
+    public static final String stringToBeTransformed =
+        TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern;
+
+    default void printString() {
+        System.out.println(stringToBeTransformed);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class SubClass extends SuperClazz {
+    public static void main(String[] args) {
+        System.out.println("SubClass: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // The line below will be used to check for successful class transformation
+        System.out.println(TransformUtil.ChildCheckPattern +
+                           TransformUtil.BeforePattern);
+        (new SubClass()).callParent();
+    }
+
+    private void callParent() {
+        super.testParent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+public class SuperClazz {
+    public static void testParent() {
+        System.out.println("SuperClazz: entering testParent()");
+
+        // The line below will be used to check for successful class transformation
+        System.out.println(TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+// Test Entry - a single entry in a test table
+// that defines a test case
+// See TransformRelatedClasses.java for more details
+public class TestEntry {
+    int testCaseId;
+    boolean transformParent;
+    boolean transformChild;
+    boolean isParentExpectedShared;
+    boolean isChildExpectedShared;
+
+    public TestEntry(int testCaseId,
+                     boolean transformParent, boolean transformChild,
+                     boolean isParentExpectedShared, boolean isChildExpectedShared) {
+        this.testCaseId = testCaseId;
+        this.transformParent = transformParent;
+        this.transformChild = transformChild;
+        this.isParentExpectedShared = isParentExpectedShared;
+        this.isChildExpectedShared = isChildExpectedShared;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with Interface/Implementor pair
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent Interface Implementor
+ * @run main/othervm TransformRelatedClasses Interface Implementor
+ */
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related interface
+// and its implementor in combination with CDS.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to an interface and an implementor in a combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+// This is the main test class for testing transformation of related classes
+// in combination with CDS, to ensure these features work well together.
+// The relationships that can be tested using this test class are:
+// superclass/subclass, and interface/implementor relationships.
+//
+// The test uses combinatorial approach.
+// For details on test table and test cases see main() method in this class.
+//
+// This test consists of multiple classes for better flexibility and reuse,
+// and also relies on certain common utility code.
+// Here are the details on the structure of the test
+//
+// Structure of the test:
+// TransformRelatedClasses -- common main test driver
+//     The TransformRelatedClasses is invoked from test driver classes:
+//     TransformInterfaceAndImplementor, TransformSuperAndSubClasses
+//     It is responsible for preparing test artifacts (test jar, agent jar
+//     and the shared archive), running test cases and checking the results.
+// The following test classes below are launched in a sub-process with use
+// of shared archive:
+//     SuperClazz, SubClass -- super/sub class pair under test
+//     Interface, Implementor -- classes under test
+// This test will transform these classes, based on the test case data,
+// by changing a predefined unique string in each class.
+// For more details, see the test classes' code and comments.
+//
+// Other related classes:
+//     TestEntry - a class representing a single test case, as test entry in the table
+//     TransformTestCommon - common methods for transformation test cases
+//
+// Other utility/helper classes and files used in this test:
+//     TransformerAgent - an agent that is used when JVM-under-test is executed
+//         to transform specific strings inside specified classes
+//     TransformerAgent.mf - accompanies transformer agent
+//     CDSTestUtils - Test Utilities common to all CDS tests
+
+import java.io.File;
+import java.util.ArrayList;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+
+public class TransformRelatedClasses {
+    static final String archiveName = "./TransformRelatedClasses.jsa";
+    static String agentClasses[] = {
+        "TransformerAgent",
+        "TransformerAgent$SimpleTransformer",
+        "TransformUtil"
+    };
+
+    String parent;
+    String child;
+    String[] testClasses = new String[2];
+    String[] testNames = new String[2];
+    String testJar;
+    String agentJar;
+
+
+    private static void log(String msg) {
+        System.out.println("TransformRelatedClasses: " + msg);
+    }
+
+
+    // This class is intended to test 2 parent-child relationships:
+    // 1. Base Class (parent) and Derived Class (child)
+    // 2. Interface (parent) and Implementor (child)
+    //    Parameters to main(): parent, child
+    public static void main(String args[]) throws Exception {
+        TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]);
+        test.prepare();
+
+        // Test Table
+        // TestEntry:  (testCaseId, transformParent, tranformChild,
+        //             isParentExpectedShared, isChildExpectedShared)
+        ArrayList<TestEntry> testTable = new ArrayList<>();
+
+        // base case - no tranformation - all expected to be shared
+        testTable.add(new TestEntry(0, false, false, true, true));
+
+        // transform parent only - both parent and child should not be shared
+        testTable.add(new TestEntry(1, true, false, false, false));
+
+        // transform parent and child - both parent and child should not be shared
+        testTable.add(new TestEntry(2, true, true, false, false));
+
+        // transform child only - parent should still be shared, but not child
+        testTable.add(new TestEntry(3, false, true, true, false));
+
+        // run the tests
+        for (TestEntry entry : testTable) {
+            test.runTest(entry);
+        }
+    }
+
+
+    public TransformRelatedClasses(String parent, String child) {
+        log("Constructor: parent = " + parent + ", child = " + child);
+        this.parent = parent;
+        this.child = child;
+        testClasses[0] = parent;
+        testClasses[1] = child;
+        testNames[0] = parent.replace('.', '/');
+        testNames[1] = child.replace('.', '/');
+    }
+
+
+    // same test jar and archive can be used for all test cases
+    private void prepare() throws Exception {
+        // create agent jar
+        // Agent is the same for all test cases
+        String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
+        agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
+                       ClassFileInstaller.Manifest.fromSourceFile(pathToManifest),
+                                           agentClasses);
+
+        // create a test jar
+        testJar =
+            ClassFileInstaller.writeJar(parent + "-" + child + ".jar",
+                                           testClasses);
+
+        // create an archive
+        File classList = CDSTestUtils.makeClassList("transform-" + parent,
+                                                    testNames);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
+                                        "-Xbootclasspath/a:" + testJar,
+                                        "-XX:+UnlockDiagnosticVMOptions",
+                                        "-XX:ExtraSharedClassListFile=" +
+                                        classList.getPath(),
+                                        "-XX:SharedArchiveFile=" + archiveName,
+                                        "-XX:+PrintSharedSpaces",
+                                        "-Xshare:dump");
+        OutputAnalyzer out = new OutputAnalyzer(pb.start());
+        CDSTestUtils.checkDump(out);
+    }
+
+
+    private void runTest(TestEntry entry) throws Exception {
+        log("runTest(): testCaseId = " + entry.testCaseId);
+
+        // execute with archive
+        String agentParam = "-javaagent:" + agentJar + "=" +
+            TransformTestCommon.getAgentParams(entry, parent, child);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
+                                        "-Xbootclasspath/a:" + testJar,
+                                        "-XX:+UnlockDiagnosticVMOptions",
+                                        "-XX:SharedArchiveFile=" + archiveName,
+                                        "-Xlog:class+load=info",
+                                        "-Xshare:on", "-showversion",
+                                        agentParam, child);
+        OutputAnalyzer out = new OutputAnalyzer(pb.start());
+
+        TransformTestCommon.checkResults(entry, out, parent, child);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with SubClass and SuperClass
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent SubClass SuperClazz
+ * @run main/othervm TransformRelatedClasses SuperClazz SubClass
+*/
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related superclass
+// and subclass in combination with CDS.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to a parent and child in combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with SubClass and SuperClass, each lives in own separate package
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent SubClass SuperClazz
+ * @compile myPkg2/SubClass.java myPkg1/SuperClazz.java
+ * @run main/othervm TransformRelatedClasses myPkg1.SuperClazz myPkg2.SubClass
+*/
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related superclass
+// and subclass in combination with CDS; each class lives in its own package.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to a parent and child in combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+// This class contains methods common to all transformation test cases
+public class TransformTestCommon {
+
+    // get parameters to an agent depending on the test case
+    // these parameters will instruct the agent which classes should be
+    // transformed
+    public static String getAgentParams(TestEntry entry,
+                                        String parent, String child) {
+
+        if (entry.transformParent && entry.transformChild)
+            return parent + "," + child;
+        if (entry.transformParent)
+            return parent;
+        if (entry.transformChild)
+            return child;
+
+        return "";
+    }
+
+
+    private static void checkTransformationResults(TestEntry entry,
+                                                   OutputAnalyzer out)
+        throws Exception {
+
+        if (entry.transformParent)
+            out.shouldContain(TransformUtil.ParentCheckPattern +
+                              TransformUtil.AfterPattern);
+
+        if (entry.transformChild)
+            out.shouldContain(TransformUtil.ChildCheckPattern +
+                              TransformUtil.AfterPattern);
+    }
+
+
+    private static void checkSharingByClass(TestEntry entry, OutputAnalyzer out,
+                                            String parent, String child)
+        throws Exception {
+
+        String parentSharedMatch = parent + " source: shared objects file";
+        String childSharedMatch =  child +  " source: shared objects file";
+
+        if (entry.isParentExpectedShared)
+            out.shouldContain(parentSharedMatch);
+        else
+            out.shouldNotContain(parentSharedMatch);
+
+        if (entry.isChildExpectedShared)
+            out.shouldContain(childSharedMatch);
+        else
+            out.shouldNotContain(childSharedMatch);
+    }
+
+
+    // Both parent and child classes should be passed to ClassFileTransformer.transform()
+    // exactly once.
+    private static void checkTransformationCounts(TestEntry entry, OutputAnalyzer out,
+                                                  String parent, String child)
+        throws Exception {
+
+        String patternBase = "TransformerAgent: SimpleTransformer called for: ";
+
+        out.shouldContain(patternBase + child + "@1");
+        out.shouldContain(patternBase + parent + "@1");
+
+        out.shouldNotContain(patternBase + child + "@2");
+        out.shouldNotContain(patternBase + parent + "@2");
+    }
+
+
+    public static void checkResults(TestEntry entry, OutputAnalyzer out,
+                                    String parent, String child)
+        throws Exception {
+
+        // If we were not able to map an archive,
+        // then do not perform other checks, since
+        // there was no sharing at all
+        if (CDSTestUtils.isUnableToMap(out))
+            return;
+
+        String childVmName = child.replace('.', '/');
+        String parentVmName = parent.replace('.', '/');
+
+        CDSTestUtils.checkExec(out);
+        checkTransformationCounts(entry, out, parentVmName, childVmName);
+        checkTransformationResults(entry, out);
+        checkSharingByClass(entry, out, parent, child);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myPkg1;
+
+public class SuperClazz {
+    public static void testParent() {
+        System.out.println("SuperClazz: entering testParent()");
+
+        // The line below will be used to check for successful class transformation
+        System.out.println("parent-transform-check: this-should-be-transformed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package myPkg2;
+
+import myPkg1.SuperClazz;
+
+public class SubClass extends SuperClazz {
+    public static void main(String[] args) {
+        System.out.println("SubClass: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // The line below will be used to check for successful class transformation
+        System.out.println("child-transform-check: this-should-be-transformed");
+        (new SubClass()).callParent();
+
+        // Get the system packages, which should contain myPkg1 and myPkag2
+        Package[] pkgs = Package.getPackages();
+        for (int i = 0; i < pkgs.length; i++) {
+            if (pkgs[i].getName().equals("myPkg1")) {
+                for (int j = 0; j < pkgs.length; j++) {
+                    if (pkgs[j].getName().equals("myPkg2")) {
+                        return; // found myPkg1 & myPkg1
+                    }
+                }
+            }
+        }
+        throw new RuntimeException("Missing system package");
+    }
+
+    private void callParent() {
+        super.testParent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jvmti/TransformUtil.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+public class TransformUtil {
+    public static final String BeforePattern = "this-should-be-transformed";
+    public static final String AfterPattern  = "this-has-been--transformed";
+    public static final String ParentCheckPattern = "parent-transform-check: ";
+    public static final String ChildCheckPattern = "child-transform-check: ";
+
+    /**
+     * @return the number of occurrences of the <code>from</code> string that
+     * have been replaced.
+     */
+    public static int replace(byte buff[], String from, String to) {
+        if (to.length() != from.length()) {
+            throw new RuntimeException("bad strings");
+        }
+        byte f[] = asciibytes(from);
+        byte t[] = asciibytes(to);
+        byte f0 = f[0];
+
+        int numReplaced = 0;
+        int max = buff.length - f.length;
+        for (int i = 0; i < max; ) {
+            if (buff[i] == f0 && replace(buff, f, t, i)) {
+                i += f.length;
+                numReplaced++;
+            } else {
+                i++;
+            }
+        }
+        return numReplaced;
+    }
+
+    public static boolean replace(byte buff[], byte f[], byte t[], int i) {
+        for (int x = 0; x < f.length; x++) {
+            if (buff[x+i] != f[x]) {
+                return false;
+            }
+        }
+        for (int x = 0; x < f.length; x++) {
+            buff[x+i] = t[x];
+        }
+        return true;
+    }
+
+    static byte[] asciibytes(String s) {
+        byte b[] = new byte[s.length()];
+        for (int i = 0; i < b.length; i++) {
+            b[i] = (byte)s.charAt(i);
+        }
+        return b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jvmti/TransformerAgent.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+
+// This is a test utility class used to transform
+// specified classes via initial transformation (ClassFileLoadHook).
+// Names of classes to be transformed are supplied as arguments,
+// the phrase to be transformed is a hard-coded predefined
+// fairly unique phrase.
+
+public class TransformerAgent {
+    private static String[] classesToTransform;
+
+
+    private static void log(String msg) {
+        System.out.println("TransformerAgent: " + msg);
+    }
+
+
+    // arguments are comma-separated list of classes to transform
+    public static void premain(String agentArguments, Instrumentation instrumentation) {
+        log("premain() is called, arguments = " + agentArguments);
+        classesToTransform = agentArguments.split(",");
+        instrumentation.addTransformer(new SimpleTransformer(), /*canRetransform=*/true);
+    }
+
+
+    public static void agentmain(String args, Instrumentation inst) throws Exception {
+        log("agentmain() is called");
+        premain(args, inst);
+    }
+
+
+    static class SimpleTransformer implements ClassFileTransformer {
+       public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
+                            ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
+
+            log("SimpleTransformer called for: " + name + "@" + incrCounter(name));
+            if (!shouldTransform(name))
+                return null;
+
+            log("transforming: class name = " + name);
+            int nrOfReplacements = TransformUtil.replace(buffer, TransformUtil.BeforePattern,
+                                                         TransformUtil.AfterPattern);
+            log("replaced the string, nrOfReplacements = " + nrOfReplacements);
+            return buffer;
+        }
+
+        // Check class name pattern, since test should only transform certain classes
+        private static boolean shouldTransform(String name) {
+            for (String match : classesToTransform) {
+                if (name.matches(match)) {
+                    log("shouldTransform: match-found, match = " + match);
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+
+    static HashMap<String, Integer> counterMap = new HashMap<>();
+
+    static Integer incrCounter(String className) {
+        Integer i = counterMap.get(className);
+        if (i == null) {
+            i = new Integer(1);
+        } else {
+            i = new Integer(i.intValue() + 1);
+        }
+        counterMap.put(className, i);
+        return i;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jvmti/TransformerAgent.mf	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: TransformerAgent
+Agent-Class: TransformerAgent
+Can-Retransform-Classes: true
+Can-Redefine-Classes: false
--- a/jaxp/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/jaxp/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -380,3 +380,4 @@
 f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135
 f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136
 a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137
+69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
--- a/jaxws/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/jaxws/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -383,3 +383,4 @@
 22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135
 09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136
 297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137
+7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138
--- a/jdk/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -381,3 +381,4 @@
 54c5931849a33a363e03fdffa141503f5cc4779d jdk-9+136
 e72df94364e3686e7d62059ce0d6b187b82da713 jdk-9+137
 665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
+5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
--- a/jdk/ASSEMBLY_EXCEPTION	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/ASSEMBLY_EXCEPTION	Mon Oct 10 13:31:48 2016 -0700
@@ -1,27 +1,27 @@
 
 OPENJDK ASSEMBLY EXCEPTION
 
-The OpenJDK source code made available by Sun at openjdk.java.net and
-openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
-GNU General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
+The OpenJDK source code made available by Oracle America, Inc. (Oracle) at
+openjdk.java.net ("OpenJDK Code") is distributed under the terms of the GNU
+General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
 only ("GPL2"), with the following clarification and special exception.
 
     Linking this OpenJDK Code statically or dynamically with other code
     is making a combined work based on this library.  Thus, the terms
     and conditions of GPL2 cover the whole combination.
 
-    As a special exception, Sun gives you permission to link this
-    OpenJDK Code with certain code licensed by Sun as indicated at
+    As a special exception, Oracle gives you permission to link this
+    OpenJDK Code with certain code licensed by Oracle as indicated at
     http://openjdk.java.net/legal/exception-modules-2007-05-08.html
     ("Designated Exception Modules") to produce an executable,
     regardless of the license terms of the Designated Exception Modules,
     and to copy and distribute the resulting executable under GPL2,
     provided that the Designated Exception Modules continue to be
-    governed by the licenses under which they were offered by Sun.
+    governed by the licenses under which they were offered by Oracle.
 
-As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
-build an executable that includes those portions of necessary code that Sun
-could not provide under GPL2 (or that Sun has provided under GPL2 with the
-Classpath exception).  If you modify or add to the OpenJDK code, that new
-GPL2 code may still be combined with Designated Exception Modules if the
-new code is made subject to this exception by its copyright holder.
+As such, it allows licensees and sublicensees of Oracle's GPL2 OpenJDK Code
+to build an executable that includes those portions of necessary code that
+Oracle could not provide under GPL2 (or that Oracle has provided under GPL2
+with the Classpath exception).  If you modify or add to the OpenJDK code,
+that new GPL2 code may still be combined with Designated Exception Modules
+if the new code is made subject to this exception by its copyright holder.
--- a/jdk/make/CompileDemos.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/CompileDemos.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, 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
@@ -338,6 +338,7 @@
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1, \
       OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib, \
       LIBRARY := $1, \
+      STRIP_SYMBOLS := false, \
   ))
 
   $1 += $$(BUILD_DEMO_JVMTI_NATIVE_$1)
@@ -453,6 +454,7 @@
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller, \
       OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native, \
       LIBRARY := Poller, \
+      STRIP_SYMBOLS := false, \
   ))
 
   TARGETS += $(BUILD_DEMO_NATIVE_Poller)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/CompileModuleTools.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,42 @@
+#
+# 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.  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 $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
+
+$(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
+    SETUP := GENERATE_USINGJDKBYTECODE, \
+    SRC := $(JDK_TOPDIR)/make/src/classes, \
+    INCLUDES := build/tools/deps \
+                build/tools/jigsaw, \
+    BIN := $(TOOLS_CLASSES_DIR), \
+    ADD_JAVAC_FLAGS := \
+        --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
+        --add-exports java.base/jdk.internal.module=ALL-UNNAMED \
+))
--- a/jdk/make/Import.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-#
-# Copyright (c) 2012, 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.
-#
-
-default: all
-
-include $(SPEC)
-include MakeBase.gmk
-
-################################################################################
-
-# Put the libraries here. Different locations for different target OS types.
-ifneq ($(OPENJDK_TARGET_OS), windows)
-  HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
-  BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
-else
-  HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin
-  BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
-endif
-
-################################################################################
-#
-# Import hotspot
-#
-
-# Don't import jsig library for static builds
-ifneq ($(STATIC_BUILD), true)
-  JSIG_IMPORT = jsig.*
-else
-  JSIG_IMPORT =
-endif
-
-HOTSPOT_BASE_IMPORT_FILES := \
-    $(addprefix $(LIBRARY_PREFIX), jvm.* $(JSIG_IMPORT) jvm_db.* jvm_dtrace.*) \
-    Xusage.txt \
-    #
-
-$(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE, \
-    SRC := $(HOTSPOT_LIB_DIR), \
-    DEST := $(BASE_INSTALL_LIBRARIES_HERE), \
-    FILES := $(shell $(FIND) $(HOTSPOT_LIB_DIR) -type f  \
-        -a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE), $(HOTSPOT_BASE_IMPORT_FILES)) \) )))
-
-ifeq ($(OPENJDK_TARGET_OS), windows)
-  $(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE_JVMLIB, \
-      SRC := $(HOTSPOT_DIST)/lib, \
-      DEST := $(BASE_INSTALL_LIBRARIES_HERE), \
-      FILES := $(wildcard $(HOTSPOT_DIST)/lib/*.lib)))
-endif
-
-BASE_TARGETS := $(COPY_HOTSPOT_BASE) $(COPY_HOTSPOT_BASE_JVMLIB)
-
-################################################################################
-
-ifneq ($(STATIC_BUILD), true)
-  ifeq ($(OPENJDK_TARGET_OS), macosx)
-    JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
-        $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-  else
-    JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
-        $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-  endif
-
-  ifneq ($(OPENJDK_TARGET_OS), windows)
-    ifeq ($(call check-jvm-variant, server), true)
-      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-      ifneq (, $(JSIG_DEBUGINFO))
-        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
-      endif
-    endif
-    ifeq ($(call check-jvm-variant, client), true)
-      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-      ifneq (, $(JSIG_DEBUGINFO))
-        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
-      endif
-    endif
-    ifneq ($(OPENJDK_TARGET_OS), macosx)
-      ifeq ($(call check-jvm-variant, minimal), true)
-        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-        ifneq (,$(JSIG_DEBUGINFO))
-          BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
-        endif
-      endif
-    endif
-  endif
-endif
-
-$(BASE_INSTALL_LIBRARIES_HERE)/server/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-  $(BASE_INSTALL_LIBRARIES_HERE)/server/%.dSYM:
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-  $(BASE_INSTALL_LIBRARIES_HERE)/server/%.diz : $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(RM) $@.tmp $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(LN) -s ../$(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(RM) $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(MV) $@.tmp $@
-else
-  $(BASE_INSTALL_LIBRARIES_HERE)/server/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-  $(BASE_INSTALL_LIBRARIES_HERE)/server/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(RM) $@.tmp $(basename $@).debuginfo
-	$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
-	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
-	$(RM) $(basename $@).debuginfo
-	$(MV) $@.tmp $@
-endif
-
-$(BASE_INSTALL_LIBRARIES_HERE)/client/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-  $(BASE_INSTALL_LIBRARIES_HERE)/client/%.dSYM : $(BASE_INSTALL_LIBRARIES_HERE)/%.dSYM
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-  $(BASE_INSTALL_LIBRARIES_HERE)/client/%.diz : $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(RM) $@.tmp $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(LN) -s ../$(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(RM) $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
-	$(MV) $@.tmp $@
-else
-  $(BASE_INSTALL_LIBRARIES_HERE)/client/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-  $(BASE_INSTALL_LIBRARIES_HERE)/client/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(RM) $@.tmp $(basename $@).debuginfo
-	$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
-	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
-	$(RM) $(basename $@).debuginfo
-	$(MV) $@.tmp $@
-endif
-
-$(BASE_INSTALL_LIBRARIES_HERE)/minimal/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-ifneq ($(OPENJDK_TARGET_OS), macosx)
-  $(BASE_INSTALL_LIBRARIES_HERE)/minimal/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(LN) -s ../$(@F) $@
-
-  $(BASE_INSTALL_LIBRARIES_HERE)/minimal/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
-	$(MKDIR) -p $(@D)
-	$(RM) $@
-	$(RM) $@.tmp $(basename $@).debuginfo
-	$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
-	$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
-	$(RM) $(basename $@).debuginfo
-	$(MV) $@.tmp $@
-endif
-
-################################################################################
-
-ifeq ($(OPENJDK_TARGET_OS), windows)
-  $(eval $(call SetupCopyFiles,BASE_COPY_LIBS_BIN, \
-      SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
-      DEST := $(JDK_OUTPUTDIR)/bin, \
-      FILES := $(filter-out %.lib, $(BASE_TARGETS))))
-
-  $(eval $(call SetupCopyFiles,BASE_COPY_LIBS_LIB, \
-      SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
-      DEST := $(JDK_OUTPUTDIR)/lib, \
-      FILES := $(filter %.lib, $(BASE_TARGETS))))
-
-else
-  $(eval $(call SetupCopyFiles,BASE_COPY_LIBS, \
-      SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
-      DEST := $(JDK_OUTPUTDIR)/lib, \
-      FILES := $(BASE_TARGETS)))
-endif
-
-################################################################################
-
-all: $(BASE_TARGETS) $(BASE_COPY_LIBS_BIN) $(BASE_COPY_LIBS_LIB) \
-    $(BASE_COPY_LIBS)
-
-.PHONY: default all
--- a/jdk/make/ModuleTools.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/ModuleTools.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -26,18 +26,14 @@
 include $(SPEC)
 include MakeBase.gmk
 include JavaCompilation.gmk
-include SetupJavaCompilers.gmk
 
 TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
 
-$(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
-    SETUP := GENERATE_USINGJDKBYTECODE, \
-    SRC := $(JDK_TOPDIR)/make/src/classes, \
-    INCLUDES := build/tools/deps \
-                build/tools/jigsaw, \
-    BIN := $(TOOLS_CLASSES_DIR), \
-    ADD_JAVAC_FLAGS := --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
-
+# To avoid reevaluating the compilation setup for the tools each time this file
+# is included, the actual compilation is handled by CompileModuleTools.gmk. The
+# following trick is used to be able to declare a dependency on the built tools.
+BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
+    BUILD_JIGSAW_TOOLS, $(TOOLS_CLASSES_DIR))
 
 TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
     build.tools.jigsaw.GenGraphs
@@ -45,3 +41,8 @@
 TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
     --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
     build.tools.jigsaw.ModuleSummary
+
+TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \
+    -cp $(TOOLS_CLASSES_DIR) \
+    --add-exports java.base/jdk.internal.module=ALL-UNNAMED \
+    build.tools.jigsaw.AddPackagesAttribute
--- a/jdk/make/data/tzdata/VERSION	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/VERSION	Mon Oct 10 13:31:48 2016 -0700
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2016f
+tzdata2016g
--- a/jdk/make/data/tzdata/africa	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/africa	Mon Oct 10 13:31:48 2016 -0700
@@ -487,7 +487,7 @@
 # http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/
 #
 # From Paul Eggert (2013-10-25):
-# For now, assume they're reverting to the pre-2012 rules of permanent UTC+2.
+# For now, assume they're reverting to the pre-2012 rules of permanent UT +02.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
--- a/jdk/make/data/tzdata/antarctica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/antarctica	Mon Oct 10 13:31:48 2016 -0700
@@ -33,9 +33,7 @@
 # http://www.spri.cam.ac.uk/bob/periant.htm
 # for information.
 # Unless otherwise specified, we have no time zone information.
-#
-# Except for the French entries,
-# I made up all time zone abbreviations mentioned here; corrections welcome!
+
 # FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
 
 # Argentina - year-round bases
@@ -52,7 +50,7 @@
 #	previously sealers and scientific personnel wintered
 #	Margaret Turner reports
 #	http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html
-#	(1999-09-30) that they're UTC+5, with no DST;
+#	(1999-09-30) that they're UT +05, with no DST;
 #	presumably this is when they have visitors.
 #
 # year-round bases
@@ -91,23 +89,22 @@
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Casey	0	-	-00	1969
-			8:00	-	AWST	2009 Oct 18  2:00
-						# Australian Western Std Time
-			11:00	-	CAST	2010 Mar  5  2:00  # Casey Time
-			8:00	-	AWST	2011 Oct 28  2:00
-			11:00	-	CAST	2012 Feb 21 17:00u
-			8:00	-	AWST
+			8:00	-	+08	2009 Oct 18  2:00
+			11:00	-	+11	2010 Mar  5  2:00
+			8:00	-	+08	2011 Oct 28  2:00
+			11:00	-	+11	2012 Feb 21 17:00u
+			8:00	-	+08
 Zone Antarctica/Davis	0	-	-00	1957 Jan 13
-			7:00	-	DAVT	1964 Nov    # Davis Time
+			7:00	-	+07	1964 Nov
 			0	-	-00	1969 Feb
-			7:00	-	DAVT	2009 Oct 18  2:00
-			5:00	-	DAVT	2010 Mar 10 20:00u
-			7:00	-	DAVT	2011 Oct 28  2:00
-			5:00	-	DAVT	2012 Feb 21 20:00u
-			7:00	-	DAVT
+			7:00	-	+07	2009 Oct 18  2:00
+			5:00	-	+05	2010 Mar 10 20:00u
+			7:00	-	+07	2011 Oct 28  2:00
+			5:00	-	+05	2012 Feb 21 20:00u
+			7:00	-	+07
 Zone Antarctica/Mawson	0	-	-00	1954 Feb 13
-			6:00	-	MAWT	2009 Oct 18  2:00 # Mawson Time
-			5:00	-	MAWT
+			6:00	-	+06	2009 Oct 18  2:00
+			5:00	-	+05
 # References:
 # Casey Weather (1998-02-26)
 # http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html
@@ -161,7 +158,7 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Indian/Kerguelen	0	-	-00	1950 # Port-aux-Français
-			5:00	-	TFT	# ISO code TF Time
+			5:00	-	+05
 #
 # year-round base in the main continent
 # Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11
@@ -172,9 +169,9 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/DumontDUrville 0 -	-00	1947
-			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
+			10:00	-	+10	1952 Jan 14
 			0	-	-00	1956 Nov
-			10:00	-	DDUT	# Dumont-d'Urville Time
+			10:00	-	+10
 
 # France & Italy - year-round base
 # Concordia, -750600+1232000, since 2005
@@ -200,7 +197,7 @@
 # station of Japan, it's appropriate for the principal location.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Syowa	0	-	-00	1957 Jan 29
-			3:00	-	SYOT	# Syowa Time
+			3:00	-	+03
 # See:
 # NIPR Antarctic Research Activities (1999-08-17)
 # http://www.nipr.ac.jp/english/ara01.html
@@ -237,17 +234,17 @@
 # correct, but they should be quite close to the actual dates.
 #
 # From Paul Eggert (2014-03-21):
-# The CET-switching Troll rules require zic from tzcode 2014b or later, so as
+# The CET-switching Troll rules require zic from tz 2014b or later, so as
 # suggested by Bengt-Inge Larsson comment them out for now, and approximate
 # with only UTC and CEST.  Uncomment them when 2014b is more prevalent.
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-#Rule	Troll	2005	max	-	Mar	 1	1:00u	1:00	CET
-Rule	Troll	2005	max	-	Mar	lastSun	1:00u	2:00	CEST
-#Rule	Troll	2005	max	-	Oct	lastSun	1:00u	1:00	CET
-#Rule	Troll	2004	max	-	Nov	 7	1:00u	0:00	UTC
+#Rule	Troll	2005	max	-	Mar	 1	1:00u	1:00	+01
+Rule	Troll	2005	max	-	Mar	lastSun	1:00u	2:00	+02
+#Rule	Troll	2005	max	-	Oct	lastSun	1:00u	1:00	+01
+#Rule	Troll	2004	max	-	Nov	 7	1:00u	0:00	+00
 # Remove the following line when uncommenting the above '#Rule' lines.
-Rule	Troll	2004	max	-	Oct	lastSun	1:00u	0:00	UTC
+Rule	Troll	2004	max	-	Oct	lastSun	1:00u	0:00	+00
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Troll	0	-	-00	2005 Feb 12
 			0:00	Troll	%s
@@ -288,10 +285,10 @@
 # changes during the year and does not necessarily correspond to mean
 # solar noon.  So the Vostok time might have been whatever the clocks
 # happened to be during their visit.  So we still don't really know what time
-# it is at Vostok.  But we'll guess UTC+6.
+# it is at Vostok.  But we'll guess +06.
 #
 Zone Antarctica/Vostok	0	-	-00	1957 Dec 16
-			6:00	-	VOST	# Vostok time
+			6:00	-	+06
 
 # S Africa - year-round bases
 # Marion Island, -4653+03752
@@ -324,7 +321,7 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Rothera	0	-	-00	1976 Dec  1
-			-3:00	-	ROTT	# Rothera time
+			-3:00	-	-03
 
 # Uruguay - year round base
 # Artigas, King George Island, -621104-0585107
--- a/jdk/make/data/tzdata/asia	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/asia	Mon Oct 10 13:31:48 2016 -0700
@@ -139,13 +139,11 @@
 # http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
-			3:00	-	YERT	1957 Mar    # Yerevan Time
-			4:00 RussiaAsia YER%sT	1991 Mar 31  2:00s
-			3:00	1:00	YERST	1991 Sep 23 # independence
-			3:00 RussiaAsia	AM%sT	1995 Sep 24  2:00s
-			4:00	-	AMT	1997
-			4:00 RussiaAsia	AM%sT	2012 Feb  9
-			4:00	-	AMT
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia	+03/+04	1995 Sep 24  2:00s
+			4:00	-	+04	1997
+			4:00 RussiaAsia	+04/+05
 
 # Azerbaijan
 
@@ -166,13 +164,12 @@
 Rule	Azer	1997	2015	-	Oct	lastSun	 5:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
-			3:00	-	BAKT	1957 Mar    # Baku Time
-			4:00 RussiaAsia BAK%sT	1991 Mar 31  2:00s
-			3:00	1:00	BAKST	1991 Aug 30 # independence
-			3:00 RussiaAsia	AZ%sT	1992 Sep lastSun  2:00s
-			4:00	-	AZT	1996     # Azerbaijan Time
-			4:00	EUAsia	AZ%sT	1997
-			4:00	Azer	AZ%sT
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia	+03/+04	1992 Sep lastSun  2:00s
+			4:00	-	+04	1996
+			4:00	EUAsia	+04/+05	1997
+			4:00	Azer	+04/+05
 
 # Bahrain
 # See Asia/Qatar.
@@ -291,7 +288,7 @@
 # Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Rangoon	6:24:40 -	LMT	1880        # or Yangon
+Zone	Asia/Yangon	6:24:40 -	LMT	1880        # or Rangoon
 			6:24:40	-	RMT	1920        # Rangoon Mean Time?
 			6:30	-	BURT	1942 May    # Burma Time
 			9:00	-	JST	1945 May  3
@@ -406,7 +403,7 @@
 # Lewiston (ME) Daily Sun (1939-05-29), p 17, said "Even the time is
 # different - the occupied districts going by Tokyo time, an hour
 # ahead of that prevailing in the rest of Shanghai."  Guess that the
-# Xujiahui Observatory was under French control and stuck with UT+8.
+# Xujiahui Observatory was under French control and stuck with UT +08.
 #
 # In earlier versions of this file, China had many separate Zone entries, but
 # this was based on what were apparently incorrect data in Shanks & Pottenger.
@@ -415,26 +412,26 @@
 # Proposed in 1918 and theoretically in effect until 1949 (although in practice
 # mainly observed in coastal areas), the five zones were:
 #
-# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT+8.5
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT +08:30
 # Asia/Harbin (currently a link to Asia/Shanghai)
 # Heilongjiang (except Mohe county), Jilin
 #
-# Zhongyuan Time ("Central plain Time") UT+8
+# Zhongyuan Time ("Central plain Time") UT +08
 # Asia/Shanghai
 # most of China
 # This currently represents most other zones as well,
 # as apparently these regions have been the same since 1970.
 # Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest.
-# Guo says Shanghai switched to UT+8 "from the end of the 19th century".
+# Guo says Shanghai switched to UT +08 "from the end of the 19th century".
 #
-# Long-shu Time (probably due to Long and Shu being two names of that area) UT+7
+# Long-shu Time (probably due to Long and Shu being two names of the area) UT +07
 # Asia/Chongqing (currently a link to Asia/Shanghai)
 # Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
 # most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
 # counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
 # Yangchun, Yangjiang, Yu'nan, and Yunfu.
 #
-# Xin-zang Time ("Xinjiang-Tibet Time") UT+6
+# Xin-zang Time ("Xinjiang-Tibet Time") UT +06
 # Asia/Urumqi
 # This currently represents Kunlun Time as well,
 # as apparently the two regions have been the same since 1970.
@@ -447,7 +444,7 @@
 # Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
 # Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
 #
-# Kunlun Time UT+5.5
+# Kunlun Time UT +05:30
 # Asia/Kashgar (currently a link to Asia/Urumqi)
 # West Tibet, including Pulan, Aheqi, Shufu, Shule;
 # West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
@@ -463,7 +460,7 @@
 #
 # On the other hand, ethnic Uyghurs, who make up about half the
 # population of Xinjiang, typically use "Xinjiang time" which is two
-# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
+# hours behind Beijing time, or UT +06. The government of the Xinjiang
 # Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
 # local governments such as the Ürümqi city government use both times in
 # publications, referring to what is popularly called Xinjiang time as
@@ -519,8 +516,8 @@
 # having the same time as Beijing.
 
 # From Paul Eggert (2014-06-30):
-# In the early days of the PRC, Tibet was given its own time zone (UT+6) but
-# this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
+# In the early days of the PRC, Tibet was given its own time zone (UT +06)
+# but this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
 # Memories of life in Lhasa under Chinese Rule, Columbia U Press, ISBN
 # 978-0231142861 (2008), translator's introduction by Matthew Akester, p x.
 # As this is before our 1970 cutoff, Tibet doesn't need a separate zone.
@@ -534,12 +531,12 @@
 # Republics, the Soviet Union, the Kuomintang, and the People's Republic of
 # China, and tracking down all these organizations' timekeeping rules would be
 # quite a trick.  Approximate this lost history by a transition from LMT to
-# XJT at the start of 1928, the year of accession of the warlord Jin Shuren,
+# UT +06 at the start of 1928, the year of accession of the warlord Jin Shuren,
 # which happens to be the date given by Shanks & Pottenger (no doubt as a
-# guess) as the transition from LMT.  Ignore the usage of UT+8 before
-# 1986-02-01 under the theory that the transition date to UT+8 is unknown and
+# guess) as the transition from LMT.  Ignore the usage of +08 before
+# 1986-02-01 under the theory that the transition date to +08 is unknown and
 # that the sort of users who prefer Asia/Urumqi now typically ignored the
-# UT+8 mandate back then.
+# +08 mandate back then.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # Beijing time, used throughout China; represented by Shanghai.
@@ -744,7 +741,7 @@
 # be found from historical government announcement database.
 
 # From Paul Eggert (2014-07-03):
-# As per Yu-Cheng Chuang, say that Taiwan was at UT+9 from 1937-10-01
+# As per Yu-Cheng Chuang, say that Taiwan was at UT +09 from 1937-10-01
 # until 1945-09-21 at 01:00, overriding Shanks & Pottenger.
 # Likewise, use Yu-Cheng Chuang's data for DST in Taiwan.
 
@@ -858,16 +855,15 @@
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Tbilisi	2:59:11 -	LMT	1880
 			2:59:11	-	TBMT	1924 May  2 # Tbilisi Mean Time
-			3:00	-	TBIT	1957 Mar    # Tbilisi Time
-			4:00 RussiaAsia TBI%sT	1991 Mar 31  2:00s
-			3:00	1:00	TBIST	1991 Apr  9 # independence
-			3:00 RussiaAsia GE%sT	1992        # Georgia Time
-			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
-			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
-			4:00	1:00	GEST	1997 Mar lastSun
-			4:00 E-EurAsia	GE%sT	2004 Jun 27
-			3:00 RussiaAsia	GE%sT	2005 Mar lastSun  2:00
-			4:00	-	GET
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia +03/+04	1992
+			3:00 E-EurAsia	+03/+04	1994 Sep lastSun
+			4:00 E-EurAsia	+04/+05	1996 Oct lastSun
+			4:00	1:00	+05	1997 Mar lastSun
+			4:00 E-EurAsia	+04/+05	2004 Jun 27
+			3:00 RussiaAsia	+03/+04	2005 Mar lastSun  2:00
+			4:00	-	+04
 
 # East Timor
 
@@ -944,7 +940,7 @@
 # These would be the earliest possible times for a change.
 # Régimes horaires pour le monde entier, by Henri Le Corre, (Éditions
 # Traditionnelles, 1987, Paris) says that Java and Madura switched
-# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
+# from UT +09 to +07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
 # (Hollandia).  For now, assume all Indonesian locations other than Jayapura
 # switched on 1945-09-23.
 #
@@ -955,11 +951,11 @@
 # summary published by the Time and Frequency Laboratory of the
 # Research Center for Calibration, Instrumentation and Metrology,
 # Indonesia, <http://time.kim.lipi.go.id/time-eng.php> (2006-09-29).
-# The abbreviations are:
+# The time zone abbreviations and UT offsets are:
 #
-# WIB  - UTC+7 - Waktu Indonesia Barat (Indonesia western time)
-# WITA - UTC+8 - Waktu Indonesia Tengah (Indonesia central time)
-# WIT  - UTC+9 - Waktu Indonesia Timur (Indonesia eastern time)
+# WIB  - +07 - Waktu Indonesia Barat (Indonesia western time)
+# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time)
+# WIT  - +09 - Waktu Indonesia Timur (Indonesia eastern time)
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # Java, Sumatra
@@ -1848,11 +1844,11 @@
 Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
-			5:00	-	FRUT	1930 Jun 21 # Frunze Time
-			6:00 RussiaAsia FRU%sT	1991 Mar 31  2:00s
-			5:00	1:00	FRUST	1991 Aug 31  2:00 # independence
-			5:00	Kyrgyz	KG%sT	2005 Aug 12 # Kyrgyzstan Time
-			6:00	-	KGT
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia +06/+07	1991 Mar 31  2:00s
+			5:00 RussiaAsia	+05/+06	1991 Aug 31  2:00
+			5:00	Kyrgyz	+05/+06	2005 Aug 12
+			6:00	-	+06
 
 ###############################################################################
 
@@ -1891,25 +1887,24 @@
 Rule	ROK	1987	1988	-	May	Sun>=8	2:00	1:00	D
 Rule	ROK	1987	1988	-	Oct	Sun>=8	3:00	0	S
 
-# From Paul Eggert (2014-10-30):
+# From Paul Eggert (2016-08-23):
 # The Korean Wikipedia entry gives the following sources for UT offsets:
 #
-# 1908: Official Journal Article No. 3994 (Edict No. 5)
+# 1908: Official Journal Article No. 3994 (decree No. 5)
 # 1912: Governor-General of Korea Official Gazette Issue No. 367
 #       (Announcement No. 338)
 # 1954: Presidential Decree No. 876 (1954-03-17)
 # 1961: Law No. 676 (1961-08-07)
-# 1987: Law No. 3919 (1986-12-31)
 #
-# The Wikipedia entry also has confusing information about a change
-# to UT+9 in April 1910, but then what would be the point of the later change
-# to UT+9 on 1912-01-01?  Omit the 1910 change for now.
+# (Another source "1987: Law No. 3919 (1986-12-31)" was in the 2014-10-30
+# edition of the Korean Wikipedia entry.)
 #
 # I guessed that time zone abbreviations through 1945 followed the same
 # rules as discussed under Taiwan, with nominal switches from JST to KST
 # when the respective cities were taken over by the Allies after WWII.
 #
-# For Pyongyang we have no information; guess no changes since World War II.
+# For Pyongyang, guess no changes from World War II until 2015, as we
+# have no information otherwise.
 
 # From Steffen Thorsen (2015-08-07):
 # According to many news sources, North Korea is going to change to
@@ -2069,7 +2064,7 @@
 # Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
 # there is only one time zone and that DST is observed, citing Microsoft
 # Windows XP as the source.  Risto Nykänen (2005-05-16) reports that
-# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
+# travelmongolia.org says there are two time zones (UT +07, +08) with no DST.
 # Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
 # Washington, DC says there are two time zones, with DST observed.
 # He also found
@@ -2705,7 +2700,7 @@
 # earlier date.
 #
 # Shanks & Pottenger also state that until 1968-05-01 Saudi Arabia had two
-# time zones; the other zone, at UTC+4, was in the far eastern part of
+# time zones; the other zone, at UT +04, was in the far eastern part of
 # the country.  Ignore this, as it's before our 1970 cutoff.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2974,10 +2969,10 @@
 # From Shanks & Pottenger.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
-			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
-			6:00 RussiaAsia DUS%sT	1991 Mar 31  2:00s
-			5:00	1:00	DUSST	1991 Sep  9  2:00s
-			5:00	-	TJT	# Tajikistan Time
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia +06/+07	1991 Mar 31  2:00s
+			5:00	1:00	+05/+06	1991 Sep  9  2:00s
+			5:00	-	+05
 
 # Thailand
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2991,11 +2986,10 @@
 # From Shanks & Pottenger.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
-			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
-			5:00 RussiaAsia	ASH%sT	1991 Mar 31  2:00
-			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
-			4:00 RussiaAsia	TM%sT	1992 Jan 19  2:00
-			5:00	-	TMT
+			4:00	-	+04	1930 Jun 21
+			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00
+			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00
+			5:00	-	+05
 
 # United Arab Emirates
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -3007,20 +3001,18 @@
 # Byalokoz 1919 says Uzbekistan was 4:27:53.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Samarkand	4:27:53 -	LMT	1924 May  2
-			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
-			5:00	-	SAMT	1981 Apr  1
-			5:00	1:00	SAMST	1981 Oct  1
-			6:00	-	TAST	1982 Apr  1 # Tashkent Time
-			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
+			4:00	-	+04	1930 Jun 21
+			5:00	-	+05	1981 Apr  1
+			5:00	1:00	+06	1981 Oct  1
+			6:00	-	+06	1982 Apr  1
+			5:00 RussiaAsia	+05/+06	1992
+			5:00	-	+05
 # Milne says Tashkent was 4:37:10.8; round to nearest.
 Zone	Asia/Tashkent	4:37:11 -	LMT	1924 May  2
-			5:00	-	TAST	1930 Jun 21 # Tashkent Time
-			6:00 RussiaAsia	TAS%sT	1991 Mar 31  2:00
-			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia	+06/+07	1991 Mar 31  2:00
+			5:00 RussiaAsia	+05/+06	1992
+			5:00	-	+05
 
 # Vietnam
 
--- a/jdk/make/data/tzdata/australasia	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/australasia	Mon Oct 10 13:31:48 2016 -0700
@@ -568,7 +568,7 @@
 # Base the Bougainville entry on the Arawa-Kieta region, which appears to have
 # the most people even though it was devastated in the Bougainville Civil War.
 #
-# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates
+# Although Shanks gives 1942-03-15 / 1943-11-01 for UT +09, these dates
 # are apparently rough guesswork from the starts of military campaigns.
 # The World War II entries below are instead based on Arawa-Kieta.
 # The Japanese occupied Kieta in July 1942,
@@ -576,8 +576,8 @@
 # http://pwencycl.kgbudge.com/B/o/Bougainville.htm
 # and seem to have controlled it until their 1945-08-21 surrender.
 #
-# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11
-# on 2014-12-28 at 02:00.  They call UTC+11 "Bougainville Standard Time";
+# The Autonomous Region of Bougainville switched from UT +10 to +11
+# on 2014-12-28 at 02:00.  They call +11 "Bougainville Standard Time";
 # abbreviate this as BST.  See:
 # http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/
 #
@@ -643,7 +643,7 @@
 # From Paul Eggert (2014-06-27):
 # The International Date Line Act 2011
 # http://www.parliament.gov.ws/images/ACTS/International_Date_Line_Act__2011_-_Eng.pdf
-# changed Samoa from UTC-11 to UTC+13, effective "12 o'clock midnight, on
+# changed Samoa from UT -11 to +13, effective "12 o'clock midnight, on
 # Thursday 29th December 2011".  The International Date Line was adjusted
 # accordingly.
 
@@ -738,7 +738,7 @@
 # 1886-1891; Baker was similar but exact dates are not known.
 # Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
 # uninhabited thereafter.
-# Howland observed Hawaii Standard Time (UT-10:30) in 1937;
+# Howland observed Hawaii Standard Time (UT -10:30) in 1937;
 # see page 206 of Elgen M. Long and Marie K. Long,
 # Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
 # So most likely Howland and Baker observed Hawaii Time from 1935
@@ -1496,7 +1496,7 @@
 # Zealand time.  I understand that is the time they keep locally, anyhow."
 # For now, assume this practice goes back to the introduction of standard time
 # in New Zealand, as this would make Chatham Islands time almost exactly match
-# LMT back when New Zealand was at UTC+11:30; also, assume Chatham Islands did
+# LMT back when New Zealand was at UT +11:30; also, assume Chatham Islands did
 # not observe New Zealand's prewar DST.
 
 ###############################################################################
@@ -1552,7 +1552,7 @@
 # For now, we assume the Ladrones switched at the same time as the Philippines;
 # see Asia/Manila.
 
-# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
+# US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
 # under the name "Chamorro Standard Time".  There is no official abbreviation,
 # but Congressman Robert A. Underwood, author of the bill that became law,
 # wrote in a press release (2000-12-27) that he will seek the use of "ChST".
@@ -1564,15 +1564,15 @@
 # "I am certain, having lived there for the past decade, that 'Truk'
 # (now properly known as Chuuk) ... is in the time zone GMT+10."
 #
-# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
+# Shanks & Pottenger write that Truk switched from UT +10 to +11
 # on 1978-10-01; ignore this for now.
 
 # From Paul Eggert (1999-10-29):
 # The Federated States of Micronesia Visitors Board writes in
 # The Federated States of Micronesia - Visitor Information (1999-01-26)
 # http://www.fsmgov.org/info/clocks.html
-# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
-# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
+# We don't know when Kosrae switched from +12; assume January 1 for now.
 
 
 # Midway
@@ -1638,11 +1638,11 @@
 # ordaining - by a masterpiece of diplomatic flattery - that
 # the Fourth of July should be celebrated twice in that year."
 
-# Although Shanks & Pottenger says they both switched to UTC-11:30
-# in 1911, and to UTC-11 in 1950. many earlier sources give UTC-11
+# Although Shanks & Pottenger says they both switched to UT -11:30
+# in 1911, and to -11 in 1950. many earlier sources give -11
 # for American Samoa, e.g., the US National Bureau of Standards
 # circular "Standard Time Throughout the World", 1932.
-# Assume American Samoa switched to UTC-11 in 1911, not 1950,
+# Assume American Samoa switched to -11 in 1911, not 1950,
 # and that after 1950 they agreed until (western) Samoa skipped a
 # day in 2011.  Assume also that the Samoas follow the US and New
 # Zealand's "ST"/"DT" style of daylight-saving abbreviations.
--- a/jdk/make/data/tzdata/backward	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/backward	Mon Oct 10 13:31:48 2016 -0700
@@ -59,6 +59,7 @@
 Link	Asia/Urumqi		Asia/Kashgar
 Link	Asia/Kathmandu		Asia/Katmandu
 Link	Asia/Macau		Asia/Macao
+Link	Asia/Yangon		Asia/Rangoon
 Link	Asia/Ho_Chi_Minh	Asia/Saigon
 Link	Asia/Jerusalem		Asia/Tel_Aviv
 Link	Asia/Thimphu		Asia/Thimbu
--- a/jdk/make/data/tzdata/etcetera	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/etcetera	Mon Oct 10 13:31:48 2016 -0700
@@ -31,6 +31,13 @@
 # need now for the entries that are not on UTC are for ships at sea
 # that cannot use POSIX TZ settings.
 
+# Starting with POSIX 1003.1-2001, the entries below are all
+# unnecessary as settings for the TZ environment variable.  E.g.,
+# instead of TZ='Etc/GMT+4' one can use the POSIX setting TZ='<-04>+4'.
+#
+# Do not use a POSIX TZ setting like TZ='GMT+4', which is four hours
+# behind GMT but uses the completely misleading abbreviation "GMT".
+
 Zone	Etc/GMT		0	-	GMT
 Zone	Etc/UTC		0	-	UTC
 Zone	Etc/UCT		0	-	UCT
@@ -49,23 +56,13 @@
 Link	Etc/GMT				Etc/GMT+0
 Link	Etc/GMT				Etc/GMT0
 
-# We use POSIX-style signs in the Zone names and the output abbreviations,
+# Be consistent with POSIX TZ settings in the Zone names,
 # even though this is the opposite of what many people expect.
 # POSIX has positive signs west of Greenwich, but many people expect
 # positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
-# the abbreviation "GMT+4" and corresponds to 4 hours behind UT
+# the abbreviation "-04" and corresponds to 4 hours behind UT
 # (i.e. west of Greenwich) even though many people would expect it to
 # mean 4 hours ahead of UT (i.e. east of Greenwich).
-#
-# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
-# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
-# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
-# offset is kept within the angle bracket (and is used for display)
-# while the POSIX sign is kept outside the angle bracket (and is used
-# for calculation).
-#
-# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
-# GMT but uses the completely misleading abbreviation "GMT".
 
 # Earlier incarnations of this package were not POSIX-compliant,
 # and had lines such as
@@ -74,30 +71,31 @@
 # way does a
 #		zic -l GMT-12
 # so we moved the names into the Etc subdirectory.
+# Also, the time zone abbreviations are now compatible with %z.
 
-Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
-Zone	Etc/GMT-13	13	-	GMT-13
-Zone	Etc/GMT-12	12	-	GMT-12
-Zone	Etc/GMT-11	11	-	GMT-11
-Zone	Etc/GMT-10	10	-	GMT-10
-Zone	Etc/GMT-9	9	-	GMT-9
-Zone	Etc/GMT-8	8	-	GMT-8
-Zone	Etc/GMT-7	7	-	GMT-7
-Zone	Etc/GMT-6	6	-	GMT-6
-Zone	Etc/GMT-5	5	-	GMT-5
-Zone	Etc/GMT-4	4	-	GMT-4
-Zone	Etc/GMT-3	3	-	GMT-3
-Zone	Etc/GMT-2	2	-	GMT-2
-Zone	Etc/GMT-1	1	-	GMT-1
-Zone	Etc/GMT+1	-1	-	GMT+1
-Zone	Etc/GMT+2	-2	-	GMT+2
-Zone	Etc/GMT+3	-3	-	GMT+3
-Zone	Etc/GMT+4	-4	-	GMT+4
-Zone	Etc/GMT+5	-5	-	GMT+5
-Zone	Etc/GMT+6	-6	-	GMT+6
-Zone	Etc/GMT+7	-7	-	GMT+7
-Zone	Etc/GMT+8	-8	-	GMT+8
-Zone	Etc/GMT+9	-9	-	GMT+9
-Zone	Etc/GMT+10	-10	-	GMT+10
-Zone	Etc/GMT+11	-11	-	GMT+11
-Zone	Etc/GMT+12	-12	-	GMT+12
+Zone	Etc/GMT-14	14	-	+14
+Zone	Etc/GMT-13	13	-	+13
+Zone	Etc/GMT-12	12	-	+12
+Zone	Etc/GMT-11	11	-	+11
+Zone	Etc/GMT-10	10	-	+10
+Zone	Etc/GMT-9	9	-	+09
+Zone	Etc/GMT-8	8	-	+08
+Zone	Etc/GMT-7	7	-	+07
+Zone	Etc/GMT-6	6	-	+06
+Zone	Etc/GMT-5	5	-	+05
+Zone	Etc/GMT-4	4	-	+04
+Zone	Etc/GMT-3	3	-	+03
+Zone	Etc/GMT-2	2	-	+02
+Zone	Etc/GMT-1	1	-	+01
+Zone	Etc/GMT+1	-1	-	-01
+Zone	Etc/GMT+2	-2	-	-02
+Zone	Etc/GMT+3	-3	-	-03
+Zone	Etc/GMT+4	-4	-	-04
+Zone	Etc/GMT+5	-5	-	-05
+Zone	Etc/GMT+6	-6	-	-06
+Zone	Etc/GMT+7	-7	-	-07
+Zone	Etc/GMT+8	-8	-	-08
+Zone	Etc/GMT+9	-9	-	-09
+Zone	Etc/GMT+10	-10	-	-10
+Zone	Etc/GMT+11	-11	-	-11
+Zone	Etc/GMT+12	-12	-	-12
--- a/jdk/make/data/tzdata/europe	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/europe	Mon Oct 10 13:31:48 2016 -0700
@@ -98,8 +98,7 @@
 #        1:00       CET CEST CEMT Central Europe
 #        1:00:14    SET           Swedish (1879-1899)*
 #        2:00       EET EEST      Eastern Europe
-#        3:00       FET           Further-eastern Europe (2011-2014)*
-#        3:00       MSK MSD  MSM* Minsk, Moscow
+#        3:00       MSK MSD       Moscow
 
 # From Peter Ilieve (1994-12-04),
 # The original six [EU members]: Belgium, France, (West) Germany, Italy,
@@ -606,16 +605,33 @@
 Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
 Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
 
+
+# Daylight saving time for Russia and the Soviet Union
+#
+# The 1917-1921 decree URLs are from Alexander Belopolsky (2016-08-23).
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST  # Moscow Summer Time
+#
+# Decree No. 142 (1917-12-22) http://istmat.info/node/28137
 Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT  # Moscow Mean Time
+#
+# Decree No. 497 (1918-05-30) http://istmat.info/node/30001
 Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST # Moscow Double Summer Time
 Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
+#
+# Decree No. 258 (1919-05-29) http://istmat.info/node/37949
 Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
-Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	MSD
+#
+Rule	Russia	1919	only	-	Jul	 1	 0:00u	1:00	MSD
 Rule	Russia	1919	only	-	Aug	16	 0:00	0	MSK
+#
+# Decree No. 63 (1921-02-03) http://istmat.info/node/45840
 Rule	Russia	1921	only	-	Feb	14	23:00	1:00	MSD
-Rule	Russia	1921	only	-	Mar	20	23:00	2:00	MSM  # Midsummer
+#
+# Decree No. 121 (1921-03-07) http://istmat.info/node/45949
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	+05
+#
 Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	MSD
 Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
 # Act No. 925 of the Council of Ministers of the USSR (1980-10-24):
@@ -798,8 +814,6 @@
 # From Alexander Bokovoy (2014-10-09):
 # Belarussian government decided against changing to winter time....
 # http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
-# From Paul Eggert (2014-10-08):
-# Hence Belarus can share time zone abbreviations with Moscow again.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Minsk	1:50:16 -	LMT	1880
@@ -810,8 +824,7 @@
 			3:00	Russia	MSK/MSD	1990
 			3:00	-	MSK	1991 Mar 31  2:00s
 			2:00	Russia	EE%sT	2011 Mar 27  2:00s
-			3:00	-	FET	2014 Oct 26  1:00s
-			3:00	-	MSK
+			3:00	-	+03
 
 # Belgium
 #
@@ -1319,7 +1332,7 @@
 # http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
 # says that Bersarin issued an order to use Moscow time on May 20.
 # However, Moscow did not observe daylight saving in 1945, so
-# this was equivalent to CEMT (GMT+3), not GMT+4.
+# this was equivalent to UT +03, not +04.
 
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -2283,7 +2296,6 @@
 # http://www.worldtimezone.com/dst_news/dst_news_russia-map-2014-07.html
 
 # From Paul Eggert (2006-03-22):
-# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
 # Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
 # are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
 # except we follow Chernov's report that 1992 DST transitions were Sat
@@ -2359,7 +2371,7 @@
 			 2:00	Poland	CE%sT	1946
 			 3:00	Russia	MSK/MSD	1989 Mar 26  2:00s
 			 2:00	Russia	EE%sT	2011 Mar 27  2:00s
-			 3:00	-	FET	2014 Oct 26  2:00s
+			 3:00	-	+03	2014 Oct 26  2:00s
 			 2:00	-	EET
 
 
@@ -2412,6 +2424,16 @@
 # 78	RU-SPE	Saint Petersburg
 # 83	RU-NEN	Nenets Autonomous Okrug
 
+# From Paul Eggert (2016-08-23):
+# The Soviets switched to UT-based time in 1919.  Decree No. 59
+# (1919-02-08) http://istmat.info/node/35567 established UT-based time
+# zones, and Decree No. 147 (1919-03-29) http://istmat.info/node/35854
+# specified a transition date of 1919-07-01, apparently at 00:00 UT.
+# No doubt only the Soviet-controlled regions switched on that date;
+# later transitions to UT-based time in other parts of Russia are
+# taken from what appear to be guesses by Shanks.
+# (Thanks to Alexander Belopolsky for pointers to the decrees.)
+
 # From Stepan Golosunov (2016-03-07):
 # 11. Regions-violators, 1981-1982.
 # Wikipedia refers to
@@ -2453,7 +2475,7 @@
 # attributes the 1982 changes to the Act of the Council of Ministers
 # of the USSR No. 126 from 18.02.1982.  1980-925.txt also adds
 # Udmurtia to the list of affected territories and lists Khatangsky
-# district separately from Taymyr Autonomous Okurg.  Probably erroneously.
+# district separately from Taymyr Autonomous Okrug.  Probably erroneously.
 #
 # The affected territories are currently listed under Europe/Moscow,
 # Asia/Yekaterinburg and Asia/Krasnoyarsk.
@@ -2513,7 +2535,7 @@
 
 Zone Europe/Moscow	 2:30:17 -	LMT	1880
 			 2:30:17 -	MMT	1916 Jul  3 # Moscow Mean Time
-			 2:31:19 Russia	%s	1919 Jul  1  2:00
+			 2:31:19 Russia	%s	1919 Jul  1  0:00u
 			 3:00	Russia	%s	1921 Oct
 			 3:00	Russia	MSK/MSD	1922 Oct
 			 2:00	-	EET	1930 Jun 21
@@ -2596,22 +2618,21 @@
 # The 1988 transition is from USSR act No. 5 (1988-01-04).
 
 Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
-			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
-			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
-			 4:00	-	STAT	1961 Nov 11
-			 4:00	Russia	VOL%sT	1988 Mar 27  2:00s # Volgograd T
-			 3:00	Russia	VOL%sT	1991 Mar 31  2:00s
-			 4:00	-	VOLT	1992 Mar 29  2:00s
-			 3:00	Russia	MSK/MSD	2011 Mar 27  2:00s
-			 4:00	-	MSK	2014 Oct 26  2:00s
-			 3:00	-	MSK
+			 3:00	-	+03	1930 Jun 21
+			 4:00	-	+04	1961 Nov 11
+			 4:00	Russia	+04/+05	1988 Mar 27  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 4:00	-	+04	1992 Mar 29  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04	2014 Oct 26  2:00s
+			 3:00	-	+03
 
 # From Paul Eggert (2016-03-18):
 # Europe/Kirov covers:
 # 43	RU-KIR	Kirov Oblast
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
 #
-Zone Europe/Kirov	 3:18:48 -	LMT	1919 Jul  1  2:00
+Zone Europe/Kirov	 3:18:48 -	LMT	1919 Jul  1  0:00u
 			 3:00	-	+03	1930 Jun 21
 			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
 			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
@@ -2629,16 +2650,16 @@
 # Byalokoz 1919 says Samara was 3:20:20.
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
 
-Zone Europe/Samara	 3:20:20 -	LMT	1919 Jul  1  2:00
-			 3:00	-	SAMT	1930 Jun 21 # Samara Time
-			 4:00	-	SAMT	1935 Jan 27
-			 4:00	Russia	KUY%sT	1989 Mar 26  2:00s # Kuybyshev
-			 3:00	Russia	MSK/MSD	1991 Mar 31  2:00s
-			 2:00	Russia	EE%sT	1991 Sep 29  2:00s
-			 3:00	-	SAMT	1991 Oct 20  3:00
-			 4:00	Russia	SAM%sT	2010 Mar 28  2:00s
-			 3:00	Russia	SAM%sT	2011 Mar 27  2:00s
-			 4:00	-	SAMT
+Zone Europe/Samara	 3:20:20 -	LMT	1919 Jul  1  0:00u
+			 3:00	-	+03	1930 Jun 21
+			 4:00	-	+04	1935 Jan 27
+			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 2:00	Russia	+02/+03	1991 Sep 29  2:00s
+			 3:00	-	+03	1991 Oct 20  3:00
+			 4:00	Russia	+04/+05	2010 Mar 28  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04
 
 # From Paul Eggert (2016-03-18):
 # Europe/Ulyanovsk covers:
@@ -2653,7 +2674,7 @@
 # From Matt Johnson (2016-03-09):
 # http://publication.pravo.gov.ru/Document/View/0001201603090051
 
-Zone Europe/Ulyanovsk	 3:13:36 -	LMT	1919 Jul  1  2:00
+Zone Europe/Ulyanovsk	 3:13:36 -	LMT	1919 Jul  1  0:00u
 			 3:00	-	+03	1930 Jun 21
 			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
 			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
@@ -2685,12 +2706,12 @@
 
 Zone Asia/Yekaterinburg	 4:02:33 -	LMT	1916 Jul  3
 			 3:45:05 -	PMT	1919 Jul 15  4:00
-			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
-			 5:00	Russia	SVE%sT	1991 Mar 31  2:00s
-			 4:00	Russia	SVE%sT	1992 Jan 19  2:00s
-			 5:00	Russia	YEK%sT	2011 Mar 27  2:00s
-			 6:00	-	YEKT	2014 Oct 26  2:00s
-			 5:00	-	YEKT
+			 4:00	-	+04	1930 Jun 21
+			 5:00	Russia	+05/+06	1991 Mar 31  2:00s
+			 4:00	Russia	+04/+05	1992 Jan 19  2:00s
+			 5:00	Russia	+05/+06	2011 Mar 27  2:00s
+			 6:00	-	+06	2014 Oct 26  2:00s
+			 5:00	-	+05
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -2700,12 +2721,12 @@
 # Byalokoz 1919 says Omsk was 4:53:30.
 
 Zone Asia/Omsk		 4:53:30 -	LMT	1919 Nov 14
-			 5:00	-	OMST	1930 Jun 21 # Omsk Time
-			 6:00	Russia	OMS%sT	1991 Mar 31  2:00s
-			 5:00	Russia	OMS%sT	1992 Jan 19  2:00s
-			 6:00	Russia	OMS%sT	2011 Mar 27  2:00s
-			 7:00	-	OMST	2014 Oct 26  2:00s
-			 6:00	-	OMST
+			 5:00	-	+05	1930 Jun 21
+			 6:00	Russia	+06/+07	1991 Mar 31  2:00s
+			 5:00	Russia	+05/+06	1992 Jan 19  2:00s
+			 6:00	Russia	+06/+07	2011 Mar 27  2:00s
+			 7:00	-	+07	2014 Oct 26  2:00s
+			 6:00	-	+06
 
 # From Paul Eggert (2016-02-22):
 # Asia/Barnaul covers:
@@ -2785,7 +2806,7 @@
 # Note that time belts (numbered from 2 (Moscow) to 12 according to their
 # GMT/UTC offset and having too many exceptions like regions formally
 # belonging to one belt but using time from another) were replaced
-# with time zones in 2011 with different numberings (there was a
+# with time zones in 2011 with different numbering (there was a
 # 2-hour gap between second and third zones in 2011-2014).
 
 # From Stepan Golosunov (2016-04-12):
@@ -2868,12 +2889,12 @@
 # Byalokoz 1919 says Krasnoyarsk was 6:11:26.
 
 Zone Asia/Krasnoyarsk	 6:11:26 -	LMT	1920 Jan  6
-			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
-			 7:00	Russia	KRA%sT	1991 Mar 31  2:00s
-			 6:00	Russia	KRA%sT	1992 Jan 19  2:00s
-			 7:00	Russia	KRA%sT	2011 Mar 27  2:00s
-			 8:00	-	KRAT	2014 Oct 26  2:00s
-			 7:00	-	KRAT
+			 6:00	-	+06	1930 Jun 21
+			 7:00	Russia	+07/+08	1991 Mar 31  2:00s
+			 6:00	Russia	+06/+07	1992 Jan 19  2:00s
+			 7:00	Russia	+07/+08	2011 Mar 27  2:00s
+			 8:00	-	+08	2014 Oct 26  2:00s
+			 7:00	-	+07
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -2890,12 +2911,12 @@
 
 Zone Asia/Irkutsk	 6:57:05 -	LMT	1880
 			 6:57:05 -	IMT	1920 Jan 25 # Irkutsk Mean Time
-			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
-			 8:00	Russia	IRK%sT	1991 Mar 31  2:00s
-			 7:00	Russia	IRK%sT	1992 Jan 19  2:00s
-			 8:00	Russia	IRK%sT	2011 Mar 27  2:00s
-			 9:00	-	IRKT	2014 Oct 26  2:00s
-			 8:00	-	IRKT
+			 7:00	-	+07	1930 Jun 21
+			 8:00	Russia	+08/+09	1991 Mar 31  2:00s
+			 7:00	Russia	+07/+08	1992 Jan 19  2:00s
+			 8:00	Russia	+08/+09	2011 Mar 27  2:00s
+			 9:00	-	+09	2014 Oct 26  2:00s
+			 8:00	-	+08
 
 
 # From Tim Parenti (2014-07-06):
@@ -2912,13 +2933,13 @@
 # http://publication.pravo.gov.ru/Document/View/0001201512300107
 
 Zone Asia/Chita	 7:33:52 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2011 Mar 27  2:00s
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 8:00	-	IRKT	2016 Mar 27  2:00
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2011 Mar 27  2:00s
+			10:00	-	+10	2014 Oct 26  2:00s
+			 8:00	-	+08	2016 Mar 27  2:00
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -2958,12 +2979,12 @@
 # Byalokoz 1919 says Yakutsk was 8:38:58.
 
 Zone Asia/Yakutsk	 8:38:58 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2011 Mar 27  2:00s
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2011 Mar 27  2:00s
+			10:00	-	+10	2014 Oct 26  2:00s
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -2981,12 +3002,12 @@
 # Go with Byalokoz.
 
 Zone Asia/Vladivostok	 8:47:31 -	LMT	1922 Nov 15
-			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
-			10:00	Russia	VLA%sT	1991 Mar 31  2:00s
-			 9:00	Russia	VLA%sT	1992 Jan 19  2:00s
-			10:00	Russia	VLA%sT	2011 Mar 27  2:00s
-			11:00	-	VLAT	2014 Oct 26  2:00s
-			10:00	-	VLAT
+			 9:00	-	+09	1930 Jun 21
+			10:00	Russia	+10/+11	1991 Mar 31  2:00s
+			 9:00	Russia	+09/+10	1992 Jan 19  2:00s
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10
 
 
 # From Tim Parenti (2014-07-03):
@@ -3004,14 +3025,14 @@
 # This transition is no doubt wrong, but we have no better info.
 
 Zone Asia/Khandyga	 9:02:13 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2004
-			10:00	Russia	VLA%sT	2011 Mar 27  2:00s
-			11:00	-	VLAT	2011 Sep 13  0:00s # Decree 725?
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2004
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2011 Sep 13  0:00s # Decree 725?
+			10:00	-	+10	2014 Oct 26  2:00s
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03):
@@ -3027,15 +3048,14 @@
 
 # The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long.
 Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
-			 9:00	-	JCST	1937 Oct  1
-			 9:00	-	JST	1945 Aug 25
-			11:00	Russia	SAK%sT	1991 Mar 31  2:00s # Sakhalin T
-			10:00	Russia	SAK%sT	1992 Jan 19  2:00s
-			11:00	Russia	SAK%sT	1997 Mar lastSun  2:00s
-			10:00	Russia	SAK%sT	2011 Mar 27  2:00s
-			11:00	-	SAKT	2014 Oct 26  2:00s
-			10:00	-	SAKT	2016 Mar 27  2:00s
-			11:00	-	SAKT
+			 9:00	-	+09	1945 Aug 25
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s # Sakhalin T
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	1997 Mar lastSun  2:00s
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10	2016 Mar 27  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -3058,13 +3078,13 @@
 # http://publication.pravo.gov.ru/Document/View/0001201604050038
 
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
-			10:00	-	MAGT	1930 Jun 21 # Magadan Time
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2014 Oct 26  2:00s
-			10:00	-	MAGT	2016 Apr 24  2:00s
-			11:00	-	MAGT
+			10:00	-	+10	1930 Jun 21 # Magadan Time
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2014 Oct 26  2:00s
+			10:00	-	+10	2016 Apr 24  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-06):
@@ -3107,17 +3127,14 @@
 # in Russian.)  In addition, Srednekolymsk appears to be a much older
 # settlement and the population of Zyryanka seems to be declining.
 # Go with Srednekolymsk.
-#
-# Since Magadan Oblast moves to UTC+10 on 2014-10-26, we cannot keep using MAGT
-# as the abbreviation.  Use SRET instead.
 
 Zone Asia/Srednekolymsk	10:14:52 -	LMT	1924 May  2
-			10:00	-	MAGT	1930 Jun 21 # Magadan Time
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2014 Oct 26  2:00s
-			11:00	-	SRET	# Srednekolymsk Time
+			10:00	-	+10	1930 Jun 21
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2014 Oct 26  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-03):
@@ -3135,14 +3152,14 @@
 # UTC+12 since at least then, too.
 
 Zone Asia/Ust-Nera	 9:32:54 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAKT	1981 Apr  1
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2011 Sep 13  0:00s # Decree 725?
-			11:00	-	VLAT	2014 Oct 26  2:00s
-			10:00	-	VLAT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1981 Apr  1
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2011 Sep 13  0:00s # Decree 725?
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -3155,12 +3172,12 @@
 # The Zone name should be Asia/Petropavlovsk-Kamchatski or perhaps
 # Asia/Petropavlovsk-Kamchatsky, but these are too long.
 Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
-			11:00	-	PETT	1930 Jun 21 # P-K Time
-			12:00	Russia	PET%sT	1991 Mar 31  2:00s
-			11:00	Russia	PET%sT	1992 Jan 19  2:00s
-			12:00	Russia	PET%sT	2010 Mar 28  2:00s
-			11:00	Russia	PET%sT	2011 Mar 27  2:00s
-			12:00	-	PETT
+			11:00	-	+11	1930 Jun 21
+			12:00	Russia	+12/+13	1991 Mar 31  2:00s
+			11:00	Russia	+11/+12	1992 Jan 19  2:00s
+			12:00	Russia	+12/+13	2010 Mar 28  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12
 
 
 # From Tim Parenti (2014-07-03):
@@ -3168,13 +3185,13 @@
 # 87	RU-CHU	Chukotka Autonomous Okrug
 
 Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
-			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
-			13:00	Russia	ANA%sT	1982 Apr  1  0:00s
-			12:00	Russia	ANA%sT	1991 Mar 31  2:00s
-			11:00	Russia	ANA%sT	1992 Jan 19  2:00s
-			12:00	Russia	ANA%sT	2010 Mar 28  2:00s
-			11:00	Russia	ANA%sT	2011 Mar 27  2:00s
-			12:00	-	ANAT
+			12:00	-	+12	1930 Jun 21
+			13:00	Russia	+13/+14	1982 Apr  1  0:00s
+			12:00	Russia	+12/+13	1991 Mar 31  2:00s
+			11:00	Russia	+11/+12	1992 Jan 19  2:00s
+			12:00	Russia	+12/+13	2010 Mar 28  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12
 
 
 # San Marino
@@ -3495,6 +3512,14 @@
 # Engineered Standard Time," said Twitter user @aysekarahasan.
 # http://www.bbc.com/news/world-europe-34631326
 
+# From Burak AYDIN (2016-09-08):
+# Turkey will stay in Daylight Saving Time even in winter....
+# http://www.resmigazete.gov.tr/eskiler/2016/09/20160908-2.pdf
+#
+# From Paul Eggert (2016-09-07):
+# The change is permanent, so this is the new standard time in Turkey.
+# It takes effect today, which is not much notice.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
 Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
@@ -3558,7 +3583,7 @@
 Zone	Europe/Istanbul	1:55:52 -	LMT	1880
 			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
 			2:00	Turkey	EE%sT	1978 Oct 15
-			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
+			3:00	Turkey	+03/+04	1985 Apr 20
 			2:00	Turkey	EE%sT	2007
 			2:00	EU	EE%sT	2011 Mar 27  1:00u
 			2:00	-	EET	2011 Mar 28  1:00u
@@ -3566,7 +3591,8 @@
 			2:00	-	EET	2014 Mar 31  1:00u
 			2:00	EU	EE%sT	2015 Oct 25  1:00u
 			2:00	1:00	EEST	2015 Nov  8  1:00u
-			2:00	EU	EE%sT
+			2:00	EU	EE%sT	2016 Sep  7
+			3:00	-	+03
 Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
 
 # Ukraine
--- a/jdk/make/data/tzdata/factory	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/factory	Mon Oct 10 13:31:48 2016 -0700
@@ -24,9 +24,10 @@
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
-# For companies who don't want to put time zone specification in
-# their installation procedures.  When users run date, they'll get the message.
-# Also useful for the "comp.sources" version.
+# For distributors who don't want to put time zone specification in
+# their installation procedures.  Users that run 'date' will get the
+# time zone abbreviation "-00", indicating that the actual time zone
+# is unknown.
 
 # Zone	NAME	GMTOFF	RULES	FORMAT
-Zone	Factory	0	- "Local time zone must be set--see zic manual page"
+Zone	Factory	0	-	-00
--- a/jdk/make/data/tzdata/leapseconds	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/leapseconds	Mon Oct 10 13:31:48 2016 -0700
@@ -79,6 +79,7 @@
 Leap	2008	Dec	31	23:59:60	+	S
 Leap	2012	Jun	30	23:59:60	+	S
 Leap	2015	Jun	30	23:59:60	+	S
+Leap	2016	Dec	31	23:59:60	+	S
 
-#	Updated through IERS Bulletin C51
-#	File expires on:  28 December 2016
+#	Updated through IERS Bulletin C52
+#	File expires on:  28 June 2017
--- a/jdk/make/data/tzdata/northamerica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/northamerica	Mon Oct 10 13:31:48 2016 -0700
@@ -436,11 +436,42 @@
 # north of the Salmon River, and the towns of Burgdorf and Warren),
 # Nevada (except West Wendover), Oregon (except the northern 3/4 of
 # Malheur county), and Washington
+
+# From Paul Eggert (2016-08-20):
+# In early February 1948, in response to California's electricity shortage,
+# PG&E changed power frequency from 60 to 59.5 Hz during daylight hours,
+# causing electric clocks to lose six minutes per day.  (This did not change
+# legal time, and is not part of the data here.)  See:
+# Ross SA. An energy crisis from the past: Northern California in 1948.
+# Working Paper No. 8, Institute of Governmental Studies, UC Berkeley,
+# 1973-11.  http://escholarship.org/uc/item/8x22k30c
+#
+# In another measure to save electricity, DST was instituted from 1948-03-14
+# at 02:01 to 1949-01-16 at 02:00, with the governor having the option to move
+# the fallback transition earlier.  See pages 3-4 of:
+# http://clerk.assembly.ca.gov/sites/clerk.assembly.ca.gov/files/archive/Statutes/1948/48Vol1_Chapters.pdf
+#
+# In response:
+#
+#   Governor Warren received a torrent of objecting mail, and it is not too much
+#   to speculate that the objections to Daylight Saving Time were one important
+#   factor in the defeat of the Dewey-Warren Presidential ticket in California.
+#     -- Ross, p 25
+#
+# On December 8 the governor exercised the option, setting the date to January 1
+# (LA Times 1948-12-09).  The transition time was 02:00 (LA Times 1949-01-01).
+#
+# Despite the controversy, in 1949 California voters approved Proposition 12,
+# which established DST from April's last Sunday at 01:00 until September's
+# last Sunday at 02:00. This was amended by 1962's Proposition 6, which changed
+# the fall-back date to October's last Sunday. See:
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
+Rule	CA	1948	only	-	Mar	14	2:01	1:00	D
 Rule	CA	1949	only	-	Jan	 1	2:00	0	S
-Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	CA	1950	1966	-	Apr	lastSun	1:00	1:00	D
 Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
 Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -3304,7 +3335,7 @@
 # indicating that the normal ET rules are followed.
 #
 # From Paul Eggert (2014-08-19):
-# The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round.  See:
+# The 2014-08-13 Cabinet meeting decided to stay on UT -04 year-round.  See:
 # http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
 # Model this as a switch from EST/EDT to AST ...
 # From Chris Walton (2014-11-04):
--- a/jdk/make/data/tzdata/southamerica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/southamerica	Mon Oct 10 13:31:48 2016 -0700
@@ -433,9 +433,9 @@
 # stuck on Summer daylight savings time even though the summer is over.
 
 # From Paul Eggert (2013-09-05):
-# Perhaps San Luis operates on the legal fiction that it is at UTC-4
+# Perhaps San Luis operates on the legal fiction that it is at -04
 # with perpetual summer time, but ordinary usage typically seems to
-# just say it's at UTC-3; see, for example,
+# just say it's at -03; see, for example,
 # http://es.wikipedia.org/wiki/Hora_oficial_argentina
 # We've documented similar situations as being plain changes to
 # standard time, so let's do that here too.  This does not change UTC
--- a/jdk/make/data/tzdata/zone.tab	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/data/tzdata/zone.tab	Mon Oct 10 13:31:48 2016 -0700
@@ -284,7 +284,7 @@
 MH	+0905+16720	Pacific/Kwajalein	Kwajalein
 MK	+4159+02126	Europe/Skopje
 ML	+1239-00800	Africa/Bamako
-MM	+1647+09610	Asia/Rangoon
+MM	+1647+09610	Asia/Yangon
 MN	+4755+10653	Asia/Ulaanbaatar	Mongolia (most areas)
 MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
 MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
--- a/jdk/make/lib/CoreLibraries.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/lib/CoreLibraries.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -218,7 +218,7 @@
         $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \
         -export:ZIP_ReadEntry -export:ZIP_GetNextEntry \
-        -export:ZIP_InflateFully -export:ZIP_CRC32, \
+        -export:ZIP_InflateFully -export:ZIP_CRC32 -export:ZIP_FreeEntry, \
     LIBS_unix := -ljvm -ljava $(LIBZ), \
     LIBS_solaris := -lc, \
     LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
--- a/jdk/make/mapfiles/libzip/mapfile-vers	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/mapfiles/libzip/mapfile-vers	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -49,6 +49,7 @@
 		Java_java_util_zip_Inflater_setDictionary;
 		ZIP_Close;
 		ZIP_CRC32;
+		ZIP_FreeEntry;
 		ZIP_FindEntry;
 		ZIP_GetEntry;
 		ZIP_GetNextEntry;
--- a/jdk/make/rmic/RmicCommon.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/make/rmic/RmicCommon.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -37,7 +37,7 @@
   RMIC_MAIN_CLASS := sun.rmi.rmic.Main
 endif
 
-RMIC := $(JAVA) $(INTERIM_OVERRIDE_MODULES_ARGS) $(RMIC_MAIN_CLASS)
+RMIC := $(JAVA_SMALL) $(INTERIM_OVERRIDE_MODULES_ARGS) $(RMIC_MAIN_CLASS)
 
 CLASSES_DIR := $(JDK_OUTPUTDIR)/modules
 # NOTE: If the smart javac dependency management is reintroduced, these classes risk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/AddPackagesAttribute.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.jigsaw;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+import java.util.Set;
+
+import jdk.internal.module.ModuleInfoExtender;
+
+/**
+ * Adds the Packages class file attribute to each module-info.class in an
+ * exploded build.
+ */
+
+public class AddPackagesAttribute {
+
+    public static void main(String[] args) throws IOException {
+
+        if (args.length != 1) {
+            System.err.println("Usage AddPackagesAttribute exploded-java-home");
+            System.exit(-1);
+        }
+
+        String home = args[0];
+        Path dir = Paths.get(home, "modules");
+
+        ModuleFinder finder = ModuleFinder.of(dir);
+
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+            for (Path entry : stream) {
+                Path mi = entry.resolve("module-info.class");
+                if (Files.isRegularFile(mi)) {
+                    String mn = entry.getFileName().toString();
+                    Optional<ModuleReference> omref = finder.find(mn);
+                    if (omref.isPresent()) {
+                        Set<String> packages = omref.get().descriptor().conceals();
+                        addPackagesAttribute(mi, packages);
+                    }
+                }
+            }
+        }
+    }
+
+    static void addPackagesAttribute(Path mi, Set<String> packages) throws IOException {
+        byte[] bytes;
+        try (InputStream in = Files.newInputStream(mi)) {
+            ModuleInfoExtender extender = ModuleInfoExtender.newExtender(in);
+            extender.conceals(packages);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            extender.write(baos);
+            bytes = baos.toByteArray();
+        }
+
+        Files.write(mi, bytes);
+    }
+
+}
--- a/jdk/src/java.base/share/classes/java/io/FilePermission.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/FilePermission.java	Mon Oct 10 13:31:48 2016 -0700
@@ -25,11 +25,20 @@
 
 package java.io;
 
+import java.net.URI;
+import java.nio.file.*;
 import java.security.*;
 import java.util.Enumeration;
+import java.util.Objects;
 import java.util.StringJoiner;
 import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
+
+import jdk.internal.misc.JavaIOFilePermissionAccess;
+import jdk.internal.misc.SharedSecrets;
+import sun.nio.fs.DefaultFileSystemProvider;
+import sun.security.action.GetPropertyAction;
+import sun.security.util.FilePermCompat;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -41,8 +50,11 @@
  * the file separator character, <code>File.separatorChar</code>) indicates
  * all the files and directories contained in that directory. A pathname
  * that ends with "/-" indicates (recursively) all files
- * and subdirectories contained in that directory. A pathname consisting of
- * the special token "&lt;&lt;ALL FILES&gt;&gt;" matches <b>any</b> file.
+ * and subdirectories contained in that directory. Such a pathname is called
+ * a wildcard pathname. Otherwise, it's a simple pathname.
+ * <P>
+ * A pathname consisting of the special token {@literal "<<ALL FILES>>"}
+ * matches <b>any</b> file.
  * <P>
  * Note: A pathname consisting of a single "*" indicates all the files
  * in the current directory, while a pathname consisting of a single "-"
@@ -75,12 +87,12 @@
  * <P>
  * Be careful when granting FilePermissions. Think about the implications
  * of granting read and especially write access to various files and
- * directories. The "&lt;&lt;ALL FILES&gt;&gt;" permission with write action is
+ * directories. The {@literal "<<ALL FILES>>"} permission with write action is
  * especially dangerous. This grants permission to write to the entire
  * file system. One thing this effectively allows is replacement of the
  * system binary, including the JVM runtime environment.
- *
- * <p>Please note: Code can always read a file from the same
+ * <P>
+ * Please note: Code can always read a file from the same
  * directory it's in (or a subdirectory of that directory); it does not
  * need explicit permission to do so.
  *
@@ -145,34 +157,127 @@
     private String actions; // Left null as long as possible, then
                             // created and re-used in the getAction function.
 
-    // canonicalized dir path. In the case of
-    // directories, it is the name "/blah/*" or "/blah/-" without
-    // the last character (the "*" or "-").
+    // canonicalized dir path. used by the "old" behavior (nb == false).
+    // In the case of directories, it is the name "/blah/*" or "/blah/-"
+    // without the last character (the "*" or "-").
 
     private transient String cpath;
 
+    // Following fields used by the "new" behavior (nb == true), in which
+    // input path is not canonicalized. For compatibility (so that granting
+    // FilePermission on "x" allows reading "`pwd`/x", an alternative path
+    // can be added so that both can be used in an implies() check. Please note
+    // the alternative path only deals with absolute/relative path, and does
+    // not deal with symlink/target.
+
+    private transient Path npath;       // normalized dir path.
+    private transient Path npath2;      // alternative normalized dir path.
+    private transient boolean allFiles; // whether this is <<ALL FILES>>
+
     // static Strings used by init(int mask)
     private static final char RECURSIVE_CHAR = '-';
     private static final char WILD_CHAR = '*';
 
-/*
-    public String toString()
-    {
-        StringBuffer sb = new StringBuffer();
-        sb.append("***\n");
-        sb.append("cpath = "+cpath+"\n");
-        sb.append("mask = "+mask+"\n");
-        sb.append("actions = "+getActions()+"\n");
-        sb.append("directory = "+directory+"\n");
-        sb.append("recursive = "+recursive+"\n");
-        sb.append("***\n");
-        return sb.toString();
-    }
-*/
+//    public String toString() {
+//        StringBuffer sb = new StringBuffer();
+//        sb.append("*** FilePermission on " + getName() + " ***");
+//        for (Field f : FilePermission.class.getDeclaredFields()) {
+//            if (!Modifier.isStatic(f.getModifiers())) {
+//                try {
+//                    sb.append(f.getName() + " = " + f.get(this));
+//                } catch (Exception e) {
+//                    sb.append(f.getName() + " = " + e.toString());
+//                }
+//                sb.append('\n');
+//            }
+//        }
+//        sb.append("***\n");
+//        return sb.toString();
+//    }
 
     private static final long serialVersionUID = 7930732926638008763L;
 
     /**
+     * Always use the internal default file system, in case it was modified
+     * with java.nio.file.spi.DefaultFileSystemProvider.
+     */
+    private static final java.nio.file.FileSystem builtInFS =
+            DefaultFileSystemProvider.create()
+                    .getFileSystem(URI.create("file:///"));
+
+    /**
+     * Creates FilePermission objects with special internals.
+     * See {@link FilePermCompat#newPermPlusAltPath(Permission)} and
+     * {@link FilePermCompat#newPermUsingAltPath(Permission)}.
+     */
+
+    private static final Path here = builtInFS.getPath(
+            GetPropertyAction.privilegedGetProperty("user.dir"));
+
+    /**
+     * A private constructor like a clone, only npath2 is not touched.
+     * @param input
+     */
+    private FilePermission(FilePermission input) {
+        super(input.getName());
+        this.npath = input.npath;
+        this.actions = input.actions;
+        this.allFiles = input.allFiles;
+        this.recursive = input.recursive;
+        this.directory = input.directory;
+        this.cpath = input.cpath;
+        this.mask = input.mask;
+    }
+
+    /**
+     * Returns the alternative path as a Path object, i.e. absolute path
+     * for a relative one, or vice versa.
+     *
+     * @param in a real path w/o "-" or "*" at the end, and not <<ALL FILES>>.
+     * @return the alternative path, or null if cannot find one.
+     */
+    private static Path altPath(Path in) {
+        try {
+            if (!in.isAbsolute()) {
+                return here.resolve(in).normalize();
+            } else {
+                return here.relativize(in).normalize();
+            }
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
+
+    static {
+        SharedSecrets.setJavaIOFilePermissionAccess(
+            new JavaIOFilePermissionAccess() {
+                public FilePermission newPermPlusAltPath(FilePermission input) {
+                    if (input.npath2 == null && !input.allFiles) {
+                        Path npath2 = altPath(input.npath);
+                        if (npath2 != null) {
+                            FilePermission np = new FilePermission(input);
+                            np.npath2 = npath2;
+                            return np;
+                        }
+                    }
+                    return input;
+                }
+                public FilePermission newPermUsingAltPath(FilePermission input) {
+                    if (!input.allFiles) {
+                        Path npath2 = altPath(input.npath);
+                        if (npath2 != null) {
+                            FilePermission np = new FilePermission(input);
+                            np.npath = npath2;
+                            return np;
+                        }
+                    }
+                    return null;
+                }
+            }
+        );
+    }
+
+    /**
      * initialize a FilePermission object. Common to all constructors.
      * Also called during de-serialization.
      *
@@ -186,60 +291,106 @@
         if (mask == NONE)
                 throw new IllegalArgumentException("invalid actions mask");
 
-        if ((cpath = getName()) == null)
+        if (FilePermCompat.nb) {
+            String name = getName();
+
+            if (name == null)
+                throw new NullPointerException("name can't be null");
+
+            this.mask = mask;
+
+            if (name.equals("<<ALL FILES>>")) {
+                allFiles = true;
+                npath = builtInFS.getPath("");
+                // other fields remain default
+                return;
+            }
+
+            boolean rememberStar = false;
+            if (name.endsWith("*")) {
+                rememberStar = true;
+                recursive = false;
+                name = name.substring(0, name.length()-1) + "-";
+            }
+
+            try {
+                // new File() can "normalize" some name, for example, "/C:/X" on
+                // Windows. Some JDK codes generate such illegal names.
+                npath = builtInFS.getPath(new File(name).getPath())
+                        .normalize();
+            } catch (InvalidPathException ipe) {
+                // Still invalid. For compatibility reason, accept it
+                // but make this permission useless.
+                npath = builtInFS.getPath("-u-s-e-l-e-s-s-");
+                this.mask = NONE;
+            }
+
+            // lastName should always be non-null now
+            Path lastName = npath.getFileName();
+            if (lastName != null && lastName.toString().equals("-")) {
+                directory = true;
+                recursive = !rememberStar;
+                npath = npath.getParent();
+            }
+            if (npath == null) {
+                npath = builtInFS.getPath("");
+            }
+        } else {
+            if ((cpath = getName()) == null)
                 throw new NullPointerException("name can't be null");
 
-        this.mask = mask;
+            this.mask = mask;
 
-        if (cpath.equals("<<ALL FILES>>")) {
-            directory = true;
-            recursive = true;
-            cpath = "";
-            return;
-        }
+            if (cpath.equals("<<ALL FILES>>")) {
+                directory = true;
+                recursive = true;
+                cpath = "";
+                return;
+            }
 
-        // store only the canonical cpath if possible
-        cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
-            public String run() {
-                try {
-                    String path = cpath;
-                    if (cpath.endsWith("*")) {
-                        // call getCanonicalPath with a path with wildcard character
-                        // replaced to avoid calling it with paths that are
-                        // intended to match all entries in a directory
-                        path = path.substring(0, path.length()-1) + "-";
-                        path = new File(path).getCanonicalPath();
-                        return path.substring(0, path.length()-1) + "*";
-                    } else {
-                        return new File(path).getCanonicalPath();
+            // store only the canonical cpath if possible
+            cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
+                public String run() {
+                    try {
+                        String path = cpath;
+                        if (cpath.endsWith("*")) {
+                            // call getCanonicalPath with a path with wildcard character
+                            // replaced to avoid calling it with paths that are
+                            // intended to match all entries in a directory
+                            path = path.substring(0, path.length() - 1) + "-";
+                            path = new File(path).getCanonicalPath();
+                            return path.substring(0, path.length() - 1) + "*";
+                        } else {
+                            return new File(path).getCanonicalPath();
+                        }
+                    } catch (IOException ioe) {
+                        return cpath;
                     }
-                } catch (IOException ioe) {
-                    return cpath;
                 }
-            }
-        });
+            });
 
-        int len = cpath.length();
-        char last = ((len > 0) ? cpath.charAt(len - 1) : 0);
+            int len = cpath.length();
+            char last = ((len > 0) ? cpath.charAt(len - 1) : 0);
 
-        if (last == RECURSIVE_CHAR &&
-            cpath.charAt(len - 2) == File.separatorChar) {
-            directory = true;
-            recursive = true;
-            cpath = cpath.substring(0, --len);
-        } else if (last == WILD_CHAR &&
-            cpath.charAt(len - 2) == File.separatorChar) {
-            directory = true;
-            //recursive = false;
-            cpath = cpath.substring(0, --len);
-        } else {
-            // overkill since they are initialized to false, but
-            // commented out here to remind us...
-            //directory = false;
-            //recursive = false;
+            if (last == RECURSIVE_CHAR &&
+                    cpath.charAt(len - 2) == File.separatorChar) {
+                directory = true;
+                recursive = true;
+                cpath = cpath.substring(0, --len);
+            } else if (last == WILD_CHAR &&
+                    cpath.charAt(len - 2) == File.separatorChar) {
+                directory = true;
+                //recursive = false;
+                cpath = cpath.substring(0, --len);
+            } else {
+                // overkill since they are initialized to false, but
+                // commented out here to remind us...
+                //directory = false;
+                //recursive = false;
+            }
+
+            // XXX: at this point the path should be absolute. die if it isn't?
         }
-
-        // XXX: at this point the path should be absolute. die if it isn't?
     }
 
     /**
@@ -254,7 +405,7 @@
      * indicates all the files and directories contained in that directory.
      * A pathname that ends with "/-" indicates (recursively) all files and
      * subdirectories contained in that directory. The special pathname
-     * "&lt;&lt;ALL FILES&gt;&gt;" matches any file.
+     * {@literal "<<ALL FILES>>"} matches any file.
      *
      * <p>A pathname consisting of a single "*" indicates all the files
      * in the current directory, while a pathname consisting of a single "-"
@@ -264,6 +415,28 @@
      *
      * <p>A pathname containing an empty string represents an empty path.
      *
+     * @implNote In this implementation, the
+     * {@code jdk.io.permissionsUseCanonicalPath} system property dictates how
+     * the {@code path} argument is processed and stored.
+     * <P>
+     * If the value of the system property is set to {@code true}, {@code path}
+     * is canonicalized and stored as a String object named {@code cpath}.
+     * This means a relative path is converted to an absolute path, a Windows
+     * DOS-style 8.3 path is expanded to a long path, and a symbolic link is
+     * resolved to its target, etc.
+     * <P>
+     * If the value of the system property is set to {@code false}, {@code path}
+     * is converted to a {@link java.nio.file.Path} object named {@code npath}
+     * after {@link Path#normalize() normalization}. No canonicalization is
+     * performed which means the underlying file system is not accessed.
+     * <P>
+     * In either case, the "*" or "-" character at the end of a wildcard
+     * {@code path} is removed before canonicalization or normalization.
+     * It is stored in a separate wildcard flag field.
+     * <P>
+     * The default value of the {@code jdk.io.permissionsUseCanonicalPath}
+     * system property is {@code false} in this implementation.
+     *
      * @param path the pathname of the file/directory.
      * @param actions the action string.
      *
@@ -305,6 +478,38 @@
      *      "/tmp/*" encompasses all files in the "/tmp" directory,
      *      including the one named "foo".
      * </ul>
+     * <P>
+     * Precisely, a simple pathname implies another simple pathname
+     * if and only if they are equal. A simple pathname never implies
+     * a wildcard pathname. A wildcard pathname implies another wildcard
+     * pathname if and only if all simple pathnames implied by the latter
+     * are implied by the former. A wildcard pathname implies a simple
+     * pathname if and only if
+     * <ul>
+     *     <li>if the wildcard flag is "*", the simple pathname's path
+     *     must be right inside the wildcard pathname's path.
+     *     <li>if the wildcard flag is "-", the simple pathname's path
+     *     must be recursively inside the wildcard pathname's path.
+     * </ul>
+     * <P>
+     * {@literal "<<ALL FILES>>"} implies every other pathname. No pathname,
+     * except for {@literal "<<ALL FILES>>"} itself, implies
+     * {@literal "<<ALL FILES>>"}.
+     *
+     * @implNote
+     * If {@code jdk.io.permissionsUseCanonicalPath} is {@code true}, a
+     * simple {@code cpath} is inside a wildcard {@code cpath} if and only if
+     * after removing the base name (the last name in the pathname's name
+     * sequence) from the former the remaining part equals to the latter,
+     * a simple {@code cpath} is recursively inside a wildcard {@code cpath}
+     * if and only if the former starts with the latter.
+     * <p>
+     * If {@code jdk.io.permissionsUseCanonicalPath} is {@code false}, a
+     * simple {@code npath} is inside a wildcard {@code npath} if and only if
+     * {@code  simple_npath.relativize(wildcard_npath)} is exactly "..",
+     * a simple {@code npath} is recursively inside a wildcard {@code npath}
+     * if and only if {@code simple_npath.relativize(wildcard_npath)}
+     * is a series of one or more "..".
      *
      * @param p the permission to check against.
      *
@@ -334,45 +539,125 @@
      * @return the effective mask
      */
     boolean impliesIgnoreMask(FilePermission that) {
-        if (this.directory) {
-            if (this.recursive) {
-                // make sure that.path is longer then path so
-                // something like /foo/- does not imply /foo
-                if (that.directory) {
-                    return (that.cpath.length() >= this.cpath.length()) &&
-                            that.cpath.startsWith(this.cpath);
-                }  else {
-                    return ((that.cpath.length() > this.cpath.length()) &&
-                        that.cpath.startsWith(this.cpath));
+        if (FilePermCompat.nb) {
+            if (allFiles) {
+                return true;
+            }
+            if (that.allFiles) {
+                return false;
+            }
+            // Left at least same level of wildness as right
+            if ((this.recursive && that.recursive) != that.recursive
+                    || (this.directory && that.directory) != that.directory) {
+                return false;
+            }
+            // Same npath is good as long as both or neither are directories
+            if (this.npath.equals(that.npath)
+                    && this.directory == that.directory) {
+                return true;
+            }
+            int diff = containsPath(this.npath, that.npath);
+            // Right inside left is good if recursive
+            if (diff >= 1 && recursive) {
+                return true;
+            }
+            // Right right inside left if it is element in set
+            if (diff == 1 && directory && !that.directory) {
+                return true;
+            }
+
+            // Hack: if a npath2 field exists, apply the same checks
+            // on it as a fallback.
+            if (this.npath2 != null) {
+                if (this.npath2.equals(that.npath)
+                        && this.directory == that.directory) {
+                    return true;
+                }
+                diff = containsPath(this.npath2, that.npath);
+                if (diff >= 1 && recursive) {
+                    return true;
                 }
-            } else {
-                if (that.directory) {
-                    // if the permission passed in is a directory
-                    // specification, make sure that a non-recursive
-                    // permission (i.e., this object) can't imply a recursive
-                    // permission.
-                    if (that.recursive)
-                        return false;
-                    else
-                        return (this.cpath.equals(that.cpath));
+                if (diff == 1 && directory && !that.directory) {
+                    return true;
+                }
+            }
+
+            return false;
+        } else {
+            if (this.directory) {
+                if (this.recursive) {
+                    // make sure that.path is longer then path so
+                    // something like /foo/- does not imply /foo
+                    if (that.directory) {
+                        return (that.cpath.length() >= this.cpath.length()) &&
+                                that.cpath.startsWith(this.cpath);
+                    } else {
+                        return ((that.cpath.length() > this.cpath.length()) &&
+                                that.cpath.startsWith(this.cpath));
+                    }
                 } else {
-                    int last = that.cpath.lastIndexOf(File.separatorChar);
-                    if (last == -1)
-                        return false;
-                    else {
-                        // this.cpath.equals(that.cpath.substring(0, last+1));
-                        // Use regionMatches to avoid creating new string
-                        return (this.cpath.length() == (last + 1)) &&
-                            this.cpath.regionMatches(0, that.cpath, 0, last+1);
+                    if (that.directory) {
+                        // if the permission passed in is a directory
+                        // specification, make sure that a non-recursive
+                        // permission (i.e., this object) can't imply a recursive
+                        // permission.
+                        if (that.recursive)
+                            return false;
+                        else
+                            return (this.cpath.equals(that.cpath));
+                    } else {
+                        int last = that.cpath.lastIndexOf(File.separatorChar);
+                        if (last == -1)
+                            return false;
+                        else {
+                            // this.cpath.equals(that.cpath.substring(0, last+1));
+                            // Use regionMatches to avoid creating new string
+                            return (this.cpath.length() == (last + 1)) &&
+                                    this.cpath.regionMatches(0, that.cpath, 0, last + 1);
+                        }
                     }
                 }
+            } else if (that.directory) {
+                // if this is NOT recursive/wildcarded,
+                // do not let it imply a recursive/wildcarded permission
+                return false;
+            } else {
+                return (this.cpath.equals(that.cpath));
             }
-        } else if (that.directory) {
-            // if this is NOT recursive/wildcarded,
-            // do not let it imply a recursive/wildcarded permission
-            return false;
-        } else {
-            return (this.cpath.equals(that.cpath));
+        }
+    }
+
+    /**
+     * Returns the depth between an outer path p1 and an inner path p2. -1
+     * is returned if
+     *
+     * - p1 does not contains p2.
+     * - this is not decidable. For example, p1="../x", p2="y".
+     * - the depth is not decidable. For example, p1="/", p2="x".
+     *
+     * This method can return 2 if the depth is greater than 2.
+     *
+     * @param p1 the expected outer path, normalized
+     * @param p2 the expected inner path, normalized
+     * @return the depth in between
+     */
+    private static int containsPath(Path p1, Path p2) {
+        Path p;
+        try {
+            p = p2.relativize(p1).normalize();
+            if (p.getName(0).toString().isEmpty()) {
+                return 0;
+            } else {
+                for (Path item: p) {
+                    String s = item.toString();
+                    if (!s.equals("..")) {
+                        return -1;
+                    }
+                }
+                return p.getNameCount();
+            }
+        } catch (IllegalArgumentException iae) {
+            return -1;
         }
     }
 
@@ -380,6 +665,12 @@
      * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
      * a FilePermission, and has the same pathname and actions as this object.
      *
+     * @implNote More specifically, two pathnames are the same if and only if
+     * they have the same wildcard flag and their {@code cpath}
+     * (if {@code jdk.io.permissionsUseCanonicalPath} is {@code true}) or
+     * {@code npath} (if {@code jdk.io.permissionsUseCanonicalPath}
+     * is {@code false}) are equal. Or they are both {@literal "<<ALL FILES>>"}.
+     *
      * @param obj the object we are testing for equality with this object.
      * @return <code>true</code> if obj is a FilePermission, and has the same
      *          pathname and actions as this FilePermission object,
@@ -395,10 +686,18 @@
 
         FilePermission that = (FilePermission) obj;
 
-        return (this.mask == that.mask) &&
-            this.cpath.equals(that.cpath) &&
-            (this.directory == that.directory) &&
-            (this.recursive == that.recursive);
+        if (FilePermCompat.nb) {
+            return (this.mask == that.mask) &&
+                    (this.allFiles == that.allFiles) &&
+                    this.npath.equals(that.npath) &&
+                    (this.directory == that.directory) &&
+                    (this.recursive == that.recursive);
+        } else {
+            return (this.mask == that.mask) &&
+                    this.cpath.equals(that.cpath) &&
+                    (this.directory == that.directory) &&
+                    (this.recursive == that.recursive);
+        }
     }
 
     /**
@@ -408,7 +707,11 @@
      */
     @Override
     public int hashCode() {
-        return 0;
+        if (FilePermCompat.nb) {
+            return Objects.hash(mask, allFiles, directory, recursive, npath);
+        } else {
+            return 0;
+        }
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.io;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+
+
+/**
+ * Filter classes, array lengths, and graph metrics during deserialization.
+ * If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
+ * method is called to validate classes, the length of each array,
+ * the number of objects being read from the stream, the depth of the graph,
+ * and the total number of bytes read from the stream.
+ * <p>
+ * A filter can be set via {@link ObjectInputStream#setObjectInputFilter setObjectInputFilter}
+ * for an individual ObjectInputStream.
+ * A filter can be set via {@link Config#setSerialFilter(ObjectInputFilter) Config.setSerialFilter}
+ * to affect every {@code ObjectInputStream} that does not otherwise set a filter.
+ * <p>
+ * A filter determines whether the arguments are {@link Status#ALLOWED ALLOWED}
+ * or {@link Status#REJECTED REJECTED} and should return the appropriate status.
+ * If the filter cannot determine the status it should return
+ * {@link Status#UNDECIDED UNDECIDED}.
+ * Filters should be designed for the specific use case and expected types.
+ * A filter designed for a particular use may be passed a class that is outside
+ * of the scope of the filter. If the purpose of the filter is to black-list classes
+ * then it can reject a candidate class that matches and report UNDECIDED for others.
+ * A filter may be called with class equals {@code null}, {@code arrayLength} equal -1,
+ * the depth, number of references, and stream size and return a status
+ * that reflects only one or only some of the values.
+ * This allows a filter to specific about the choice it is reporting and
+ * to use other filters without forcing either allowed or rejected status.
+ *
+ * <p>
+ * Typically, a custom filter should check if a process-wide filter
+ * is configured and defer to it if so. For example,
+ * <pre>{@code
+ * ObjectInputFilter.Status checkInput(FilterInfo info) {
+ *     ObjectInputFilter serialFilter = ObjectInputFilter.Config.getSerialFilter();
+ *     if (serialFilter != null) {
+ *         ObjectInputFilter.Status status = serialFilter.checkInput(info);
+ *         if (status != ObjectInputFilter.Status.UNDECIDED) {
+ *             // The process-wide filter overrides this filter
+ *             return status;
+ *         }
+ *     }
+ *     if (info.serialClass() != null &&
+ *         Remote.class.isAssignableFrom(info.serialClass())) {
+ *         return Status.REJECTED;      // Do not allow Remote objects
+ *     }
+ *     return Status.UNDECIDED;
+ * }
+ *}</pre>
+ * <p>
+ * Unless otherwise noted, passing a {@code null} argument to a
+ * method in this interface and its nested classes will cause a
+ * {@link NullPointerException} to be thrown.
+ *
+ * @see ObjectInputStream#setObjectInputFilter(ObjectInputFilter)
+ * @since 9
+ */
+@FunctionalInterface
+public interface ObjectInputFilter {
+
+    /**
+     * Check the class, array length, number of object references, depth,
+     * stream size, and other available filtering information.
+     * Implementations of this method check the contents of the object graph being created
+     * during deserialization. The filter returns {@link Status#ALLOWED Status.ALLOWED},
+     * {@link Status#REJECTED Status.REJECTED}, or {@link Status#UNDECIDED Status.UNDECIDED}.
+     *
+     * @param filterInfo provides information about the current object being deserialized,
+     *             if any, and the status of the {@link ObjectInputStream}
+     * @return  {@link Status#ALLOWED Status.ALLOWED} if accepted,
+     *          {@link Status#REJECTED Status.REJECTED} if rejected,
+     *          {@link Status#UNDECIDED Status.UNDECIDED} if undecided.
+     * @since 9
+     */
+    Status checkInput(FilterInfo filterInfo);
+
+    /**
+     * FilterInfo provides access to information about the current object
+     * being deserialized and the status of the {@link ObjectInputStream}.
+     * @since 9
+     */
+    interface FilterInfo {
+        /**
+         * The class of an object being deserialized.
+         * For arrays, it is the array type.
+         * For example, the array class name of a 2 dimensional array of strings is
+         * "{@code [[Ljava.lang.String;}".
+         * To check the array's element type, iteratively use
+         * {@link Class#getComponentType() Class.getComponentType} while the result
+         * is an array and then check the class.
+         * The {@code serialClass is null} in the case where a new object is not being
+         * created and to give the filter a chance to check the depth, number of
+         * references to existing objects, and the stream size.
+         *
+         * @return class of an object being deserialized; may be null
+         */
+        Class<?> serialClass();
+
+        /**
+         * The number of array elements when deserializing an array of the class.
+         *
+         * @return the non-negative number of array elements when deserializing
+         * an array of the class, otherwise -1
+         */
+        long arrayLength();
+
+        /**
+         * The current depth.
+         * The depth starts at {@code 1} and increases for each nested object and
+         * decrements when each nested object returns.
+         *
+         * @return the current depth
+         */
+        long depth();
+
+        /**
+         * The current number of object references.
+         *
+         * @return the non-negative current number of object references
+         */
+        long references();
+
+        /**
+         * The current number of bytes consumed.
+         * @implSpec  {@code streamBytes} is implementation specific
+         * and may not be directly related to the object in the stream
+         * that caused the callback.
+         *
+         * @return the non-negative current number of bytes consumed
+         */
+        long streamBytes();
+    }
+
+    /**
+     * The status of a check on the class, array length, number of references,
+     * depth, and stream size.
+     *
+     * @since 9
+     */
+    enum Status {
+        /**
+         * The status is undecided, not allowed and not rejected.
+         */
+        UNDECIDED,
+        /**
+         * The status is allowed.
+         */
+        ALLOWED,
+        /**
+         * The status is rejected.
+         */
+        REJECTED;
+    }
+
+    /**
+     * A utility class to set and get the process-wide filter or create a filter
+     * from a pattern string. If a process-wide filter is set, it will be
+     * used for each {@link ObjectInputStream} that does not set its own filter.
+     * <p>
+     * When setting the filter, it should be stateless and idempotent,
+     * reporting the same result when passed the same arguments.
+     * <p>
+     * The filter is configured using the {@link java.security.Security}
+     * property {@code jdk.serialFilter} and can be overridden by
+     * the System property {@code jdk.serialFilter}.
+     *
+     * The syntax is the same as for the {@link #createFilter(String) createFilter} method.
+     *
+     * @since 9
+     */
+    final class Config {
+        /* No instances. */
+        private Config() {}
+
+        /**
+         * Lock object for process-wide filter.
+         */
+        private final static Object serialFilterLock = new Object();
+
+        /**
+         * Debug: Logger
+         */
+        private final static System.Logger configLog;
+
+        /**
+         * Logger for debugging.
+         */
+        static void filterLog(System.Logger.Level level, String msg, Object... args) {
+            if (configLog != null) {
+                configLog.log(level, msg, args);
+            }
+        }
+
+        /**
+         * The name for the process-wide deserialization filter.
+         * Used as a system property and a java.security.Security property.
+         */
+        private final static String SERIAL_FILTER_PROPNAME = "jdk.serialFilter";
+
+        /**
+         * The process-wide filter; may be null.
+         * Lookup the filter in java.security.Security or
+         * the system property.
+         */
+        private final static ObjectInputFilter configuredFilter;
+
+        static {
+            configuredFilter = AccessController
+                    .doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
+                        String props = System.getProperty(SERIAL_FILTER_PROPNAME);
+                        if (props == null) {
+                            props = Security.getProperty(SERIAL_FILTER_PROPNAME);
+                        }
+                        if (props != null) {
+                            System.Logger log =
+                                    System.getLogger("java.io.serialization");
+                            log.log(System.Logger.Level.INFO,
+                                    "Creating serialization filter from {0}", props);
+                            try {
+                                return createFilter(props);
+                            } catch (RuntimeException re) {
+                                log.log(System.Logger.Level.ERROR,
+                                        "Error configuring filter: {0}", re);
+                            }
+                        }
+                        return null;
+                    });
+            configLog = (configuredFilter != null) ? System.getLogger("java.io.serialization") : null;
+        }
+
+        /**
+         * Current configured filter.
+         */
+        private static ObjectInputFilter serialFilter = configuredFilter;
+
+        /**
+         * Returns the process-wide serialization filter or {@code null} if not configured.
+         *
+         * @return the process-wide serialization filter or {@code null} if not configured
+         */
+        public static ObjectInputFilter getSerialFilter() {
+            synchronized (serialFilterLock) {
+                return serialFilter;
+            }
+        }
+
+        /**
+         * Set the process-wide filter if it has not already been configured or set.
+         *
+         * @param filter the serialization filter to set as the process-wide filter; not null
+         * @throws SecurityException if there is security manager and the
+         *       {@code SerializablePermission("serialFilter")} is not granted
+         * @throws IllegalStateException if the filter has already been set {@code non-null}
+         */
+        public static void setSerialFilter(ObjectInputFilter filter) {
+            Objects.requireNonNull(filter, "filter");
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION);
+            }
+            synchronized (serialFilterLock) {
+                if (serialFilter != null) {
+                    throw new IllegalStateException("Serial filter can only be set once");
+                }
+                serialFilter = filter;
+            }
+        }
+
+        /**
+         * Returns an ObjectInputFilter from a string of patterns.
+         * <p>
+         * Patterns are separated by ";" (semicolon). Whitespace is significant and
+         * is considered part of the pattern.
+         * If a pattern includes an equals assignment, "{@code =}" it sets a limit.
+         * If a limit appears more than once the last value is used.
+         * <ul>
+         *     <li>maxdepth={@code value} - the maximum depth of a graph</li>
+         *     <li>maxrefs={@code value}  - the maximum number of internal references</li>
+         *     <li>maxbytes={@code value} - the maximum number of bytes in the input stream</li>
+         *     <li>maxarray={@code value} - the maximum array length allowed</li>
+         * </ul>
+         * <p>
+         * Other patterns match or reject class or package name
+         * as returned from {@link Class#getName() Class.getName()} and
+         * if an optional module name is present
+         * {@link java.lang.reflect.Module#getName() class.getModule().getName()}.
+         * Note that for arrays the element type is used in the pattern,
+         * not the array type.
+         * <ul>
+         * <li>If the pattern starts with "!", the class is rejected if the remaining pattern is matched;
+         *     otherwise the class is allowed if the pattern matches.
+         * <li>If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
+         *     if the module name matches the module name of the class then
+         *     the remaining pattern is matched with the class name.
+         *     If there is no "/", the module name is not compared.
+         * <li>If the pattern ends with ".**" it matches any class in the package and all subpackages.
+         * <li>If the pattern ends with ".*" it matches any class in the package.
+         * <li>If the pattern ends with "*", it matches any class with the pattern as a prefix.
+         * <li>If the pattern is equal to the class name, it matches.
+         * <li>Otherwise, the pattern is not matched.
+         * </ul>
+         * <p>
+         * The resulting filter performs the limit checks and then
+         * tries to match the class, if any. If any of the limits are exceeded,
+         * the filter returns {@link Status#REJECTED Status.REJECTED}.
+         * If the class is an array type, the class to be matched is the element type.
+         * Arrays of any number of dimensions are treated the same as the element type.
+         * For example, a pattern of "{@code !example.Foo}",
+         * rejects creation of any instance or array of {@code example.Foo}.
+         * The first pattern that matches, working from left to right, determines
+         * the {@link Status#ALLOWED Status.ALLOWED}
+         * or {@link Status#REJECTED Status.REJECTED} result.
+         * If nothing matches, the result is {@link Status#UNDECIDED Status.UNDECIDED}.
+         *
+         * @param pattern the pattern string to parse; not null
+         * @return a filter to check a class being deserialized; may be null;
+         *          {@code null} if no patterns
+         * @throws IllegalArgumentException
+         *                if a limit is missing the name, or the long value
+         *                is not a number or is negative,
+         *                or the module name is missing if the pattern contains "/"
+         *                or if the package is missing for ".*" and ".**"
+         */
+        public static ObjectInputFilter createFilter(String pattern) {
+            Objects.requireNonNull(pattern, "pattern");
+            return Global.createFilter(pattern);
+        }
+
+        /**
+         * Implementation of ObjectInputFilter that performs the checks of
+         * the process-wide serialization filter. If configured, it will be
+         * used for all ObjectInputStreams that do not set their own filters.
+         *
+         */
+        final static class Global implements ObjectInputFilter {
+            /**
+             * The pattern used to create the filter.
+             */
+            private final String pattern;
+            /**
+             * The list of class filters.
+             */
+            private final List<Function<Class<?>, Status>> filters;
+            /**
+             * Maximum allowed bytes in the stream.
+             */
+            private long maxStreamBytes;
+            /**
+             * Maximum depth of the graph allowed.
+             */
+            private long maxDepth;
+            /**
+             * Maximum number of references in a graph.
+             */
+            private long maxReferences;
+            /**
+             * Maximum length of any array.
+             */
+            private long maxArrayLength;
+
+            /**
+             * Returns an ObjectInputFilter from a string of patterns.
+             *
+             * @param pattern the pattern string to parse
+             * @return a filter to check a class being deserialized; not null
+             * @throws IllegalArgumentException if the parameter is malformed
+             *                if the pattern is missing the name, the long value
+             *                is not a number or is negative.
+             */
+            static ObjectInputFilter createFilter(String pattern) {
+                Global filter = new Global(pattern);
+                return filter.isEmpty() ? null : filter;
+            }
+
+            /**
+             * Construct a new filter from the pattern String.
+             *
+             * @param pattern a pattern string of filters
+             * @throws IllegalArgumentException if the pattern is malformed
+             */
+            private Global(String pattern) {
+                this.pattern = pattern;
+
+                maxArrayLength = Long.MAX_VALUE; // Default values are unlimited
+                maxDepth = Long.MAX_VALUE;
+                maxReferences = Long.MAX_VALUE;
+                maxStreamBytes = Long.MAX_VALUE;
+
+                String[] patterns = pattern.split(";");
+                filters = new ArrayList<>(patterns.length);
+                for (int i = 0; i < patterns.length; i++) {
+                    String p = patterns[i];
+                    int nameLen = p.length();
+                    if (nameLen == 0) {
+                        continue;
+                    }
+                    if (parseLimit(p)) {
+                        // If the pattern contained a limit setting, i.e. type=value
+                        continue;
+                    }
+                    boolean negate = p.charAt(0) == '!';
+                    int poffset = negate ? 1 : 0;
+
+                    // isolate module name, if any
+                    int slash = p.indexOf('/', poffset);
+                    if (slash == poffset) {
+                        throw new IllegalArgumentException("module name is missing in: \"" + pattern + "\"");
+                    }
+                    final String moduleName = (slash >= 0) ? p.substring(poffset, slash) : null;
+                    poffset = (slash >= 0) ? slash + 1 : poffset;
+
+                    final Function<Class<?>, Status> patternFilter;
+                    if (p.endsWith("*")) {
+                        // Wildcard cases
+                        if (p.endsWith(".*")) {
+                            // Pattern is a package name with a wildcard
+                            final String pkg = p.substring(poffset, nameLen - 1);
+                            if (pkg.length() < 2) {
+                                throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
+                            }
+                            if (negate) {
+                                // A Function that fails if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> matchesPackage(c, pkg) ? Status.REJECTED : Status.UNDECIDED;
+                            } else {
+                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> matchesPackage(c, pkg) ? Status.ALLOWED : Status.UNDECIDED;
+                            }
+                        } else if (p.endsWith(".**")) {
+                            // Pattern is a package prefix with a double wildcard
+                            final String pkgs = p.substring(poffset, nameLen - 2);
+                            if (pkgs.length() < 2) {
+                                throw new IllegalArgumentException("package missing in: \"" + pattern + "\"");
+                            }
+                            if (negate) {
+                                // A Function that fails if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> c.getName().startsWith(pkgs) ? Status.REJECTED : Status.UNDECIDED;
+                            } else {
+                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> c.getName().startsWith(pkgs) ? Status.ALLOWED : Status.UNDECIDED;
+                            }
+                        } else {
+                            // Pattern is a classname (possibly empty) with a trailing wildcard
+                            final String className = p.substring(poffset, nameLen - 1);
+                            if (negate) {
+                                // A Function that fails if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> c.getName().startsWith(className) ? Status.REJECTED : Status.UNDECIDED;
+                            } else {
+                                // A Function that succeeds if the class starts with the pattern, otherwise don't care
+                                patternFilter = c -> c.getName().startsWith(className) ? Status.ALLOWED : Status.UNDECIDED;
+                            }
+                        }
+                    } else {
+                        final String name = p.substring(poffset);
+                        if (name.isEmpty()) {
+                            throw new IllegalArgumentException("class or package missing in: \"" + pattern + "\"");
+                        }
+                        // Pattern is a class name
+                        if (negate) {
+                            // A Function that fails if the class equals the pattern, otherwise don't care
+                            patternFilter = c -> c.getName().equals(name) ? Status.REJECTED : Status.UNDECIDED;
+                        } else {
+                            // A Function that succeeds if the class equals the pattern, otherwise don't care
+                            patternFilter = c -> c.getName().equals(name) ? Status.ALLOWED : Status.UNDECIDED;
+                        }
+                    }
+                    // If there is a moduleName, combine the module name check with the package/class check
+                    if (moduleName == null) {
+                        filters.add(patternFilter);
+                    } else {
+                        filters.add(c -> moduleName.equals(c.getModule().getName()) ? patternFilter.apply(c) : Status.UNDECIDED);
+                    }
+                }
+            }
+
+            /**
+             * Returns if this filter has any checks.
+             * @return {@code true} if the filter has any checks, {@code false} otherwise
+             */
+            private boolean isEmpty() {
+                return filters.isEmpty() &&
+                        maxArrayLength == Long.MAX_VALUE &&
+                        maxDepth == Long.MAX_VALUE &&
+                        maxReferences == Long.MAX_VALUE &&
+                        maxStreamBytes == Long.MAX_VALUE;
+            }
+
+            /**
+             * Parse out a limit for one of maxarray, maxdepth, maxbytes, maxreferences.
+             *
+             * @param pattern a string with a type name, '=' and a value
+             * @return {@code true} if a limit was parsed, else {@code false}
+             * @throws IllegalArgumentException if the pattern is missing
+             *                the name, the Long value is not a number or is negative.
+             */
+            private boolean parseLimit(String pattern) {
+                int eqNdx = pattern.indexOf('=');
+                if (eqNdx < 0) {
+                    // not a limit pattern
+                    return false;
+                }
+                String valueString = pattern.substring(eqNdx + 1);
+                if (pattern.startsWith("maxdepth=")) {
+                    maxDepth = parseValue(valueString);
+                } else if (pattern.startsWith("maxarray=")) {
+                    maxArrayLength = parseValue(valueString);
+                } else if (pattern.startsWith("maxrefs=")) {
+                    maxReferences = parseValue(valueString);
+                } else if (pattern.startsWith("maxbytes=")) {
+                    maxStreamBytes = parseValue(valueString);
+                } else {
+                    throw new IllegalArgumentException("unknown limit: " + pattern.substring(0, eqNdx));
+                }
+                return true;
+            }
+
+            /**
+             * Parse the value of a limit and check that it is non-negative.
+             * @param string inputstring
+             * @return the parsed value
+             * @throws IllegalArgumentException if parsing the value fails or the value is negative
+             */
+            private static long parseValue(String string) throws IllegalArgumentException {
+                // Parse a Long from after the '=' to the end
+                long value = Long.parseLong(string);
+                if (value < 0) {
+                    throw new IllegalArgumentException("negative limit: " + string);
+                }
+                return value;
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public Status checkInput(FilterInfo filterInfo) {
+                if (filterInfo.references() < 0
+                        || filterInfo.depth() < 0
+                        || filterInfo.streamBytes() < 0
+                        || filterInfo.references() > maxReferences
+                        || filterInfo.depth() > maxDepth
+                        || filterInfo.streamBytes() > maxStreamBytes) {
+                    return Status.REJECTED;
+                }
+
+                Class<?> clazz = filterInfo.serialClass();
+                if (clazz != null) {
+                    if (clazz.isArray()) {
+                        if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > maxArrayLength) {
+                            // array length is too big
+                            return Status.REJECTED;
+                        }
+                        do {
+                            // Arrays are decided based on the component type
+                            clazz = clazz.getComponentType();
+                        } while (clazz.isArray());
+                    }
+
+                    if (clazz.isPrimitive())  {
+                        // Primitive types are undecided; let someone else decide
+                        return Status.UNDECIDED;
+                    } else {
+                        // Find any filter that allowed or rejected the class
+                        final Class<?> cl = clazz;
+                        Optional<Status> status = filters.stream()
+                                .map(f -> f.apply(cl))
+                                .filter(p -> p != Status.UNDECIDED)
+                                .findFirst();
+                        return status.orElse(Status.UNDECIDED);
+                    }
+                }
+                return Status.UNDECIDED;
+            }
+
+            /**
+             * Returns {@code true} if the class is in the package.
+             *
+             * @param c   a class
+             * @param pkg a package name (including the trailing ".")
+             * @return {@code true} if the class is in the package,
+             * otherwise {@code false}
+             */
+            private static boolean matchesPackage(Class<?> c, String pkg) {
+                String n = c.getName();
+                return n.startsWith(pkg) && n.lastIndexOf('.') == pkg.length() - 1;
+            }
+
+            /**
+             * Returns the pattern used to create this filter.
+             * @return the pattern used to create this filter
+             */
+            @Override
+            public String toString() {
+                return pattern;
+            }
+        }
+    }
+}
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Mon Oct 10 13:31:48 2016 -0700
@@ -26,6 +26,7 @@
 package java.io;
 
 import java.io.ObjectStreamClass.WeakClassKey;
+import java.lang.System.Logger;
 import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.Array;
 import java.lang.reflect.Modifier;
@@ -37,10 +38,12 @@
 import java.security.PrivilegedExceptionAction;
 import java.util.Arrays;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+
 import static java.io.ObjectStreamClass.processQueue;
-import jdk.internal.misc.JavaObjectInputStreamAccess;
+
 import jdk.internal.misc.ObjectStreamClassValidator;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.Unsafe;
@@ -172,6 +175,16 @@
  * protected) or that there are get and set methods that can be used to restore
  * the state.
  *
+ * <p>The contents of the stream can be filtered during deserialization.
+ * If a {@linkplain #setObjectInputFilter(ObjectInputFilter) filter is set}
+ * on an ObjectInputStream, the {@link ObjectInputFilter} can check that
+ * the classes, array lengths, number of references in the stream, depth, and
+ * number of bytes consumed from the input stream are allowed and
+ * if not, can terminate deserialization.
+ * A {@linkplain ObjectInputFilter.Config#setSerialFilter(ObjectInputFilter) process-wide filter}
+ * can be configured that is applied to each {@code ObjectInputStream} unless replaced
+ * using {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter}.
+ *
  * <p>Any exception that occurs while deserializing an object will be caught by
  * the ObjectInputStream and abort the reading process.
  *
@@ -240,12 +253,32 @@
             new ReferenceQueue<>();
     }
 
+    /*
+     * Separate class to defer initialization of logging until needed.
+     */
+    private static class Logging {
+        /*
+         * Logger for ObjectInputFilter results.
+         * Setup the filter logger if it is set to DEBUG or TRACE.
+         * (Assuming it will not change).
+         */
+        static final System.Logger filterLogger;
+
+        static {
+            Logger filterLog = System.getLogger("java.io.serialization");
+            filterLogger = (filterLog.isLoggable(Logger.Level.DEBUG)
+                    || filterLog.isLoggable(Logger.Level.TRACE)) ? filterLog : null;
+        }
+    }
+
     /** filter stream for handling block data conversion */
     private final BlockDataInputStream bin;
     /** validation callback list */
     private final ValidationList vlist;
     /** recursion depth */
-    private int depth;
+    private long depth;
+    /** Total number of references to any type of object, class, enum, proxy, etc. */
+    private long totalObjectRefs;
     /** whether stream is closed */
     private boolean closed;
 
@@ -269,11 +302,20 @@
     private SerialCallbackContext curContext;
 
     /**
+     * Filter of class descriptors and classes read from the stream;
+     * may be null.
+     */
+    private ObjectInputFilter serialFilter;
+
+    /**
      * Creates an ObjectInputStream that reads from the specified InputStream.
      * A serialization stream header is read from the stream and verified.
      * This constructor will block until the corresponding ObjectOutputStream
      * has written and flushed the header.
      *
+     * <p>The serialization filter is initialized to the value of
+     * {@linkplain ObjectInputFilter.Config#getSerialFilter() the process-wide filter}.
+     *
      * <p>If a security manager is installed, this constructor will check for
      * the "enableSubclassImplementation" SerializablePermission when invoked
      * directly or indirectly by the constructor of a subclass which overrides
@@ -295,6 +337,7 @@
         bin = new BlockDataInputStream(in);
         handles = new HandleTable(10);
         vlist = new ValidationList();
+        serialFilter = ObjectInputFilter.Config.getSerialFilter();
         enableOverride = false;
         readStreamHeader();
         bin.setBlockDataMode(true);
@@ -305,6 +348,9 @@
      * ObjectInputStream to not have to allocate private data just used by this
      * implementation of ObjectInputStream.
      *
+     * <p>The serialization filter is initialized to the value of
+     * {@linkplain ObjectInputFilter.Config#getSerialFilter() the process-wide filter}.
+     *
      * <p>If there is a security manager installed, this method first calls the
      * security manager's <code>checkPermission</code> method with the
      * <code>SerializablePermission("enableSubclassImplementation")</code>
@@ -325,6 +371,7 @@
         bin = null;
         handles = null;
         vlist = null;
+        serialFilter = ObjectInputFilter.Config.getSerialFilter();
         enableOverride = true;
     }
 
@@ -332,7 +379,7 @@
      * Read an object from the ObjectInputStream.  The class of the object, the
      * signature of the class, and the values of the non-transient and
      * non-static fields of the class and all of its supertypes are read.
-     * Default deserializing for a class can be overriden using the writeObject
+     * Default deserializing for a class can be overridden using the writeObject
      * and readObject methods.  Objects referenced by this object are read
      * transitively so that a complete equivalent graph of objects is
      * reconstructed by readObject.
@@ -343,6 +390,10 @@
      * priorities. The callbacks are registered by objects (in the readObject
      * special methods) as they are individually restored.
      *
+     * <p>The serialization filter, when not {@code null}, is invoked for
+     * each object (regular or class) read to reconstruct the root object.
+     * See {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter} for details.
+     *
      * <p>Exceptions are thrown for problems with the InputStream and for
      * classes that should not be deserialized.  All exceptions are fatal to
      * the InputStream and leave it in an indeterminate state; it is up to the
@@ -438,6 +489,10 @@
      * invocation of readObject or readUnshared on the ObjectInputStream,
      * even if the underlying data stream has been manipulated.
      *
+     * <p>The serialization filter, when not {@code null}, is invoked for
+     * each object (regular or class) read to reconstruct the root object.
+     * See {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter} for details.
+     *
      * <p>ObjectInputStream subclasses which override this method can only be
      * constructed in security contexts possessing the
      * "enableSubclassImplementation" SerializablePermission; any attempt to
@@ -1094,6 +1149,134 @@
     }
 
     /**
+     * Returns the serialization filter for this stream.
+     * The serialization filter is the most recent filter set in
+     * {@link #setObjectInputFilter setObjectInputFilter} or
+     * the initial process-wide filter from
+     * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter}.
+     *
+     * @return the serialization filter for the stream; may be null
+     * @since 9
+     */
+    public final ObjectInputFilter getObjectInputFilter() {
+        return serialFilter;
+    }
+
+    /**
+     * Set the serialization filter for the stream.
+     * The filter's {@link ObjectInputFilter#checkInput checkInput} method is called
+     * for each class and reference in the stream.
+     * The filter can check any or all of the class, the array length, the number
+     * of references, the depth of the graph, and the size of the input stream.
+     * <p>
+     * If the filter returns {@link ObjectInputFilter.Status#REJECTED Status.REJECTED},
+     * {@code null} or throws a {@link RuntimeException},
+     * the active {@code readObject} or {@code readUnshared}
+     * throws {@link InvalidClassException}, otherwise deserialization
+     * continues uninterrupted.
+     * <p>
+     * The serialization filter is initialized to the value of
+     * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter}
+     * when the {@code  ObjectInputStream} is constructed and can be set
+     * to a custom filter only once.
+     *
+     * @implSpec
+     * The filter, when not {@code null}, is invoked during {@link #readObject readObject}
+     * and {@link #readUnshared readUnshared} for each object
+     * (regular or class) in the stream including the following:
+     * <ul>
+     *     <li>each object reference previously deserialized from the stream
+     *     (class is {@code null}, arrayLength is -1),
+     *     <li>each regular class (class is not {@code null}, arrayLength is -1),
+     *     <li>each interface of a dynamic proxy and the dynamic proxy class itself
+     *     (class is not {@code null}, arrayLength is -1),
+     *     <li>each array is filtered using the array type and length of the array
+     *     (class is the array type, arrayLength is the requested length),
+     *     <li>each object replaced by its class' {@code readResolve} method
+     *         is filtered using the replacement object's class, if not {@code null},
+     *         and if it is an array, the arrayLength, otherwise -1,
+     *     <li>and each object replaced by {@link #resolveObject resolveObject}
+     *         is filtered using the replacement object's class, if not {@code null},
+     *         and if it is an array, the arrayLength, otherwise -1.
+     * </ul>
+     *
+     * When the {@link ObjectInputFilter#checkInput checkInput} method is invoked
+     * it is given access to the current class, the array length,
+     * the current number of references already read from the stream,
+     * the depth of nested calls to {@link #readObject readObject} or
+     * {@link #readUnshared readUnshared},
+     * and the implementation dependent number of bytes consumed from the input stream.
+     * <p>
+     * Each call to {@link #readObject readObject} or
+     * {@link #readUnshared readUnshared} increases the depth by 1
+     * before reading an object and decreases by 1 before returning
+     * normally or exceptionally.
+     * The depth starts at {@code 1} and increases for each nested object and
+     * decrements when each nested call returns.
+     * The count of references in the stream starts at {@code 1} and
+     * is increased before reading an object.
+     *
+     * @param filter the filter, may be null
+     * @throws SecurityException if there is security manager and the
+     *       {@code SerializablePermission("serialFilter")} is not granted
+     * @throws IllegalStateException if the {@linkplain #getObjectInputFilter() current filter}
+     *       is not {@code null} and is not the process-wide filter
+     * @since 9
+     */
+    public final void setObjectInputFilter(ObjectInputFilter filter) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION);
+        }
+        // Allow replacement of the process-wide filter if not already set
+        if (serialFilter != null &&
+                serialFilter != ObjectInputFilter.Config.getSerialFilter()) {
+            throw new IllegalStateException("filter can not be set more than once");
+        }
+        this.serialFilter = filter;
+    }
+
+    /**
+     * Invoke the serialization filter if non-null.
+     * If the filter rejects or an exception is thrown, throws InvalidClassException.
+     *
+     * @param clazz the class; may be null
+     * @param arrayLength the array length requested; use {@code -1} if not creating an array
+     * @throws InvalidClassException if it rejected by the filter or
+     *        a {@link RuntimeException} is thrown
+     */
+    private void filterCheck(Class<?> clazz, int arrayLength)
+            throws InvalidClassException {
+        if (serialFilter != null) {
+            RuntimeException ex = null;
+            ObjectInputFilter.Status status;
+            try {
+                status = serialFilter.checkInput(new FilterValues(clazz, arrayLength,
+                        totalObjectRefs, depth, bin.getBytesRead()));
+            } catch (RuntimeException e) {
+                // Preventive interception of an exception to log
+                status = ObjectInputFilter.Status.REJECTED;
+                ex = e;
+            }
+            if (Logging.filterLogger != null) {
+                // Debug logging of filter checks that fail; Tracing for those that succeed
+                Logging.filterLogger.log(status == null || status == ObjectInputFilter.Status.REJECTED
+                                ? Logger.Level.DEBUG
+                                : Logger.Level.TRACE,
+                        "ObjectInputFilter {0}: {1}, array length: {2}, nRefs: {3}, depth: {4}, bytes: {5}, ex: {6}",
+                        status, clazz, arrayLength, totalObjectRefs, depth, bin.getBytesRead(),
+                        Objects.toString(ex, "n/a"));
+            }
+            if (status == null ||
+                    status == ObjectInputFilter.Status.REJECTED) {
+                InvalidClassException ice = new InvalidClassException("filter status: " + status);
+                ice.initCause(ex);
+                throw ice;
+            }
+        }
+    }
+
+    /**
      * Provide access to the persistent fields read from the input stream.
      */
     public abstract static class GetField {
@@ -1280,7 +1463,7 @@
      */
     private static Boolean auditSubclass(Class<?> subcl) {
         return AccessController.doPrivileged(
-            new PrivilegedAction<>() {
+            new PrivilegedAction<Boolean>() {
                 public Boolean run() {
                     for (Class<?> cl = subcl;
                          cl != ObjectInputStream.class;
@@ -1340,6 +1523,7 @@
         }
 
         depth++;
+        totalObjectRefs++;
         try {
             switch (tc) {
                 case TC_NULL:
@@ -1416,6 +1600,15 @@
         }
         Object rep = resolveObject(obj);
         if (rep != obj) {
+            // The type of the original object has been filtered but resolveObject
+            // may have replaced it;  filter the replacement's type
+            if (rep != null) {
+                if (rep.getClass().isArray()) {
+                    filterCheck(rep.getClass(), Array.getLength(rep));
+                } else {
+                    filterCheck(rep.getClass(), -1);
+                }
+            }
             handles.setObject(passHandle, rep);
         }
         return rep;
@@ -1486,6 +1679,7 @@
             throw new InvalidObjectException(
                 "cannot read back reference to unshared object");
         }
+        filterCheck(null, -1);       // just a check for number of references, depth, no class
         return obj;
     }
 
@@ -1590,6 +1784,10 @@
                 ReflectUtil.checkProxyPackageAccess(
                         getClass().getClassLoader(),
                         cl.getInterfaces());
+                // Filter the interfaces
+                for (Class<?> clazz : cl.getInterfaces()) {
+                    filterCheck(clazz, -1);
+                }
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
@@ -1598,6 +1796,9 @@
 
         desc.initProxy(cl, resolveEx, readClassDesc(false));
 
+        // Call filterCheck on the definition
+        filterCheck(desc.forClass(), -1);
+
         handles.finish(descHandle);
         passHandle = descHandle;
         return desc;
@@ -1645,8 +1846,12 @@
 
         desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
 
+        // Call filterCheck on the definition
+        filterCheck(desc.forClass(), -1);
+
         handles.finish(descHandle);
         passHandle = descHandle;
+
         return desc;
     }
 
@@ -1687,6 +1892,8 @@
         ObjectStreamClass desc = readClassDesc(false);
         int len = bin.readInt();
 
+        filterCheck(desc.forClass(), len);
+
         Object array = null;
         Class<?> cl, ccl = null;
         if ((cl = desc.forClass()) != null) {
@@ -1835,6 +2042,14 @@
                 rep = cloneArray(rep);
             }
             if (rep != obj) {
+                // Filter the replacement object
+                if (rep != null) {
+                    if (rep.getClass().isArray()) {
+                        filterCheck(rep.getClass(), Array.getLength(rep));
+                    } else {
+                        filterCheck(rep.getClass(), -1);
+                    }
+                }
                 handles.setObject(passHandle, obj = rep);
             }
         }
@@ -2360,7 +2575,7 @@
             try {
                 while (list != null) {
                     AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<>()
+                        new PrivilegedExceptionAction<Void>()
                     {
                         public Void run() throws InvalidObjectException {
                             list.obj.validateObject();
@@ -2384,6 +2599,51 @@
     }
 
     /**
+     * Hold a snapshot of values to be passed to an ObjectInputFilter.
+     */
+    static class FilterValues implements ObjectInputFilter.FilterInfo {
+        final Class<?> clazz;
+        final long arrayLength;
+        final long totalObjectRefs;
+        final long depth;
+        final long streamBytes;
+
+        public FilterValues(Class<?> clazz, long arrayLength, long totalObjectRefs,
+                            long depth, long streamBytes) {
+            this.clazz = clazz;
+            this.arrayLength = arrayLength;
+            this.totalObjectRefs = totalObjectRefs;
+            this.depth = depth;
+            this.streamBytes = streamBytes;
+        }
+
+        @Override
+        public Class<?> serialClass() {
+            return clazz;
+        }
+
+        @Override
+        public long arrayLength() {
+            return arrayLength;
+        }
+
+        @Override
+        public long references() {
+            return totalObjectRefs;
+        }
+
+        @Override
+        public long depth() {
+            return depth;
+        }
+
+        @Override
+        public long streamBytes() {
+            return streamBytes;
+        }
+    }
+
+    /**
      * Input stream supporting single-byte peek operations.
      */
     private static class PeekInputStream extends InputStream {
@@ -2392,6 +2652,8 @@
         private final InputStream in;
         /** peeked byte */
         private int peekb = -1;
+        /** total bytes read from the stream */
+        private long totalBytesRead = 0;
 
         /**
          * Creates new PeekInputStream on top of given underlying stream.
@@ -2405,7 +2667,12 @@
          * that it does not consume the read value.
          */
         int peek() throws IOException {
-            return (peekb >= 0) ? peekb : (peekb = in.read());
+            if (peekb >= 0) {
+                return peekb;
+            }
+            peekb = in.read();
+            totalBytesRead += peekb >= 0 ? 1 : 0;
+            return peekb;
         }
 
         public int read() throws IOException {
@@ -2414,21 +2681,27 @@
                 peekb = -1;
                 return v;
             } else {
-                return in.read();
+                int nbytes = in.read();
+                totalBytesRead += nbytes >= 0 ? 1 : 0;
+                return nbytes;
             }
         }
 
         public int read(byte[] b, int off, int len) throws IOException {
+            int nbytes;
             if (len == 0) {
                 return 0;
             } else if (peekb < 0) {
-                return in.read(b, off, len);
+                nbytes = in.read(b, off, len);
+                totalBytesRead += nbytes >= 0 ? nbytes : 0;
+                return nbytes;
             } else {
                 b[off++] = (byte) peekb;
                 len--;
                 peekb = -1;
-                int n = in.read(b, off, len);
-                return (n >= 0) ? (n + 1) : 1;
+                nbytes = in.read(b, off, len);
+                totalBytesRead += nbytes >= 0 ? nbytes : 0;
+                return (nbytes >= 0) ? (nbytes + 1) : 1;
             }
         }
 
@@ -2453,7 +2726,9 @@
                 skipped++;
                 n--;
             }
-            return skipped + in.skip(n);
+            n = skipped + in.skip(n);
+            totalBytesRead += n;
+            return n;
         }
 
         public int available() throws IOException {
@@ -2463,6 +2738,10 @@
         public void close() throws IOException {
             in.close();
         }
+
+        public long getBytesRead() {
+            return totalBytesRead;
+        }
     }
 
     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
@@ -3346,6 +3625,14 @@
                     throw new UTFDataFormatException();
             }
         }
+
+        /**
+         * Returns the number of bytes read from the input stream.
+         * @return the number of bytes read from the input stream
+         */
+        long getBytesRead() {
+            return in.getBytesRead();
+        }
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamConstants.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamConstants.java	Mon Oct 10 13:31:48 2016 -0700
@@ -199,6 +199,16 @@
      */
     static final SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
                     new SerializablePermission("enableSubclassImplementation");
+
+    /**
+     * Enable setting the process-wide serial filter.
+     *
+     * @see java.io.ObjectInputFilter.Config#setSerialFilter(ObjectInputFilter)
+     * @since 9
+     */
+    static final SerializablePermission SERIAL_FILTER_PERMISSION =
+            new SerializablePermission("serialFilter");
+
    /**
     * A Stream Protocol Version. <p>
     *
--- a/jdk/src/java.base/share/classes/java/io/SerializablePermission.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/SerializablePermission.java	Mon Oct 10 13:31:48 2016 -0700
@@ -40,7 +40,7 @@
  * The target name is the name of the Serializable permission (see below).
  *
  * <P>
- * The following table lists all the possible SerializablePermission target names,
+ * The following table lists the standard {@code SerializablePermission} target names,
  * and for each provides a description of what the permission allows
  * and a discussion of the risks of granting code the permission.
  *
@@ -73,6 +73,13 @@
  * malignant data.</td>
  * </tr>
  *
+ * <tr>
+ *   <td>serialFilter</td>
+ *   <td>Setting a filter for ObjectInputStreams.</td>
+ *   <td>Code could remove a configured filter and remove protections
+ *       already established.</td>
+ * </tr>
+ *
  * </table>
  *
  * @see java.security.BasicPermission
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Mon Oct 10 13:31:48 2016 -0700
@@ -292,9 +292,6 @@
         new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
                              null, this, null);
 
-    // The initiating protection domains for all classes loaded by this loader
-    private final Set<ProtectionDomain> domains;
-
     // Invoked by the VM to record every loaded class with this loader.
     void addClass(Class<?> c) {
         classes.addElement(c);
@@ -349,13 +346,11 @@
         if (ParallelLoaders.isRegistered(this.getClass())) {
             parallelLockMap = new ConcurrentHashMap<>();
             package2certs = new ConcurrentHashMap<>();
-            domains = Collections.synchronizedSet(new HashSet<>());
             assertionLock = new Object();
         } else {
             // no finer-grained lock; lock on the classloader instance
             parallelLockMap = null;
             package2certs = new Hashtable<>();
-            domains = new HashSet<>();
             assertionLock = this;
         }
     }
@@ -640,7 +635,6 @@
                 }, new AccessControlContext(new ProtectionDomain[] {pd}));
             }
         }
-        domains.add(pd);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/Math.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1626,7 +1626,7 @@
      *
      * @since 9
      */
-    // @HotSpotIntrinsicCandidate
+    @HotSpotIntrinsicCandidate
     public static double fma(double a, double b, double c) {
         /*
          * Infinity and NaN arithmetic is not quite the same with two
@@ -1743,7 +1743,7 @@
      *
      * @since 9
      */
-    // @HotSpotIntrinsicCandidate
+    @HotSpotIntrinsicCandidate
     public static float fma(float a, float b, float c) {
         /*
          *  Since the double format has more than twice the precision
--- a/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java	Mon Oct 10 13:31:48 2016 -0700
@@ -56,6 +56,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import jdk.internal.jmod.JmodFile;
+import jdk.internal.jmod.JmodFile.Section;
 import jdk.internal.module.ConfigurableModuleFinder;
 import jdk.internal.perf.PerfCounter;
 
@@ -294,11 +296,11 @@
 
     // -- jmod files --
 
-    private Set<String> jmodPackages(ZipFile zf) {
-        return zf.stream()
-            .filter(e -> e.getName().startsWith("classes/") &&
-                    e.getName().endsWith(".class"))
-            .map(e -> toPackageName(e.getName().substring(8)))
+    private Set<String> jmodPackages(JmodFile jf) {
+        return jf.stream()
+            .filter(e -> e.section() == Section.CLASSES)
+            .map(JmodFile.Entry::name)
+            .map(this::toPackageName)
             .filter(pkg -> pkg.length() > 0) // module-info
             .collect(Collectors.toSet());
     }
@@ -311,14 +313,10 @@
      * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readJMod(Path file) throws IOException {
-        try (ZipFile zf = new ZipFile(file.toString())) {
-            ZipEntry ze = zf.getEntry("classes/" + MODULE_INFO);
-            if (ze == null) {
-                throw new IOException(MODULE_INFO + " is missing: " + file);
-            }
+        try (JmodFile jf = new JmodFile(file)) {
             ModuleDescriptor md;
-            try (InputStream in = zf.getInputStream(ze)) {
-                md = ModuleDescriptor.read(in, () -> jmodPackages(zf));
+            try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
+                md = ModuleDescriptor.read(in, () -> jmodPackages(jf));
             }
             return ModuleReferences.newJModModule(md, file);
         }
--- a/jdk/src/java.base/share/classes/java/net/MulticastSocket.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/MulticastSocket.java	Mon Oct 10 13:31:48 2016 -0700
@@ -93,23 +93,19 @@
     /**
      * Create a multicast socket.
      *
-     * <p>If there is a security manager,
-     * its {@code checkListen} method is first called
-     * with 0 as its argument to ensure the operation is allowed.
-     * This could result in a SecurityException.
+     * <p>
+     * If there is a security manager, its {@code checkListen} method is first
+     * called with 0 as its argument to ensure the operation is allowed. This
+     * could result in a SecurityException.
      * <p>
      * When the socket is created the
-     * {@link DatagramSocket#setReuseAddress(boolean)} method is
-     * called to enable the SO_REUSEADDR socket option. When
-     * {@link StandardSocketOptions#SO_REUSEPORT SO_REUSEPORT} is
-     * supported then
-     * {@link DatagramSocketImpl#setOption(SocketOption, Object)}
-     * is called to enable the socket option.
+     * {@link DatagramSocket#setReuseAddress(boolean)} method is called to
+     * enable the SO_REUSEADDR socket option.
      *
-     * @exception IOException if an I/O exception occurs
-     * while creating the MulticastSocket
-     * @exception  SecurityException  if a security manager exists and its
-     *             {@code checkListen} method doesn't allow the operation.
+     * @exception IOException if an I/O exception occurs while creating the
+     * MulticastSocket
+     * @exception SecurityException if a security manager exists and its
+     * {@code checkListen} method doesn't allow the operation.
      * @see SecurityManager#checkListen
      * @see java.net.DatagramSocket#setReuseAddress(boolean)
      * @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
@@ -174,17 +170,13 @@
         // Enable SO_REUSEADDR before binding
         setReuseAddress(true);
 
-        // Enable SO_REUSEPORT if supported before binding
-        if (supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
-            this.setOption(StandardSocketOptions.SO_REUSEPORT, true);
-        }
-
         if (bindaddr != null) {
             try {
                 bind(bindaddr);
             } finally {
-                if (!isBound())
+                if (!isBound()) {
                     close();
+                }
             }
         }
     }
--- a/jdk/src/java.base/share/classes/java/security/AccessControlContext.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/security/AccessControlContext.java	Mon Oct 10 13:31:48 2016 -0700
@@ -27,7 +27,9 @@
 
 import java.util.ArrayList;
 import java.util.List;
+
 import sun.security.util.Debug;
+import sun.security.util.FilePermCompat;
 import sun.security.util.SecurityConstants;
 
 
@@ -175,7 +177,7 @@
 
     /**
      * package private to allow calls from ProtectionDomain without performing
-     * the security check for {@linkplain SecurityConstants.CREATE_ACC_PERMISSION}
+     * the security check for {@linkplain SecurityConstants#CREATE_ACC_PERMISSION}
      * permission
      */
     AccessControlContext(AccessControlContext acc,
@@ -253,7 +255,8 @@
                 if (perms[i].getClass() == AllPermission.class) {
                     parent = null;
                 }
-                tmp[i] = perms[i];
+                // Add altPath into permission for compatibility.
+                tmp[i] = FilePermCompat.newPermPlusAltPath(perms[i]);
             }
         }
 
@@ -443,7 +446,7 @@
         }
 
         for (int i=0; i< context.length; i++) {
-            if (context[i] != null &&  !context[i].implies(perm)) {
+            if (context[i] != null && !context[i].impliesWithAltFilePerm(perm)) {
                 if (dumpDebug) {
                     debug.println("access denied " + perm);
                 }
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java	Mon Oct 10 13:31:48 2016 -0700
@@ -32,13 +32,14 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import jdk.internal.misc.JavaSecurityAccess;
 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
 import jdk.internal.misc.SharedSecrets;
+import sun.security.provider.PolicyFile;
 import sun.security.util.Debug;
+import sun.security.util.FilePermCompat;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -303,11 +304,71 @@
         }
 
         if (!staticPermissions &&
-            Policy.getPolicyNoCheck().implies(this, perm))
+            Policy.getPolicyNoCheck().implies(this, perm)) {
+            return true;
+        }
+        if (permissions != null) {
+            return permissions.implies(perm);
+        }
+
+        return false;
+    }
+
+    /**
+     * This method has the same logic flow as {@link #implies} except that
+     * when the {@link FilePermCompat#compat} flag is on it ensures
+     * FilePermission compatibility after JDK-8164705. {@code implies()}
+     * is called when compat flag is not on or user has extended
+     * {@code ProtectionDomain}.
+     *
+     * This method is called by {@link AccessControlContext#checkPermission}
+     * and not intended to be called by an application.
+     */
+    boolean impliesWithAltFilePerm(Permission perm) {
+
+        // If this is a subclass of ProtectionDomain. Call the old method.
+        if (!FilePermCompat.compat || getClass() != ProtectionDomain.class) {
+            return implies(perm);
+        }
+
+        if (hasAllPerm) {
+            // internal permission collection already has AllPermission -
+            // no need to go to policy
             return true;
-        if (permissions != null)
-            return permissions.implies(perm);
+        }
+
+        Permission p2 = null;
+        boolean p2Calculated = false;
 
+        if (!staticPermissions) {
+            Policy policy = Policy.getPolicyNoCheck();
+            if (policy instanceof PolicyFile) {
+                // The PolicyFile implementation supports compatibility
+                // inside and it also covers the static permissions.
+                return policy.implies(this, perm);
+            } else {
+                if (policy.implies(this, perm)) {
+                    return true;
+                }
+                p2 = FilePermCompat.newPermUsingAltPath(perm);
+                p2Calculated = true;
+                if (p2 != null && policy.implies(this, p2)) {
+                    return true;
+                }
+            }
+        }
+        if (permissions != null) {
+            if (permissions.implies(perm)) {
+                return true;
+            } else {
+                if (!p2Calculated) {
+                    p2 = FilePermCompat.newPermUsingAltPath(perm);
+                }
+                if (p2 != null) {
+                    return permissions.implies(p2);
+                }
+            }
+        }
         return false;
     }
 
--- a/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -968,7 +968,7 @@
      *     Decimal  : min = 0. max = 3.
      *
      */
-    private void checkAndSetFastPathStatus() {
+    private boolean checkAndSetFastPathStatus() {
 
         boolean fastPathWasOn = isFastPath;
 
@@ -998,12 +998,27 @@
         } else
             isFastPath = false;
 
+        resetFastPathData(fastPathWasOn);
+        fastPathCheckNeeded = false;
+
+        /*
+         * Returns true after successfully checking the fast path condition and
+         * setting the fast path data. The return value is used by the
+         * fastFormat() method to decide whether to call the resetFastPathData
+         * method to reinitialize fast path data or is it already initialized
+         * in this method.
+         */
+        return true;
+    }
+
+    private void resetFastPathData(boolean fastPathWasOn) {
         // Since some instance properties may have changed while still falling
         // in the fast-path case, we need to reinitialize fastPathData anyway.
         if (isFastPath) {
             // We need to instantiate fastPathData if not already done.
-            if (fastPathData == null)
+            if (fastPathData == null) {
                 fastPathData = new FastPathData();
+            }
 
             // Sets up the locale specific constants used when formatting.
             // '0' is our default representation of zero.
@@ -1011,22 +1026,27 @@
             fastPathData.groupingChar = symbols.getGroupingSeparator();
 
             // Sets up fractional constants related to currency/decimal pattern.
-            fastPathData.fractionalMaxIntBound = (isCurrencyFormat) ? 99 : 999;
-            fastPathData.fractionalScaleFactor = (isCurrencyFormat) ? 100.0d : 1000.0d;
+            fastPathData.fractionalMaxIntBound = (isCurrencyFormat)
+                    ? 99 : 999;
+            fastPathData.fractionalScaleFactor = (isCurrencyFormat)
+                    ? 100.0d : 1000.0d;
 
             // Records the need for adding prefix or suffix
-            fastPathData.positiveAffixesRequired =
-                (positivePrefix.length() != 0) || (positiveSuffix.length() != 0);
-            fastPathData.negativeAffixesRequired =
-                (negativePrefix.length() != 0) || (negativeSuffix.length() != 0);
+            fastPathData.positiveAffixesRequired
+                    = (positivePrefix.length() != 0)
+                        || (positiveSuffix.length() != 0);
+            fastPathData.negativeAffixesRequired
+                    = (negativePrefix.length() != 0)
+                        || (negativeSuffix.length() != 0);
 
             // Creates a cached char container for result, with max possible size.
             int maxNbIntegralDigits = 10;
             int maxNbGroups = 3;
-            int containerSize =
-                Math.max(positivePrefix.length(), negativePrefix.length()) +
-                maxNbIntegralDigits + maxNbGroups + 1 + maximumFractionDigits +
-                Math.max(positiveSuffix.length(), negativeSuffix.length());
+            int containerSize
+                    = Math.max(positivePrefix.length(), negativePrefix.length())
+                    + maxNbIntegralDigits + maxNbGroups + 1
+                    + maximumFractionDigits
+                    + Math.max(positiveSuffix.length(), negativeSuffix.length());
 
             fastPathData.fastPathContainer = new char[containerSize];
 
@@ -1038,17 +1058,18 @@
 
             // Sets up fixed index positions for integral and fractional digits.
             // Sets up decimal point in cached result container.
-            int longestPrefixLength =
-                Math.max(positivePrefix.length(), negativePrefix.length());
-            int decimalPointIndex =
-                maxNbIntegralDigits + maxNbGroups + longestPrefixLength;
-
-            fastPathData.integralLastIndex    = decimalPointIndex - 1;
+            int longestPrefixLength
+                    = Math.max(positivePrefix.length(),
+                            negativePrefix.length());
+            int decimalPointIndex
+                    = maxNbIntegralDigits + maxNbGroups + longestPrefixLength;
+
+            fastPathData.integralLastIndex = decimalPointIndex - 1;
             fastPathData.fractionalFirstIndex = decimalPointIndex + 1;
-            fastPathData.fastPathContainer[decimalPointIndex] =
-                isCurrencyFormat ?
-                symbols.getMonetaryDecimalSeparator() :
-                symbols.getDecimalSeparator();
+            fastPathData.fastPathContainer[decimalPointIndex]
+                    = isCurrencyFormat
+                            ? symbols.getMonetaryDecimalSeparator()
+                            : symbols.getDecimalSeparator();
 
         } else if (fastPathWasOn) {
             // Previous state was fast-path and is no more.
@@ -1059,8 +1080,6 @@
             fastPathData.charsPositivePrefix = null;
             fastPathData.charsNegativePrefix = null;
         }
-
-        fastPathCheckNeeded = false;
     }
 
     /**
@@ -1554,9 +1573,11 @@
      * @return the formatted result for {@code d} as a string.
      */
     String fastFormat(double d) {
+        boolean isDataSet = false;
         // (Re-)Evaluates fast-path status if needed.
-        if (fastPathCheckNeeded)
-            checkAndSetFastPathStatus();
+        if (fastPathCheckNeeded) {
+            isDataSet = checkAndSetFastPathStatus();
+        }
 
         if (!isFastPath )
             // DecimalFormat instance is not in a fast-path state.
@@ -1580,9 +1601,21 @@
         if (d > MAX_INT_AS_DOUBLE)
             // Filters out values that are outside expected fast-path range
             return null;
-        else
+        else {
+            if (!isDataSet) {
+                /*
+                 * If the fast path data is not set through
+                 * checkAndSetFastPathStatus() and fulfil the
+                 * fast path conditions then reset the data
+                 * directly through resetFastPathData()
+                 */
+                resetFastPathData(isFastPath);
+            }
             fastDoubleFormat(d, negative);
 
+        }
+
+
         // Returns a new string from updated fastPathContainer.
         return new String(fastPathData.fastPathContainer,
                           fastPathData.firstUsedIndex,
--- a/jdk/src/java.base/share/classes/java/time/format/ZoneName.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/ZoneName.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,11 +25,8 @@
 package java.time.format;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 
 /**
  * A helper class to map a zone name to metazone and back to the
@@ -335,6 +332,7 @@
         "America/Eirunepe", "Amazon", "America/Manaus",
         "Africa/Nairobi", "Africa_Eastern", "Africa/Nairobi",
         "Asia/Yakutsk", "Yakutsk", "Asia/Yakutsk",
+        "Asia/Yangon", "Myanmar", "Asia/Rangoon",
         "America/Goose_Bay", "Atlantic", "America/Halifax",
         "Africa/Maseru", "Africa_Southern", "Africa/Johannesburg",
         "America/Swift_Current", "America_Central", "America/Chicago",
@@ -770,6 +768,7 @@
         "America/Indianapolis", "America/Indiana/Indianapolis",
         "Europe/Belfast", "Europe/London",
         "America/Kralendijk", "America/Curacao",
+        "Asia/Rangoon", "Asia/Yangon",
     };
 
     private static final Map<String, String> zidToMzone = new HashMap<>();
--- a/jdk/src/java.base/share/classes/java/util/ArrayList.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/ArrayList.java	Mon Oct 10 13:31:48 2016 -0700
@@ -876,6 +876,7 @@
         int lastRet = -1; // index of last element returned; -1 if no such
         int expectedModCount = modCount;
 
+        // prevent creating a synthetic constructor
         Itr() {}
 
         public boolean hasNext() {
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1027,7 +1027,7 @@
      * not contain ALL valid codes that can be used to create Locales.
      * </ul>
      *
-     * @return Am array of ISO 639 two-letter language codes.
+     * @return An array of ISO 639 two-letter language codes.
      */
     public static String[] getISOLanguages() {
         if (isoLanguages == null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/util/spi/ToolProvider.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.util.spi;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.stream.StreamSupport;
+
+/**
+ * An interface for command-line tools to provide a way to
+ * be invoked without necessarily starting a new VM.
+ *
+ * <p>Tool providers are normally located using the service-provider
+ * loading facility defined by {@link ServiceLoader}.
+ * Each provider must provide a name, and a method to run
+ * an instance of the corresponding tool. When a tool is run,
+ * it will be provided with an array of string arguments, and a
+ * pair of streams: one for normal (or expected) output and the other
+ * for reporting any errors that may occur.
+ * The interpretation of the string arguments will normally be defined by
+ * each individual tool provider, but will generally correspond to the
+ * arguments that could be provided to the tool when invoking the tool
+ * from the command line.
+ *
+ * @since 9
+ */
+public interface ToolProvider {
+    /**
+     * Returns the name of this tool provider.
+     *
+     * @apiNote It is recommended that the name be the same as would be used on
+     *      the command line: for example, "javac", "jar", "jlink".
+     *
+     * @return the name of this tool provider
+     */
+    String name();
+
+    /**
+     * Runs an instance of the tool, returning zero for a successful run.
+     * Any non-zero return value indicates a tool-specific error during the
+     * execution.
+     * Two streams should be provided, for "expected" output, and for any
+     * error messages. If it is not necessary to distinguish the output,
+     * the same stream may be used for both.
+     *
+     * @apiNote The interpretation of the arguments will be specific to
+     *      each tool.
+     *
+     * @param out a stream to which "expected" output should be written
+     *
+     * @param err a stream to which any error messages should be written
+     *
+     * @param args the command-line arguments for the tool
+     *
+     * @return the result of executing the tool.
+     *      A return value of 0 means the tool did not encounter any errors;
+     *      any other value indicates that at least one error occurred during
+     *      execution.
+     *
+     * @throws NullPointerException if any of the arguments are {@code null},
+     *      or if there are any {@code null} values in the {@code args} array
+     */
+    int run(PrintWriter out, PrintWriter err, String... args);
+
+    /**
+     * Runs an instance of the tool, returning zero for a successful run.
+     * Any non-zero return value indicates a tool-specific error during the
+     * execution.
+     * Two streams should be provided, for "expected" output, and for any
+     * error messages. If it is not necessary to distinguish the output,
+     * the same stream may be used for both.
+     *
+     * @apiNote The interpretation of the arguments will be specific to
+     *      each tool.
+     *
+     * @implNote This implementation wraps the {@code out} and {@code err}
+     *      streams within {@link PrintWriter}s, and then calls
+     *      {@link run(PrintWriter, PrintWriter, String[])}.
+     *
+     * @param out a stream to which "expected" output should be written
+     *
+     * @param err a stream to which any error messages should be written
+     *
+     * @param args the command-line arguments for the tool
+     *
+     * @return the result of executing the tool.
+     *      A return value of 0 means the tool did not encounter any errors;
+     *      any other value indicates that at least one error occurred during
+     *      execution.
+     *
+     * @throws NullPointerException if any of the arguments are {@code null},
+     *      or if there are any {@code null} values in the {@code args} array
+     */
+    default int run(PrintStream out, PrintStream err, String... args) {
+        Objects.requireNonNull(out);
+        Objects.requireNonNull(err);
+        for (String arg : args) {
+            Objects.requireNonNull(args);
+        }
+
+        PrintWriter outWriter = new PrintWriter(out);
+        PrintWriter errWriter = new PrintWriter(err);
+        try {
+            try {
+                return run(outWriter, errWriter, args);
+            } finally {
+                outWriter.flush();
+            }
+        } finally {
+            errWriter.flush();
+        }
+    }
+
+    /**
+     * Returns the first instance of a {@code ToolProvider} with the given name,
+     * as loaded by {@link ServiceLoader} using the system class loader.
+     *
+     * @param name the name of the desired tool provider
+     *
+     * @return an {@code Optional<ToolProvider>} of the first instance found
+     *
+     * @throws NullPointerException if {@code name} is {@code null}
+     */
+    static Optional<ToolProvider> findFirst(String name) {
+        Objects.requireNonNull(name);
+        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+        return AccessController.doPrivileged(
+            (PrivilegedAction<Optional<ToolProvider>>) () -> {
+                ServiceLoader<ToolProvider> sl =
+                    ServiceLoader.load(ToolProvider.class, systemClassLoader);
+                return StreamSupport.stream(sl.spliterator(), false)
+                    .filter(p -> p.name().equals(name))
+                    .findFirst();
+            });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.internal.jmod;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Helper class to read JMOD file
+ */
+public class JmodFile implements AutoCloseable {
+    // jmod magic number and version number
+    public static final int JMOD_MAJOR_VERSION = 0x01;
+    public static final int JMOD_MINOR_VERSION = 0x00;
+    public static final byte[] JMOD_MAGIC_NUMBER = {
+        0x4A, 0x4D, /* JM */
+        JMOD_MAJOR_VERSION, JMOD_MINOR_VERSION, /* version 1.0 */
+    };
+
+    public static void checkMagic(Path file) throws IOException {
+        try (InputStream in = Files.newInputStream(file);
+             BufferedInputStream bis = new BufferedInputStream(in)) {
+            // validate the header
+            byte[] magic = new byte[4];
+            bis.read(magic);
+            if (magic[0] != JMOD_MAGIC_NUMBER[0] ||
+                magic[1] != JMOD_MAGIC_NUMBER[1]) {
+                throw new IOException("Invalid jmod file: " + file.toString());
+            }
+            if (magic[2] > JMOD_MAJOR_VERSION ||
+                (magic[2] == JMOD_MAJOR_VERSION && magic[3] > JMOD_MINOR_VERSION)) {
+                throw new IOException("Unsupported jmod version: " +
+                    magic[2] + "." + magic[3] + " in " + file.toString());
+            }
+        }
+    }
+
+    /**
+     * JMOD sections
+     */
+    public static enum Section {
+        NATIVE_LIBS("native"),
+        NATIVE_CMDS("bin"),
+        CLASSES("classes"),
+        CONFIG("conf");
+
+        private final String jmodDir;
+        private Section(String jmodDir) {
+            this.jmodDir = jmodDir;
+        }
+
+        /**
+         * Returns the directory name in the JMOD file corresponding to
+         * this section
+         */
+        public String jmodDir() { return jmodDir; }
+
+    }
+
+    /**
+     * JMOD file entry.
+     *
+     * Each entry corresponds to a ZipEntry whose name is:
+     *   Section::jmodDir + '/' + name
+     */
+    public static class Entry {
+        private final ZipEntry zipEntry;
+        private final Section section;
+        private final String name;
+
+        private Entry(ZipEntry e) {
+            String name = e.getName();
+            int i = name.indexOf('/');
+            if (i <= 1) {
+                throw new RuntimeException("invalid jmod entry: " + name);
+            }
+
+            this.zipEntry = e;
+            this.section = section(name);
+            this.name = name.substring(i+1);
+        }
+
+        /**
+         * Returns the section of this entry.
+         */
+        public Section section() {
+            return section;
+        }
+
+        /**
+         * Returns the name of this entry.
+         */
+        public String name() {
+            return name;
+        }
+
+        /**
+         * Returns the size of this entry.
+         */
+        public long size() {
+            return zipEntry.getSize();
+        }
+
+        public ZipEntry zipEntry() {
+            return zipEntry;
+        }
+
+        @Override
+        public String toString() {
+            return section.jmodDir() + "/" + name;
+        }
+
+        static Section section(String name) {
+            int i = name.indexOf('/');
+            String s = name.substring(0, i);
+            switch (s) {
+                case "native":
+                    return Section.NATIVE_LIBS;
+                case "bin":
+                    return Section.NATIVE_CMDS;
+                case "classes":
+                    return Section.CLASSES;
+                case "conf":
+                    return Section.CONFIG;
+                default:
+                    throw new IllegalArgumentException("invalid section: " + s);
+            }
+        }
+    }
+
+    private final Path file;
+    private final ZipFile zipfile;
+
+    /**
+     * Constructs a {@code JmodFile} from a given path.
+     */
+    public JmodFile(Path file) throws IOException {
+        checkMagic(file);
+        this.file = file;
+        this.zipfile = new ZipFile(file.toFile());
+    }
+
+    /**
+     * Opens an {@code InputStream} for reading the named entry of the given
+     * section in this jmod file.
+     *
+     * @throws IOException if the named entry is not found, or I/O error
+     *         occurs when reading it
+     */
+    public InputStream getInputStream(Section section, String name)
+        throws IOException
+    {
+
+        String entry = section.jmodDir() + "/" + name;
+        ZipEntry e = zipfile.getEntry(entry);
+        if (e == null) {
+            throw new IOException(name + " not found: " + file);
+        }
+        return zipfile.getInputStream(e);
+    }
+
+    /**
+     * Returns a stream of non-directory entries in this jmod file.
+     */
+    public Stream<Entry> stream() {
+        return zipfile.stream()
+                      .filter(e -> !e.isDirectory())
+                      .map(Entry::new);
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (zipfile != null) {
+            zipfile.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaIOFilePermissionAccess.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.internal.misc;
+
+import java.io.FilePermission;
+
+public interface JavaIOFilePermissionAccess {
+
+    /**
+     * Returns a new FilePermission plus an alternative path.
+     *
+     * @param input the input
+     * @return the new FilePermission plus the alt path (as npath2)
+     *         or the input itself if no alt path is available.
+     */
+    FilePermission newPermPlusAltPath(FilePermission input);
+
+    /**
+     * Returns a new FilePermission using an alternative path.
+     *
+     * @param input the input
+     * @return the new FilePermission using the alt path (as npath)
+     *         or null if no alt path is available
+     */
+    FilePermission newPermUsingAltPath(FilePermission input);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Mon Oct 10 13:31:48 2016 -0700
@@ -29,6 +29,7 @@
 import java.util.jar.JarFile;
 import java.io.Console;
 import java.io.FileDescriptor;
+import java.io.FilePermission;
 import java.io.ObjectInputStream;
 import java.io.RandomAccessFile;
 import java.security.ProtectionDomain;
@@ -58,6 +59,7 @@
     private static JavaNetSocketAccess javaNetSocketAccess;
     private static JavaNioAccess javaNioAccess;
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
+    private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
     private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
     private static JavaSecurityAccess javaSecurityAccess;
     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
@@ -201,6 +203,17 @@
         javaIOFileDescriptorAccess = jiofda;
     }
 
+    public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
+        if (javaIOFilePermissionAccess == null)
+            unsafe.ensureClassInitialized(FilePermission.class);
+
+        return javaIOFilePermissionAccess;
+    }
+
+    public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
+        javaIOFilePermissionAccess = jiofpa;
+    }
+
     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
         if (javaIOFileDescriptorAccess == null)
             unsafe.ensureClassInitialized(FileDescriptor.class);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Mon Oct 10 13:31:48 2016 -0700
@@ -163,6 +163,16 @@
      * be discarded.
      */
     public void write(OutputStream out) throws IOException {
+        // emit to the output stream
+        out.write(toByteArray());
+    }
+
+    /**
+     * Returns the bytes of the modified module-info.class.
+     * Once this method has been called then the Extender object should
+     * be discarded.
+     */
+    public byte[] toByteArray() throws IOException {
         ClassWriter cw
             = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
 
@@ -197,8 +207,7 @@
         // add any attributes that didn't replace previous attributes
         cv.finish();
 
-        // emit to the output stream
-        out.write(cw.toByteArray());
+        return cw.toByteArray();
     }
 
     /**
--- a/jdk/src/java.base/share/classes/module-info.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java	Mon Oct 10 13:31:48 2016 -0700
@@ -108,6 +108,7 @@
     uses java.util.spi.ResourceBundleControlProvider;
     uses java.util.spi.ResourceBundleProvider;
     uses java.util.spi.TimeZoneNameProvider;
+    uses java.util.spi.ToolProvider;
     uses javax.security.auth.spi.LoginModule;
 
 
@@ -124,6 +125,9 @@
         jdk.jlink;
     exports jdk.internal.jimage.decompressor to
         jdk.jlink;
+    exports jdk.internal.jmod to
+        jdk.compiler,
+        jdk.jlink;
     exports jdk.internal.logger to
         java.logging;
     exports jdk.internal.org.objectweb.asm to
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/file/FileURLConnection.java	Mon Oct 10 13:31:48 2016 -0700
@@ -41,10 +41,6 @@
 import java.util.*;
 import java.text.SimpleDateFormat;
 
-import sun.security.action.GetPropertyAction;
-import sun.security.action.GetIntegerAction;
-import sun.security.action.GetBooleanAction;
-
 public class FileURLConnection extends URLConnection {
 
     static String CONTENT_LENGTH = "content-length";
@@ -224,8 +220,13 @@
             if (File.separatorChar == '/') {
                 permission = new FilePermission(decodedPath, "read");
             } else {
+                // decode could return /c:/x/y/z.
+                if (decodedPath.length() > 2 && decodedPath.charAt(0) == '/'
+                        && decodedPath.charAt(2) == ':') {
+                    decodedPath = decodedPath.substring(1);
+                }
                 permission = new FilePermission(
-                        decodedPath.replace('/',File.separatorChar), "read");
+                        decodedPath.replace('/', File.separatorChar), "read");
             }
         }
         return permission;
--- a/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Mon Oct 10 13:31:48 2016 -0700
@@ -45,11 +45,7 @@
 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
 import jdk.internal.misc.SharedSecrets;
-import sun.security.util.PolicyUtil;
-import sun.security.util.PropertyExpander;
-import sun.security.util.Debug;
-import sun.security.util.ResourcesMgr;
-import sun.security.util.SecurityConstants;
+import sun.security.util.*;
 import sun.net.www.ParseUtil;
 
 /**
@@ -534,8 +530,6 @@
     /**
      * Reads a policy configuration into the Policy object using a
      * Reader object.
-     *
-     * @param policyFile the policy Reader object.
      */
     private boolean init(URL policy, PolicyInfo newInfo, boolean defPolicy) {
 
@@ -1099,7 +1093,7 @@
             synchronized (pc) {
                 Enumeration<Permission> e = pc.elements();
                 while (e.hasMoreElements()) {
-                    perms.add(e.nextElement());
+                    perms.add(FilePermCompat.newPermPlusAltPath(e.nextElement()));
                 }
             }
         }
@@ -1127,7 +1121,7 @@
      * object with additional permissions granted to the specified
      * ProtectionDomain.
      *
-     * @param perm the Permissions to populate
+     * @param perms the Permissions to populate
      * @param pd the ProtectionDomain associated with the caller.
      *
      * @return the set of Permissions according to the policy.
@@ -1157,8 +1151,8 @@
      * object with additional permissions granted to the specified
      * CodeSource.
      *
-     * @param permissions the permissions to populate
-     * @param codesource the codesource associated with the caller.
+     * @param perms the permissions to populate
+     * @param cs the codesource associated with the caller.
      * This encapsulates the original location of the code (where the code
      * came from) and the public key(s) of its signer.
      *
@@ -1386,7 +1380,7 @@
                         accPs,
                         perms);
             } else {
-                perms.add(p);
+                perms.add(FilePermCompat.newPermPlusAltPath(p));
             }
         }
     }
@@ -1458,9 +1452,9 @@
         }
         try {
             // first try to instantiate the permission
-            perms.add(getInstance(sp.getSelfType(),
+            perms.add(FilePermCompat.newPermPlusAltPath(getInstance(sp.getSelfType(),
                                   sb.toString(),
-                                  sp.getSelfActions()));
+                                  sp.getSelfActions())));
         } catch (ClassNotFoundException cnfe) {
             // ok, the permission is not in the bootclasspath.
             // before we add an UnresolvedPermission, check to see
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/FilePermCompat.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 sun.security.util;
+
+import sun.security.action.GetPropertyAction;
+
+import java.io.FilePermission;
+import java.security.Permission;
+import jdk.internal.misc.SharedSecrets;
+
+/**
+ * Take care of FilePermission compatibility after JDK-8164705.
+ */
+public class FilePermCompat {
+    /**
+     * New behavior? Keep compatibility? Both default true.
+     */
+    public static final boolean nb;
+    public static final boolean compat;
+
+    static {
+        String flag = GetPropertyAction.privilegedGetProperty(
+                "jdk.io.permissionsUseCanonicalPath", "false");
+        switch (flag) {
+            case "true":
+                nb = false;
+                compat = false;
+                break;
+            case "false":
+                nb = true;
+                compat = true;
+                break;
+            default:
+                throw new RuntimeException(
+                        "Invalid jdk.io.permissionsUseCanonicalPath: " + flag);
+        }
+    }
+
+    public static Permission newPermPlusAltPath(Permission input) {
+        if (compat && input instanceof FilePermission) {
+            return SharedSecrets.getJavaIOFilePermissionAccess()
+                    .newPermPlusAltPath((FilePermission) input);
+        }
+        return input;
+    }
+
+    public static Permission newPermUsingAltPath(Permission input) {
+        if (input instanceof FilePermission) {
+            return SharedSecrets.getJavaIOFilePermissionAccess()
+                    .newPermUsingAltPath((FilePermission) input);
+        }
+        return null;
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java	Mon Oct 10 13:31:48 2016 -0700
@@ -188,6 +188,9 @@
         String MHT[] = new String[] {"Marshall Islands Time", "MHT",
                                      "Marshall Islands Summer Time", "MHST",
                                      "Marshall Islands Time", "MHT"};
+        String MMT[] = new String[] {"Myanmar Time", "MMT",
+                                     "Myanmar Summer Time", "MMST",
+                                     "Myanmar Time", "MMT"};
         String MSK[] = new String[] {"Moscow Standard Time", "MSK",
                                      "Moscow Daylight Time", "MSD",
                                      "Moscow Time", "MT"};
@@ -683,9 +686,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda Time", "QYZT",
                                              "Qyzylorda Summer Time", "QYZST",
                                              "Qyzylorda Time", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Myanmar Time", "MMT",
-                                           "Myanmar Summer Time", "MMST",
-                                           "Myanmar Time", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Sakhalin Time", "SAKT",
@@ -718,6 +719,7 @@
                                                "Vladivostok Summer Time", "VLAST",
                                                "Vladivostok Time", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Yekaterinburg Time", "YEKT",
                                                  "Yekaterinburg Summer Time", "YEKST",
                                                  "Yekaterinburg Time", "YEKT"}},
--- a/jdk/src/java.base/share/conf/security/java.policy	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/conf/security/java.policy	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,18 @@
+//
+// This system policy file grants a set of default permissions to all domains
+// and can be configured to grant additional permissions to modules and other
+// code sources. The code source URL scheme for modules linked into a
+// run-time image is "jrt".
+//
+// For example, to grant permission to read the "foo" property to the module
+// "com.greetings", the grant entry is:
+//
+// grant codeBase "jrt:/com.greetings" {
+//     permission java.util.PropertyPermission "foo", "read";
+// };
+//
+
 // default permissions granted to all domains
-
 grant {
     // allows anyone to listen on dynamic ports
     permission java.net.SocketPermission "localhost:0", "listen";
--- a/jdk/src/java.base/share/conf/security/java.security	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/conf/security/java.security	Mon Oct 10 13:31:48 2016 -0700
@@ -894,3 +894,44 @@
     disallowReferenceUriSchemes file http https,\
     noDuplicateIds,\
     noRetrievalMethodLoops
+
+#
+# Serialization process-wide filter
+#
+# A filter, if configured, is used by java.io.ObjectInputStream during
+# deserialization to check the contents of the stream.
+# A filter is configured as a sequence of patterns, each pattern is either
+# matched against the name of a class in the stream or defines a limit.
+# Patterns are separated by ";" (semicolon).
+# Whitespace is significant and is considered part of the pattern.
+#
+# If a pattern includes a "=", it sets a limit.
+# If a limit appears more than once the last value is used.
+# Limits are checked before classes regardless of the order in the sequence of patterns.
+# If any of the limits are exceeded, the filter status is REJECTED.
+#
+#   maxdepth=value - the maximum depth of a graph
+#   maxrefs=value  - the maximum number of internal references
+#   maxbytes=value - the maximum number of bytes in the input stream
+#   maxarray=value - the maximum array length allowed
+#
+# Other patterns, from left to right, match the class or package name as
+# returned from Class.getName.
+# If the class is an array type, the class or package to be matched is the element type.
+# Arrays of any number of dimensions are treated the same as the element type.
+# For example, a pattern of "!example.Foo", rejects creation of any instance or
+# array of example.Foo.
+#
+# If the pattern starts with "!", the status is REJECTED if the remaining pattern
+#   is matched; otherwise the status is ALLOWED if the pattern matches.
+# If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
+#   if the module name matches the module name of the class then
+#   the remaining pattern is matched with the class name.
+#   If there is no "/", the module name is not compared.
+# If the pattern ends with ".**" it matches any class in the package and all subpackages.
+# If the pattern ends with ".*" it matches any class in the package.
+# If the pattern ends with "*", it matches any class with the pattern as a prefix.
+# If the pattern is equal to the class name, it matches.
+# Otherwise, the status is UNDECIDED.
+#
+#jdk.serialFilter=pattern;pattern
--- a/jdk/src/java.base/share/native/libzip/zip_util.c	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/native/libzip/zip_util.c	Mon Oct 10 13:31:48 2016 -0700
@@ -1094,7 +1094,7 @@
  * jzentry for each zip.  This optimizes a common access pattern.
  */
 
-void
+void JNICALL
 ZIP_FreeEntry(jzfile *jz, jzentry *ze)
 {
     jzentry *last;
--- a/jdk/src/java.base/share/native/libzip/zip_util.h	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/share/native/libzip/zip_util.h	Mon Oct 10 13:31:48 2016 -0700
@@ -270,7 +270,8 @@
 void ZIP_Lock(jzfile *zip);
 void ZIP_Unlock(jzfile *zip);
 jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
-void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
+void JNICALL
+ZIP_FreeEntry(jzfile *zip, jzentry *ze);
 jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
 jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
 
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -116,7 +116,7 @@
         synchronized (this) {
             if (iterator != null)
                 throw new IllegalStateException("Iterator already obtained");
-            iterator = new UnixDirectoryIterator(ds);
+            iterator = new UnixDirectoryIterator();
             return iterator;
         }
     }
@@ -130,17 +130,14 @@
      * Iterator implementation
      */
     private class UnixDirectoryIterator implements Iterator<Path> {
-        private final DirectoryStream<Path> stream;
-
         // true when at EOF
         private boolean atEof;
 
         // next entry to return
         private Path nextEntry;
 
-        UnixDirectoryIterator(DirectoryStream<Path> stream) {
+        UnixDirectoryIterator() {
             atEof = false;
-            this.stream = stream;
         }
 
         // Return true if file name is "." or ".."
--- a/jdk/src/java.instrument/share/native/libinstrument/JPLISAgent.c	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.instrument/share/native/libinstrument/JPLISAgent.c	Mon Oct 10 13:31:48 2016 -0700
@@ -790,9 +790,10 @@
     pkg_name_buf[len] = '\0';
 
     err = (*jvmti)->GetNamedModule(jvmti, loaderObject, pkg_name_buf, &moduleObject);
+    free((void*)pkg_name_buf);
+    check_phase_ret_blob(err, NULL);
     jplis_assert_msg(err == JVMTI_ERROR_NONE, "error in the JVMTI GetNamedModule");
 
-    free((void*)pkg_name_buf);
     return moduleObject;
 }
 
--- a/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Mon Oct 10 13:31:48 2016 -0700
@@ -24,9 +24,11 @@
  */
 package java.rmi.server;
 
+import java.io.ObjectInputFilter;
 import java.rmi.*;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
+import sun.rmi.transport.LiveRef;
 
 /**
  * Used for exporting a remote object with JRMP and obtaining a stub
@@ -38,11 +40,11 @@
  * generated stubs is deprecated. This includes the API in this class that
  * requires the use of static stubs, as well as the runtime support for
  * loading static stubs.  Generating stubs dynamically is preferred, using one
- * of the five non-deprecated ways of exporting objects as listed below. Do
+ * of the non-deprecated ways of exporting objects as listed below. Do
  * not run {@code rmic} to generate static stub classes. It is unnecessary, and
  * it is also deprecated.</em>
  *
- * <p>There are six ways to export remote objects:
+ * <p>There are eight ways to export remote objects:
  *
  * <ol>
  *
@@ -67,12 +69,19 @@
  * {@link #exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory)
  * exportObject(Remote, port, csf, ssf)} method.
  *
+ * <li>Calling the
+ * {@link #exportObject(Remote, int, ObjectInputFilter) exportObject(Remote, port, filter)} method.
+ *
+ * <li>Calling the
+ * {@link #exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory, ObjectInputFilter)
+ * exportObject(Remote, port, csf, ssf, filter)} method.
+ *
  * </ol>
  *
  * <p>The fourth technique, {@link #exportObject(Remote)},
  * always uses statically generated stubs and is deprecated.
  *
- * <p>The other five techniques all use the following approach: if the
+ * <p>The other techniques all use the following approach: if the
  * {@code java.rmi.server.ignoreStubClasses} property is {@code true}
  * (case insensitive) or if a static stub cannot be found, stubs are generated
  * dynamically using {@link java.lang.reflect.Proxy Proxy} objects. Otherwise,
@@ -130,6 +139,22 @@
  *
  * </ul>
  *
+ * <p>
+ * Exported remote objects receive method invocations from the stubs
+ * as described in the RMI specification. Each invocation's operation and
+ * parameters are unmarshaled using a custom {@link java.io.ObjectInputStream}.
+ * If an {@link ObjectInputFilter} is provided and is not {@code null} when the object
+ * is exported, it is used to filter the parameters as they are unmarshaled from the stream.
+ * The filter is used for all invocations and all parameters regardless of
+ * the method being invoked or the parameter values.
+ * If no filter is provided or is {@code null} for the exported object then the
+ * {@code ObjectInputStream} default filter, if any, is used. The default filter is
+ * configured with {@link ObjectInputFilter.Config#setSerialFilter(ObjectInputFilter)
+ * ObjectInputFilter.Config.setSerialFilter}.
+ * If the filter rejects any of the parameters, the {@code InvalidClassException}
+ * thrown by {@code ObjectInputStream} is reported as the cause of an
+ * {@link UnmarshalException}.
+ *
  * @implNote
  * Depending upon which constructor or static method is used for exporting an
  * object, {@link RMISocketFactory} may be used for creating sockets.
@@ -347,6 +372,58 @@
     }
 
     /**
+     * Exports the remote object to make it available to receive incoming
+     * calls, using the particular supplied port
+     * and {@linkplain ObjectInputFilter filter}.
+     *
+     * <p>The object is exported with a server socket
+     * created using the {@link RMISocketFactory} class.
+     *
+     * @param obj the remote object to be exported
+     * @param port the port to export the object on
+     * @param filter an ObjectInputFilter applied when deserializing invocation arguments;
+     *               may be {@code null}
+     * @return remote object stub
+     * @exception RemoteException if export fails
+     * @since 9
+     */
+    public static Remote exportObject(Remote obj, int port,
+                                      ObjectInputFilter filter)
+            throws RemoteException
+    {
+        return exportObject(obj, new UnicastServerRef(new LiveRef(port), filter));
+    }
+
+    /**
+     * Exports the remote object to make it available to receive incoming
+     * calls, using a transport specified by the given socket factory
+     * and {@linkplain ObjectInputFilter filter}.
+     *
+     * <p>Either socket factory may be {@code null}, in which case
+     * the corresponding client or server socket creation method of
+     * {@link RMISocketFactory} is used instead.
+     *
+     * @param obj the remote object to be exported
+     * @param port the port to export the object on
+     * @param csf the client-side socket factory for making calls to the
+     * remote object
+     * @param ssf the server-side socket factory for receiving remote calls
+     * @param filter an ObjectInputFilter applied when deserializing invocation arguments;
+     *               may be {@code null}
+     * @return remote object stub
+     * @exception RemoteException if export fails
+     * @since 9
+     */
+    public static Remote exportObject(Remote obj, int port,
+                                      RMIClientSocketFactory csf,
+                                      RMIServerSocketFactory ssf,
+                                      ObjectInputFilter filter)
+        throws RemoteException
+    {
+        return exportObject(obj, new UnicastServerRef2(port, csf, ssf, filter));
+    }
+
+    /**
      * Removes the remote object, obj, from the RMI runtime. If
      * successful, the object can no longer accept incoming RMI calls.
      * If the force parameter is true, the object is forcibly unexported
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Mon Oct 10 13:31:48 2016 -0700
@@ -27,6 +27,8 @@
 
 import java.io.IOException;
 import java.io.ObjectInput;
+import java.io.ObjectInputFilter;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.io.ObjectStreamClass;
 import java.lang.reflect.InvocationTargetException;
@@ -62,6 +64,10 @@
  * UnicastServerRef implements the remote reference layer server-side
  * behavior for remote objects exported with the "UnicastRef" reference
  * type.
+ * If an {@link ObjectInputFilter ObjectInputFilter} is supplied it is
+ * invoked during deserialization to filter the arguments,
+ * otherwise the default filter of {@link ObjectInputStream ObjectInputStream}
+ * applies.
  *
  * @author  Ann Wollrath
  * @author  Roger Riggs
@@ -103,6 +109,9 @@
      */
     private transient Skeleton skel;
 
+    // The ObjectInputFilter for checking the invocation arguments
+    private final transient ObjectInputFilter filter;
+
     /** maps method hash to Method object for each remote method */
     private transient Map<Long,Method> hashToMethod_Map = null;
 
@@ -121,16 +130,29 @@
 
     /**
      * Create a new (empty) Unicast server remote reference.
+     * The filter is null to defer to the  default ObjectInputStream filter, if any.
      */
     public UnicastServerRef() {
+        this.filter = null;
     }
 
     /**
      * Construct a Unicast server remote reference for a specified
      * liveRef.
+     * The filter is null to defer to the  default ObjectInputStream filter, if any.
      */
     public UnicastServerRef(LiveRef ref) {
         super(ref);
+        this.filter = null;
+    }
+
+    /**
+     * Construct a Unicast server remote reference for a specified
+     * liveRef and filter.
+     */
+    public UnicastServerRef(LiveRef ref, ObjectInputFilter filter) {
+        super(ref);
+        this.filter = filter;
     }
 
     /**
@@ -139,6 +161,7 @@
      */
     public UnicastServerRef(int port) {
         super(new LiveRef(port));
+        this.filter = null;
     }
 
     /**
@@ -363,9 +386,23 @@
         }
     }
 
+    /**
+     * Sets a filter for invocation arguments, if a filter has been set.
+     * Called by dispatch before the arguments are read.
+     */
     protected void unmarshalCustomCallData(ObjectInput in)
-        throws IOException, ClassNotFoundException
-    {}
+            throws IOException, ClassNotFoundException {
+        if (filter != null &&
+                in instanceof ObjectInputStream) {
+            // Set the filter on the stream
+            ObjectInputStream ois = (ObjectInputStream) in;
+
+            AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
+                ois.setObjectInputFilter(filter);
+                return null;
+            });
+        }
+    }
 
     /**
      * Handle server-side dispatch using the RMI 1.1 stub/skeleton
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef2.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef2.java	Mon Oct 10 13:31:48 2016 -0700
@@ -25,12 +25,13 @@
 
 package sun.rmi.server;
 
-import java.io.IOException;
+import java.io.ObjectInputFilter;
 import java.io.ObjectOutput;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.rmi.transport.*;
-import sun.rmi.transport.tcp.*;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RemoteRef;
+
+import sun.rmi.transport.LiveRef;
 
 /**
  * Server-side ref for a remote impl that uses a custom socket factory.
@@ -59,6 +60,16 @@
     }
 
     /**
+     * Construct a Unicast server remote reference for a specified
+     * liveRef and filter.
+     */
+    public UnicastServerRef2(LiveRef ref,
+                             ObjectInputFilter filter)
+    {
+        super(ref, filter);
+    }
+
+    /**
      * Construct a Unicast server remote reference to be exported
      * on the specified port.
      */
@@ -70,6 +81,18 @@
     }
 
     /**
+     * Construct a Unicast server remote reference to be exported
+     * on the specified port.
+     */
+    public UnicastServerRef2(int port,
+                             RMIClientSocketFactory csf,
+                             RMIServerSocketFactory ssf,
+                             ObjectInputFilter filter)
+    {
+        super(new LiveRef(port, csf, ssf), filter);
+    }
+
+    /**
      * Returns the class of the ref type to be serialized
      */
     public String getRefClass(ObjectOutput out)
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -343,6 +343,35 @@
     debugMonitorExit(invokerLock);
 }
 
+/*
+ * Check that method is in the specified clazz or one of its super classes.
+ * We have to enforce this check at the JDWP layer because the JNI layer
+ * has different requirements.
+ */
+static jvmtiError check_methodClass(JNIEnv *env, jclass clazz, jmethodID method)
+{
+    jclass containing_class = NULL;
+    jvmtiError error;
+
+    error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
+                (gdata->jvmti, method, &containing_class);
+    if (error != JVMTI_ERROR_NONE) {
+        return JVMTI_ERROR_NONE;  /* Bad jmethodID ?  This will be handled elsewhere */
+    }
+
+    if (JNI_FUNC_PTR(env,IsSameObject)(env, clazz, containing_class)) {
+        return JVMTI_ERROR_NONE;
+    }
+
+    // If not the same class then check that containing_class is a superclass of
+    // clazz (not a superinterface).
+    if (JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz, containing_class) &&
+        referenceTypeTag(containing_class) != JDWP_TYPE_TAG(INTERFACE)) {
+        return JVMTI_ERROR_NONE;
+    }
+    return JVMTI_ERROR_INVALID_METHODID;
+}
+
 jvmtiError
 invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,
                       jthread thread, jclass clazz, jmethodID method,
@@ -353,6 +382,13 @@
     InvokeRequest *request;
     jvmtiError error = JVMTI_ERROR_NONE;
 
+    if (invokeType == INVOKE_STATIC) {
+        error = check_methodClass(env, clazz, method);
+        if (error != JVMTI_ERROR_NONE) {
+            return error;
+        }
+    }
+
     debugMonitorEnter(invokerLock);
     request = threadControl_getInvokeRequest(thread);
     if (request != NULL) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java	Mon Oct 10 13:31:48 2016 -0700
@@ -55,6 +55,13 @@
         private final Archive archive;
         private final String path;
 
+        /**
+         * Constructs an entry of the given archive
+         * @param archive archive
+         * @param path
+         * @param name an entry name that does not contain the module name
+         * @param type
+         */
         public Entry(Archive archive, String path, String name, EntryType type) {
             this.archive = Objects.requireNonNull(archive);
             this.path = Objects.requireNonNull(path);
@@ -62,25 +69,29 @@
             this.type = Objects.requireNonNull(type);
         }
 
-        public Archive archive() {
+        public final Archive archive() {
             return archive;
         }
 
-        public String path() {
-            return path;
-        }
-
-        public EntryType type() {
+        public final EntryType type() {
             return type;
         }
 
-        /*
+        /**
          * Returns the name of this entry.
          */
-        public String name() {
+        public final String name() {
             return name;
         }
 
+        /**
+         * Returns the name representing a ResourcePoolEntry in the form of:
+         *    /$MODULE/$ENTRY_NAME
+         */
+        public final String getResourcePoolEntryName() {
+            return "/" + archive.moduleName() + "/" + name;
+        }
+
         @Override
         public String toString() {
             return "type " + type.name() + " path " + path;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java	Mon Oct 10 13:31:48 2016 -0700
@@ -50,7 +50,7 @@
 
         FileEntry(Path path, String name) {
             super(DirArchive.this, getPathName(path), name,
-                    Archive.Entry.EntryType.CLASS_OR_RESOURCE);
+                  Archive.Entry.EntryType.CLASS_OR_RESOURCE);
             this.path = path;
             try {
                 size = Files.size(path);
@@ -124,13 +124,7 @@
             return null;
         }
         String name = getPathName(p).substring(chop);
-        if (name.startsWith("_")) {
-            return null;
-        }
         log.accept(moduleName + "/" + name);
-        if (name.equals(MODULE_INFO)) {
-            name = moduleName + "/" + MODULE_INFO;
-        }
         return new FileEntry(p, name);
     }
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java	Mon Oct 10 13:31:48 2016 -0700
@@ -40,6 +40,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+
 import jdk.tools.jlink.internal.Archive.Entry;
 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
 import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
@@ -122,10 +123,6 @@
         });
     }
 
-    public static boolean isClassPackage(String path) {
-        return path.endsWith(".class") && !path.endsWith("module-info.class");
-    }
-
     public static void recreateJimage(Path jimageFile,
             Set<Archive> archives,
             ImagePluginStack pluginSupport)
@@ -265,26 +262,13 @@
                 return writer.getString(id);
             }
         });
+
         for (Archive archive : archives) {
             String mn = archive.moduleName();
-            for (Entry entry : entriesForModule.get(mn)) {
-                String path;
-                if (entry.type() == EntryType.CLASS_OR_RESOURCE) {
-                    // Removal of "classes/" radical.
-                    path = entry.name();
-                    if (path.endsWith("module-info.class")) {
-                        path = "/" + path;
-                    } else {
-                        path = "/" + mn + "/" + path;
-                    }
-                } else {
-                    // Entry.path() contains the kind of file native, conf, bin, ...
-                    // Keep it to avoid naming conflict (eg: native/jvm.cfg and config/jvm.cfg
-                    path = "/" + mn + "/" + entry.path();
-                }
-
-                resources.add(new ArchiveEntryResourcePoolEntry(mn, path, entry));
-            }
+            entriesForModule.get(mn).stream()
+                .map(e -> new ArchiveEntryResourcePoolEntry(mn,
+                                    e.getResourcePoolEntryName(), e))
+                .forEach(resources::add);
         }
         return resources;
     }
@@ -320,6 +304,20 @@
         return result.toArray(array);
     }
 
+    /**
+     * Returns the path of the resource.
+     */
+    public static String resourceName(String path) {
+        Objects.requireNonNull(path);
+        String s = path.substring(1);
+        int index = s.indexOf("/");
+        return s.substring(index + 1);
+    }
+
+    public static String toPackage(String name) {
+        return toPackage(name, false);
+    }
+
     private static String toPackage(String name, boolean log) {
         int index = name.lastIndexOf('/');
         if (index > 0) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JarArchive.java	Mon Oct 10 13:31:48 2016 -0700
@@ -43,7 +43,7 @@
     /**
      * An entry located in a jar file.
      */
-    private class JarEntry extends Entry {
+    public class JarEntry extends Entry {
 
         private final long size;
         private final ZipEntry entry;
@@ -70,12 +70,10 @@
         }
     }
 
-    private static final String MODULE_INFO = "module-info.class";
-
     private final Path file;
     private final String moduleName;
     // currently processed ZipFile
-    private ZipFile zipFile;
+    protected ZipFile zipFile;
 
     protected JarArchive(String mn, Path file) {
         Objects.requireNonNull(mn);
@@ -110,21 +108,7 @@
 
     abstract String getFileName(String entryName);
 
-    private Entry toEntry(ZipEntry ze) {
-        String name = ze.getName();
-        String fn = getFileName(name);
-
-        if (ze.isDirectory() || fn.startsWith("_")) {
-            return null;
-        }
-
-        EntryType rt = toEntryType(name);
-
-        if (fn.equals(MODULE_INFO)) {
-            fn = moduleName + "/" + MODULE_INFO;
-        }
-        return new JarEntry(ze.getName(), fn, rt, zipFile, ze);
-    }
+    abstract Entry toEntry(ZipEntry ze);
 
     @Override
     public void close() throws IOException {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java	Mon Oct 10 13:31:48 2016 -0700
@@ -25,34 +25,106 @@
 
 package jdk.tools.jlink.internal;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.nio.file.Path;
 import java.util.Objects;
+import java.util.stream.Stream;
+
+import jdk.internal.jmod.JmodFile;
 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
 
 /**
  * An Archive backed by a jmod file.
  */
-public class JmodArchive extends JarArchive {
-
+public class JmodArchive implements Archive {
     private static final String JMOD_EXT    = ".jmod";
-    private static final String MODULE_NAME = "module";
-    private static final String MODULE_INFO = "module-info.class";
-    private static final String CLASSES     = "classes";
-    private static final String NATIVE_LIBS = "native";
-    private static final String NATIVE_CMDS = "bin";
-    private static final String CONFIG      = "conf";
+
+    /**
+     * An entry located in a jmod file.
+     */
+    public class JmodEntry extends Entry {
+        private final JmodFile.Entry entry;
+
+        JmodEntry(String path, String name, EntryType type,
+                  JmodFile.Entry entry) {
+            super(JmodArchive.this, path, name, type);
+            this.entry = Objects.requireNonNull(entry);
+        }
+
+        /**
+         * Returns the number of uncompressed bytes for this entry.
+         */
+        @Override
+        public long size() {
+            return entry.size();
+        }
+
+        @Override
+        public InputStream stream() throws IOException {
+            return jmodFile.getInputStream(entry.section(), entry.name());
+        }
+    }
+
+    private final Path file;
+    private final String moduleName;
+    private JmodFile jmodFile;
 
     public JmodArchive(String mn, Path jmod) {
-        super(mn, jmod);
-        String filename = Objects.requireNonNull(jmod.getFileName()).toString();
+        Objects.requireNonNull(mn);
+        Objects.requireNonNull(jmod.getFileName());
+        String filename = jmod.toString();
         if (!filename.endsWith(JMOD_EXT)) {
             throw new UnsupportedOperationException("Unsupported format: " + filename);
         }
+        this.moduleName = mn;
+        this.file = jmod;
+    }
+
+    @Override
+    public String moduleName() {
+        return moduleName;
+    }
+
+    @Override
+    public Path getPath() {
+        return file;
+    }
+
+    @Override
+    public Stream<Entry> entries() {
+        ensureOpen();
+        return jmodFile.stream()
+                       .map(this::toEntry);
     }
 
     @Override
-    EntryType toEntryType(String entryName) {
-        String section = getSection(entryName.replace('\\', '/'));
+    public void open() throws IOException {
+        if (jmodFile != null) {
+            jmodFile.close();
+        }
+        this.jmodFile = new JmodFile(file);
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (jmodFile != null) {
+            jmodFile.close();
+        }
+    }
+
+    private void ensureOpen() {
+        if (jmodFile == null) {
+            try {
+                open();
+            } catch(IOException ioe){
+                throw new UncheckedIOException(ioe);
+            }
+        }
+    }
+
+    private EntryType toEntryType(JmodFile.Section section) {
         switch (section) {
             case CLASSES:
                 return EntryType.CLASS_OR_RESOURCE;
@@ -62,26 +134,23 @@
                 return EntryType.NATIVE_CMD;
             case CONFIG:
                 return EntryType.CONFIG;
-            case MODULE_NAME:
-                return EntryType.MODULE_NAME;
             default:
                 throw new InternalError("unexpected entry: " + section);
         }
     }
 
-    private static String getSection(String entryName) {
-        int i = entryName.indexOf('/');
-        // Unnamed section.
-        String section = "";
-        if (i > 0) {
-            section = entryName.substring(0, entryName.indexOf('/'));
+    private Entry toEntry(JmodFile.Entry entry) {
+        EntryType type = toEntryType(entry.section());
+        String name = entry.name();
+        String path = entry.section().jmodDir() + "/" + name;
+
+        // Entry.path() contains the kind of file native, conf, bin, ...
+        // Keep it to avoid naming conflict (eg: native/jvm.cfg and config/jvm.cfg
+        String resourceName = name;
+        if (type != EntryType.CLASS_OR_RESOURCE) {
+            resourceName = path;
         }
-        return section;
-    }
 
-    @Override
-    String getFileName(String entryName) {
-        entryName = entryName.replace('\\', '/');
-        return entryName.substring(entryName.indexOf('/') + 1);
+        return new JmodEntry(path, resourceName, type, entry);
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java	Mon Oct 10 13:31:48 2016 -0700
@@ -27,6 +27,8 @@
 
 import java.nio.file.Path;
 import java.util.Objects;
+import java.util.zip.ZipEntry;
+
 import jdk.tools.jlink.internal.Archive.Entry.EntryType;
 
 /**
@@ -35,6 +37,7 @@
 public class ModularJarArchive extends JarArchive {
 
     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);
@@ -50,6 +53,17 @@
     }
 
     @Override
+    Entry toEntry(ZipEntry ze) {
+        if (ze.isDirectory()) {
+            return null;
+        }
+
+        String name = ze.getName();
+        EntryType type = toEntryType(name);
+        return new JarEntry(ze.getName(), getFileName(name), type, zipFile, ze);
+    }
+
+    @Override
     String getFileName(String entryName) {
         return entryName;
     }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Mon Oct 10 13:31:48 2016 -0700
@@ -27,15 +27,12 @@
 import java.lang.module.ModuleDescriptor;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import java.util.function.Function;
 import java.util.stream.Stream;
 import jdk.internal.jimage.decompressor.CompressedResourceHeader;
 import jdk.tools.jlink.plugin.ResourcePool;
@@ -44,7 +41,6 @@
 import jdk.tools.jlink.plugin.ResourcePoolModule;
 import jdk.tools.jlink.plugin.ResourcePoolModuleView;
 import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
 
 /**
  * A manager for pool of resources.
@@ -100,17 +96,17 @@
         @Override
         public Set<String> packages() {
             Set<String> pkgs = new HashSet<>();
-            moduleContent.values().stream().filter(m -> m.type().
-                    equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
-                // Module metadata only contains packages with .class files
-                if (ImageFileCreator.isClassPackage(res.path())) {
-                    String[] split = ImageFileCreator.splitPath(res.path());
-                    String pkg = split[1];
-                    if (pkg != null && !pkg.isEmpty()) {
-                        pkgs.add(pkg);
+            moduleContent.values().stream()
+                .filter(m -> m.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+                .forEach(res -> {
+                    String name = ImageFileCreator.resourceName(res.path());
+                    if (name.endsWith(".class") && !name.endsWith("module-info.class")) {
+                        String pkg = ImageFileCreator.toPackage(name);
+                        if (!pkg.isEmpty()) {
+                            pkgs.add(pkg);
+                        }
                     }
-                }
-            });
+                });
             return pkgs;
         }
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java	Mon Oct 10 13:31:48 2016 -0700
@@ -307,9 +307,10 @@
 
     private boolean filterOutUnsupportedTags(byte[] b) {
         List<Locale> locales;
+        List<String> originalTags = Arrays.asList(new String(b).split(" "));
 
         try {
-            locales = Arrays.asList(new String(b).split(" ")).stream()
+            locales = originalTags.stream()
                 .filter(tag -> !tag.isEmpty())
                 .map(IncludeLocalesPlugin::tagToLocale)
                 .collect(Collectors.toList());
@@ -319,6 +320,9 @@
         }
 
         byte[] filteredBytes = filterLocales(locales).stream()
+            // Make sure the filtered language tags do exist in the
+            // original supported tags for compatibility codes, e.g., "iw"
+            .filter(originalTags::contains)
             .collect(Collectors.joining(" "))
             .getBytes();
 
@@ -331,6 +335,11 @@
         return true;
     }
 
+    /*
+     * Filter list of locales according to the secified priorityList. Note
+     * that returned list of language tags may include extra ones, such as
+     * compatibility ones (e.g., "iw" -> "iw", "he").
+     */
     private List<String> filterLocales(List<Locale> locales) {
         List<String> ret =
             Locale.filter(priorityList, locales, Locale.FilteringMode.EXTENDED_FILTERING).stream()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodOutputStream.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.tools.jmod;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import static jdk.internal.jmod.JmodFile.*;
+
+/**
+ * Output stream to write to JMOD file
+ */
+class JmodOutputStream extends OutputStream implements AutoCloseable {
+    /**
+     * This method creates (or overrides, if exists) the JMOD file,
+     * returning the the output stream to write to the JMOD file.
+     */
+    static JmodOutputStream newOutputStream(Path file) throws IOException {
+        OutputStream out = Files.newOutputStream(file);
+        BufferedOutputStream bos = new BufferedOutputStream(out);
+        return new JmodOutputStream(bos);
+    }
+
+    private final ZipOutputStream zos;
+    private JmodOutputStream(OutputStream out) {
+        this.zos = new ZipOutputStream(out);
+        try {
+            out.write(JMOD_MAGIC_NUMBER);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    /**
+     * Writes the input stream to the named entry of the given section.
+     */
+    public void writeEntry(InputStream in, Section section, String name)
+        throws IOException
+    {
+        ZipEntry ze = newEntry(section, name);
+        zos.putNextEntry(ze);
+        in.transferTo(zos);
+        zos.closeEntry();
+    }
+
+    /**
+     * Writes the given bytes to the named entry of the given section.
+     */
+    public void writeEntry(byte[] bytes, Section section, String path)
+        throws IOException
+    {
+        ZipEntry ze = newEntry(section, path);
+        zos.putNextEntry(ze);
+        zos.write(bytes);
+        zos.closeEntry();
+    }
+
+    /**
+     * Writes the given entry to the given input stream.
+     */
+    public void writeEntry(InputStream in, Entry e) throws IOException {
+        zos.putNextEntry(e.zipEntry());
+        zos.write(in.readAllBytes());
+        zos.closeEntry();
+    }
+
+    private ZipEntry newEntry(Section section, String path) {
+        String prefix = section.jmodDir();
+        String name = Paths.get(prefix, path).toString()
+                           .replace(File.separatorChar, '/');
+        return new ZipEntry(name);
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        zos.write(b);
+    }
+
+    @Override
+    public void close() throws IOException {
+        zos.close();
+    }
+}
+
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Mon Oct 10 13:31:48 2016 -0700
@@ -25,8 +25,6 @@
 
 package jdk.tools.jmod;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -60,7 +58,6 @@
 import java.text.MessageFormat;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -80,15 +77,16 @@
 import java.util.function.Supplier;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
 import java.util.stream.Collectors;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
 
+import jdk.internal.jmod.JmodFile;
+import jdk.internal.jmod.JmodFile.Section;
 import jdk.internal.joptsimple.BuiltinHelpFormatter;
 import jdk.internal.joptsimple.NonOptionArgumentSpec;
 import jdk.internal.joptsimple.OptionDescriptor;
@@ -250,23 +248,14 @@
     }
 
     private boolean describe() throws IOException {
-        ZipFile zip = null;
-        try {
-            try {
-                zip = new ZipFile(options.jmodFile.toFile());
-            } catch (IOException x) {
-                throw new IOException("error opening jmod file", x);
+        try (JmodFile jf = new JmodFile(options.jmodFile)) {
+            try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
+                ModuleDescriptor md = ModuleDescriptor.read(in);
+                printModuleDescriptor(md);
+                return true;
+            } catch (IOException e) {
+                throw new CommandException("err.module.descriptor.not.found");
             }
-
-            try (InputStream in = Files.newInputStream(options.jmodFile)) {
-                boolean found = printModuleDescriptor(in);
-                if (!found)
-                    throw new CommandException("err.module.descriptor.not.found");
-                return found;
-            }
-        } finally {
-            if (zip != null)
-                zip.close();
         }
     }
 
@@ -278,65 +267,52 @@
 
     private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
 
-    private boolean printModuleDescriptor(InputStream in)
+    private void printModuleDescriptor(ModuleDescriptor md)
         throws IOException
     {
-        final String mi = Section.CLASSES.jmodDir() + "/" + MODULE_INFO;
-        try (BufferedInputStream bis = new BufferedInputStream(in);
-             ZipInputStream zis = new ZipInputStream(bis)) {
-
-            ZipEntry e;
-            while ((e = zis.getNextEntry()) != null) {
-                if (e.getName().equals(mi)) {
-                    ModuleDescriptor md = ModuleDescriptor.read(zis);
-                    StringBuilder sb = new StringBuilder();
-                    sb.append("\n").append(md.toNameAndVersion());
+        StringBuilder sb = new StringBuilder();
+        sb.append("\n").append(md.toNameAndVersion());
 
-                    md.requires().stream()
-                        .sorted(Comparator.comparing(Requires::name))
-                        .forEach(r -> {
-                            sb.append("\n  requires ");
-                            if (!r.modifiers().isEmpty())
-                                sb.append(toString(r.modifiers())).append(" ");
-                            sb.append(r.name());
-                        });
+        md.requires().stream()
+            .sorted(Comparator.comparing(Requires::name))
+            .forEach(r -> {
+                sb.append("\n  requires ");
+                if (!r.modifiers().isEmpty())
+                    sb.append(toString(r.modifiers())).append(" ");
+                sb.append(r.name());
+            });
 
-                    md.uses().stream().sorted()
-                        .forEach(s -> sb.append("\n  uses ").append(s));
+        md.uses().stream().sorted()
+            .forEach(s -> sb.append("\n  uses ").append(s));
 
-                    md.exports().stream()
-                        .sorted(Comparator.comparing(Exports::source))
-                        .forEach(p -> sb.append("\n  exports ").append(p));
+        md.exports().stream()
+            .sorted(Comparator.comparing(Exports::source))
+            .forEach(p -> sb.append("\n  exports ").append(p));
+
+        md.conceals().stream().sorted()
+            .forEach(p -> sb.append("\n  conceals ").append(p));
 
-                    md.conceals().stream().sorted()
-                        .forEach(p -> sb.append("\n  conceals ").append(p));
+        md.provides().values().stream()
+            .sorted(Comparator.comparing(Provides::service))
+            .forEach(p -> sb.append("\n  provides ").append(p.service())
+                .append(" with ")
+                .append(toString(p.providers())));
 
-                    md.provides().values().stream()
-                        .sorted(Comparator.comparing(Provides::service))
-                        .forEach(p -> sb.append("\n  provides ").append(p.service())
-                                        .append(" with ")
-                                        .append(toString(p.providers())));
+        md.mainClass().ifPresent(v -> sb.append("\n  main-class " + v));
 
-                    md.mainClass().ifPresent(v -> sb.append("\n  main-class " + v));
-
-                    md.osName().ifPresent(v -> sb.append("\n  operating-system-name " + v));
-
-                    md.osArch().ifPresent(v -> sb.append("\n  operating-system-architecture " + v));
+        md.osName().ifPresent(v -> sb.append("\n  operating-system-name " + v));
 
-                    md.osVersion().ifPresent(v -> sb.append("\n  operating-system-version " + v));
+        md.osArch().ifPresent(v -> sb.append("\n  operating-system-architecture " + v));
+
+        md.osVersion().ifPresent(v -> sb.append("\n  operating-system-version " + v));
 
-                    JLMA.hashes(md).ifPresent(
-                            hashes -> hashes.names().stream().sorted().forEach(
-                                    mod -> sb.append("\n  hashes ").append(mod).append(" ")
-                                             .append(hashes.algorithm()).append(" ")
-                                             .append(hashes.hashFor(mod))));
+        JLMA.hashes(md).ifPresent(
+            hashes -> hashes.names().stream().sorted().forEach(
+                mod -> sb.append("\n  hashes ").append(mod).append(" ")
+                    .append(hashes.algorithm()).append(" ")
+                    .append(hashes.hashFor(mod))));
 
-                    out.println(sb.toString());
-                    return true;
-                }
-            }
-        }
-        return false;
+        out.println(sb.toString());
     }
 
     private boolean create() throws IOException {
@@ -347,9 +323,8 @@
         Path target = options.jmodFile;
         Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
         try {
-            try (OutputStream out = Files.newOutputStream(tempTarget);
-                 BufferedOutputStream bos = new BufferedOutputStream(out)) {
-                jmod.write(bos);
+            try (JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget)) {
+                jmod.write(jos);
             }
             Files.move(tempTarget, target);
         } catch (Exception e) {
@@ -383,19 +358,16 @@
         /**
          * Writes the jmod to the given output stream.
          */
-        void write(OutputStream out) throws IOException {
-            try (ZipOutputStream zos = new ZipOutputStream(out)) {
-
-                // module-info.class
-                writeModuleInfo(zos, findPackages(classpath));
+        void write(JmodOutputStream out) throws IOException {
+            // module-info.class
+            writeModuleInfo(out, findPackages(classpath));
 
-                // classes
-                processClasses(zos, classpath);
+            // classes
+            processClasses(out, classpath);
 
-                processSection(zos, Section.NATIVE_CMDS, cmds);
-                processSection(zos, Section.NATIVE_LIBS, libs);
-                processSection(zos, Section.CONFIG, configs);
-            }
+            processSection(out, Section.NATIVE_CMDS, cmds);
+            processSection(out, Section.NATIVE_LIBS, libs);
+            processSection(out, Section.CONFIG, configs);
         }
 
         /**
@@ -441,7 +413,7 @@
          * then the corresponding class file attributes are added to the
          * module-info here.
          */
-        void writeModuleInfo(ZipOutputStream zos, Set<String> packages)
+        void writeModuleInfo(JmodOutputStream out, Set<String> packages)
             throws IOException
         {
             Supplier<InputStream> miSupplier = newModuleInfoSupplier();
@@ -492,11 +464,7 @@
                 }
 
                 // write the (possibly extended or modified) module-info.class
-                String e = Section.CLASSES.jmodDir() + "/" + MODULE_INFO;
-                ZipEntry ze = new ZipEntry(e);
-                zos.putNextEntry(ze);
-                extender.write(zos);
-                zos.closeEntry();
+                out.writeEntry(extender.toByteArray(), Section.CLASSES, MODULE_INFO);
             }
         }
 
@@ -627,7 +595,7 @@
                 return "";
         }
 
-        void processClasses(ZipOutputStream zos, List<Path> classpaths)
+        void processClasses(JmodOutputStream zos, List<Path> classpaths)
             throws IOException
         {
             if (classpaths == null)
@@ -645,7 +613,7 @@
             }
         }
 
-        void processSection(ZipOutputStream zos, Section section, List<Path> paths)
+        void processSection(JmodOutputStream zos, Section section, List<Path> paths)
             throws IOException
         {
             if (paths == null)
@@ -655,11 +623,9 @@
                 processSection(zos, section, p);
         }
 
-        void processSection(ZipOutputStream zos, Section section, Path top)
+        void processSection(JmodOutputStream out, Section section, Path top)
             throws IOException
         {
-            final String prefix = section.jmodDir();
-
             Files.walkFileTree(top, new SimpleFileVisitor<Path>() {
                 @Override
                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
@@ -667,13 +633,19 @@
                 {
                     Path relPath = top.relativize(file);
                     if (relPath.toString().equals(MODULE_INFO)
-                            && !Section.CLASSES.equals(section))
+                        && !Section.CLASSES.equals(section))
                         warning("warn.ignore.entry", MODULE_INFO, section);
 
                     if (!relPath.toString().equals(MODULE_INFO)
-                            && !matches(relPath, excludes)) {
+                        && !matches(relPath, excludes)) {
                         try (InputStream in = Files.newInputStream(file)) {
-                            writeZipEntry(zos, in, prefix, relPath.toString());
+                            out.writeEntry(in, section, relPath.toString());
+                        } catch (IOException x) {
+                            if (x.getMessage().contains("duplicate entry")) {
+                                warning("warn.ignore.duplicate.entry", relPath.toString(), section);
+                                return FileVisitResult.CONTINUE;
+                            }
+                            throw x;
                         }
                     }
                     return FileVisitResult.CONTINUE;
@@ -691,36 +663,17 @@
             return false;
         }
 
-        void writeZipEntry(ZipOutputStream zos, InputStream in, String prefix, String other)
-            throws IOException
-        {
-            String name = Paths.get(prefix, other).toString()
-                               .replace(File.separatorChar, '/');
-            ZipEntry ze = new ZipEntry(name);
-            try {
-                zos.putNextEntry(ze);
-                in.transferTo(zos);
-                zos.closeEntry();
-            } catch (ZipException x) {
-                if (x.getMessage().contains("duplicate entry")) {
-                    warning("warn.ignore.duplicate.entry", name, prefix);
-                    return;
-                }
-                throw x;
-            }
-        }
-
         class JarEntryConsumer implements Consumer<JarEntry>, Predicate<JarEntry> {
-            final ZipOutputStream zos;
+            final JmodOutputStream out;
             final JarFile jarfile;
-            JarEntryConsumer(ZipOutputStream zos, JarFile jarfile) {
-                this.zos = zos;
+            JarEntryConsumer(JmodOutputStream out, JarFile jarfile) {
+                this.out = out;
                 this.jarfile = jarfile;
             }
             @Override
             public void accept(JarEntry je) {
                 try (InputStream in = jarfile.getInputStream(je)) {
-                    writeZipEntry(zos, in, Section.CLASSES.jmodDir(), je.getName());
+                    out.writeEntry(in, Section.CLASSES, je.getName());
                 } catch (IOException e) {
                     throw new UncheckedIOException(e);
                 }
@@ -947,29 +900,11 @@
         {
             Path target = moduleNameToPath.get(name);
             Path tempTarget = target.resolveSibling(target.getFileName() + ".tmp");
-            ZipFile zip = new ZipFile(target.toFile());
             try {
-                try (OutputStream out = Files.newOutputStream(tempTarget);
-                     ZipOutputStream zos = new ZipOutputStream(out)) {
-                    zip.stream().forEach(e -> {
-                        try {
-                            InputStream in = zip.getInputStream(e);
-                            if (e.getName().equals(MODULE_INFO) ||
-                                e.getName().equals(Section.CLASSES.jmodDir() + "/" + MODULE_INFO)) {
-                                ZipEntry ze = new ZipEntry(e.getName());
-                                ze.setTime(System.currentTimeMillis());
-                                zos.putNextEntry(ze);
-                                recordHashes(in, zos, moduleHashes);
-                                zos.closeEntry();
-                            } else {
-                                zos.putNextEntry(e);
-                                zos.write(in.readAllBytes());
-                                zos.closeEntry();
-                            }
-                        } catch (IOException x) {
-                            throw new UncheckedIOException(x);
-                        }
-                    });
+                if (target.getFileName().toString().endsWith(".jmod")) {
+                    updateJmodFile(target, tempTarget, moduleHashes);
+                } else {
+                    updateModularJar(target, tempTarget, moduleHashes);
                 }
             } catch (IOException|RuntimeException e) {
                 if (Files.exists(tempTarget)) {
@@ -980,13 +915,67 @@
                     }
                 }
                 throw e;
-            } finally {
-                zip.close();
             }
+
             out.println(getMessage("module.hashes.recorded", name));
             Files.move(tempTarget, target, StandardCopyOption.REPLACE_EXISTING);
         }
 
+        private void updateModularJar(Path target, Path tempTarget,
+                                      ModuleHashes moduleHashes)
+            throws IOException
+        {
+            try (JarFile jf = new JarFile(target.toFile());
+                 OutputStream out = Files.newOutputStream(tempTarget);
+                 JarOutputStream jos = new JarOutputStream(out))
+            {
+                jf.stream().forEach(e -> {
+                    try (InputStream in = jf.getInputStream(e)) {
+                        if (e.getName().equals(MODULE_INFO)) {
+                            // what about module-info.class in versioned entries?
+                            ZipEntry ze = new ZipEntry(e.getName());
+                            ze.setTime(System.currentTimeMillis());
+                            jos.putNextEntry(ze);
+                            recordHashes(in, jos, moduleHashes);
+                            jos.closeEntry();
+                        } else {
+                            jos.putNextEntry(e);
+                            jos.write(in.readAllBytes());
+                            jos.closeEntry();
+                        }
+                    } catch (IOException x) {
+                        throw new UncheckedIOException(x);
+                    }
+                });
+            }
+        }
+
+        private void updateJmodFile(Path target, Path tempTarget,
+                                    ModuleHashes moduleHashes)
+            throws IOException
+        {
+
+            try (JmodFile jf = new JmodFile(target);
+                 JmodOutputStream jos = JmodOutputStream.newOutputStream(tempTarget))
+            {
+                jf.stream().forEach(e -> {
+                    try (InputStream in = jf.getInputStream(e.section(), e.name())) {
+                        if (e.name().equals(MODULE_INFO)) {
+                            // replace module-info.class
+                            ModuleInfoExtender extender =
+                                ModuleInfoExtender.newExtender(in);
+                            extender.hashes(moduleHashes);
+                            jos.writeEntry(extender.toByteArray(), e.section(), e.name());
+                        } else {
+                            jos.writeEntry(in, e);
+                        }
+                    } catch (IOException x) {
+                        throw new UncheckedIOException(x);
+                    }
+                });
+            }
+        }
+
         private Path moduleToPath(String name) {
             ModuleReference mref = moduleFinder.find(name).orElseThrow(
                 () -> new InternalError("Selected module " + name + " not on module path"));
@@ -1001,22 +990,6 @@
         }
     }
 
-    enum Section {
-        NATIVE_LIBS("native"),
-        NATIVE_CMDS("bin"),
-        CLASSES("classes"),
-        CONFIG("conf"),
-        UNKNOWN("unknown");
-
-        private final String jmodDir;
-
-        Section(String jmodDir) {
-            this.jmodDir = jmodDir;
-        }
-
-        String jmodDir() { return jmodDir; }
-    }
-
     static class ClassPathConverter implements ValueConverter<Path> {
         static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
 
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"Marshallinseln Zeit", "MHT",
                                      "Marshallinseln Sommerzeit", "MHST",
                                      "Marshallinseln Zeit", "MHT"};
+        String MMT[] = new String[] {"Myanmar Zeit", "MMT",
+                                     "Myanmar Sommerzeit", "MMST",
+                                     "Myanmar Zeit", "MMT"};
         String MSK[] = new String[] {"Moskauer Normalzeit", "MSK",
                                      "Moskauer Sommerzeit", "MSD",
                                      "Zeitzone f\u00FCr Moskau", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda Zeit", "QYZT",
                                              "Qyzylorda Sommerzeit", "QYZST",
                                              "Qyzylorda Zeit", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Myanmar Zeit", "MMT",
-                                           "Myanmar Sommerzeit", "MMST",
-                                           "Myanmar Zeit", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Sakhalin Zeit", "SAKT",
@@ -719,6 +720,7 @@
                                                "Wladiwostok Sommerzeit", "VLAST",
                                                "Wladiwostok Zeit", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Jekaterinburger Zeit", "YEKT",
                                                  "Jekaterinburger Sommerzeit", "YEKST",
                                                  "Jekaterinburger Zeit", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"Hora de las Islas Marshall", "MHT",
                                      "Hora de verano de las Islas Marshall", "MHST",
                                      "Hora de Islas Marshall", "MHT"};
+        String MMT[] = new String[] {"Hora de Myanmar", "MMT",
+                                     "Hora de verano de Myanmar", "MMST",
+                                     "Hora de Myanmar", "MMT"};
         String MSK[] = new String[] {"Hora est\u00e1ndar de Mosc\u00fa", "MSK",
                                      "Hora de verano de Mosc\u00fa", "MSD",
                                      "Hora de Mosc\u00FA", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Hora de Qyzylorda", "QYZT",
                                              "Hora de verano de Qyzylorda", "QYZST",
                                              "Hora de Qyzylorda", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Hora de Myanmar", "MMT",
-                                           "Hora de verano de Myanmar", "MMST",
-                                           "Hora de Myanmar", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Hora de Sajalin", "SAKT",
@@ -719,6 +720,7 @@
                                                "Hora de verano de Vladivostok", "VLAST",
                                                "Hora de Vladivostok", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Hora de Ekaterinburgo", "YEKT",
                                                  "Hora de verano de Ekaterinburgo", "YEKST",
                                                  "Hora de Ekaterinburgo", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"Heure des Iles Marshall", "MHT",
                                      "Heure d'\u00e9t\u00e9 des Iles Marshall", "MHST",
                                      "Heure des Iles Marshall", "MHT"};
+        String MMT[] = new String[] {"Heure de Myanmar", "MMT",
+                                     "Heure d'\u00e9t\u00e9 de Myanmar", "MMST",
+                                     "Heure de Myanmar", "MMT"};
         String MSK[] = new String[] {"Heure standard de Moscou", "MSK",
                                      "Heure avanc\u00e9e de Moscou", "MSD",
                                      "Moscou", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Heure de Kyzylorda", "QYZT",
                                              "Heure d'\u00e9t\u00e9 de Kyzylorda", "QYZST",
                                              "Heure de Kyzylorda", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Heure de Myanmar", "MMT",
-                                           "Heure d'\u00e9t\u00e9 de Myanmar", "MMST",
-                                           "Heure de Myanmar", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Heure de Sakhalin", "SAKT",
@@ -719,6 +720,7 @@
                                                "Heure d'\u00e9t\u00e9 de Vladivostok", "VLAST",
                                                "Heure de Vladivostok", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Heure de Yekaterinburg", "YEKT",
                                                  "Heure d'\u00e9t\u00e9 de Yekaterinburg", "YEKST",
                                                  "Heure de Yekaterinburg", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"Ora delle Isole Marshall", "MHT",
                                      "Ora estiva delle Isole Marshall", "MHST",
                                      "Ora delle Isole Marshall", "MHT"};
+        String MMT[] = new String[] {"Ora della Birmania/Myanmar", "MMT",
+                                     "Ora estiva della Birmania/Myanmar", "MMST",
+                                     "Ora della Birmania/Myanmar", "MMT"};
         String MSK[] = new String[] {"Ora standard di Mosca", "MSK",
                                      "Ora legale di Mosca", "MSD",
                                      "Ora Mosca", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Ora di Qyzylorda", "QYZT",
                                              "Ora estiva di Qyzylorda", "QYZST",
                                              "Ora di Qyzylorda", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Ora della Birmania/Myanmar", "MMT",
-                                           "Ora estiva della Birmania/Myanmar", "MMST",
-                                           "Ora della Birmania/Myanmar", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Ora di Sakhalin", "SAKT",
@@ -719,6 +720,7 @@
                                                "Ora estiva di Vladivostok", "VLAST",
                                                "Ora di Vladivostok", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Ora di Ekaterinburg", "YEKT",
                                                  "Ora estiva di Ekaterinburg", "YEKST",
                                                  "Ora di Ekaterinburg", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"\u30de\u30fc\u30b7\u30e3\u30eb\u5cf6\u6642\u9593", "MHT",
                                      "\u30de\u30fc\u30b7\u30e3\u30eb\u5cf6\u590f\u6642\u9593", "MHST",
                                      "\u30DE\u30FC\u30B7\u30E3\u30EB\u8AF8\u5CF6\u6642\u9593", "MHT"};
+        String MMT[] = new String[] {"\u30df\u30e3\u30f3\u30de\u30fc\u6642\u9593", "MMT",
+                                     "\u30df\u30e3\u30f3\u30de\u30fc\u590f\u6642\u9593", "MMST",
+                                     "\u30DF\u30E3\u30F3\u30DE\u30FC\u6642\u9593", "MMT"};
         String MSK[] = new String[] {"\u30e2\u30b9\u30af\u30ef\u6a19\u6e96\u6642", "MSK",
                                      "\u30e2\u30b9\u30af\u30ef\u590f\u6642\u9593", "MSD",
                                      "\u30E2\u30B9\u30AF\u30EF\u6642\u9593", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"\u30ad\u30b8\u30eb\u30aa\u30eb\u30c0\u6642\u9593", "QYZT",
                                              "\u30ad\u30b8\u30eb\u30aa\u30eb\u30c0\u590f\u6642\u9593", "QYZST",
                                              "\u30AF\u30BA\u30ED\u30EB\u30C0\u6642\u9593", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"\u30df\u30e3\u30f3\u30de\u30fc\u6642\u9593", "MMT",
-                                           "\u30df\u30e3\u30f3\u30de\u30fc\u590f\u6642\u9593", "MMST",
-                                           "\u30DF\u30E3\u30F3\u30DE\u30FC\u6642\u9593", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"\u6a3a\u592a\u6642\u9593", "SAKT",
@@ -719,6 +720,7 @@
                                                "\u30a6\u30e9\u30b8\u30aa\u30b9\u30c8\u30af\u590f\u6642\u9593", "VLAST",
                                                "\u30A6\u30E9\u30B8\u30AA\u30B9\u30C8\u30AF\u6642\u9593", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"\u30a8\u30ab\u30c6\u30ea\u30f3\u30d6\u30eb\u30b0\u6642\u9593", "YEKT",
                                                  "\u30a8\u30ab\u30c6\u30ea\u30f3\u30d6\u30eb\u30b0\u590f\u6642\u9593", "YEKST",
                                                  "\u30A8\u30AB\u30C6\u30EA\u30F3\u30D6\u30EB\u30AF\u6642\u9593", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"\ub9c8\uc15c\uc81c\ub3c4 \uc2dc\uac04", "MHT",
                                      "\ub9c8\uc15c\uc81c\ub3c4 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MHST",
                                      "\uB9C8\uC15C \uC81C\uB3C4 \uD45C\uC900\uC2DC", "MHT"};
+        String MMT[] = new String[] {"\ubbf8\uc580\ub9c8 \uc2dc\uac04", "MMT",
+                                     "\ubbf8\uc580\ub9c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MMST",
+                                     "\uBBF8\uC580\uB9C8 \uD45C\uC900\uC2DC", "MMT"};
         String MSK[] = new String[] {"\ubaa8\uc2a4\ud06c\ubc14 \ud45c\uc900\uc2dc", "MSK",
                                      "\ubaa8\uc2a4\ud06c\ubc14 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MSD",
                                      "\uBAA8\uC2A4\uD06C\uBC14 \uD45C\uC900\uC2DC", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda \ud45c\uc900\uc2dc", "QYZT",
                                              "Qyzylorda \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "QYZST",
                                              "\uD0A4\uC9C8\uB85C\uB974\uB2E4 \uD45C\uC900\uC2DC", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"\ubbf8\uc580\ub9c8 \uc2dc\uac04", "MMT",
-                                           "\ubbf8\uc580\ub9c8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MMST",
-                                           "\uBBF8\uC580\uB9C8 \uD45C\uC900\uC2DC", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"\uc0ac\ud560\ub9b0 \uc2dc\uac04", "SAKT",
@@ -719,6 +720,7 @@
                                                "\ube14\ub77c\ub514\ubcf4\uc2a4\ud1a1 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VLAST",
                                                "\uBE14\uB77C\uB514\uBCF4\uC2A4\uD1A1 \uD45C\uC900\uC2DC", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"\uc608\uce74\ud14c\ub9b0\ubc84\uadf8 \uc2dc\uac04", "YEKT",
                                                  "\uc608\uce74\ud14c\ub9b0\ubc84\uadf8 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "YEKST",
                                                  "\uC608\uCE74\uD14C\uB9B0\uBD80\uB974\uD06C \uD45C\uC900\uC2DC", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MSK[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Moscou", "MSK",
                                      "Hor\u00e1rio de luz natural de Moscou", "MSD",
                                      "Hor\u00E1rio de Moscou", "MT"};
+        String MMT[] = new String[] {"Fuso hor\u00e1rio de Mianmar", "MMT",
+                                     "Fuso hor\u00e1rio de ver\u00e3o de Mianmar", "MMST",
+                                     "Hor\u00E1rio de Mianmar", "MMT"};
         String MST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o das montanhas", "MST",
                                      "Hor\u00e1rio de luz natural das montanhas", "MDT",
                                      "Hor\u00E1rio das Montanhas Rochosas", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Fuso hor\u00e1rio de Kizil-Orda", "QYZT",
                                              "Fuso hor\u00e1rio de ver\u00e3o de Kizil-Orda", "QYZST",
                                              "Hor\u00E1rio de Qyzylorda", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Fuso hor\u00e1rio de Mianmar", "MMT",
-                                           "Fuso hor\u00e1rio de ver\u00e3o de Mianmar", "MMST",
-                                           "Hor\u00E1rio de Mianmar", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Fuso hor\u00e1rio de Sakhalina", "SAKT",
@@ -719,6 +720,7 @@
                                                "Fuso hor\u00e1rio de ver\u00e3o de Vladivostok", "VLAST",
                                                "Hor\u00E1rio de Vladivostok", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Fuso hor\u00e1rio de Yekaterinburgo", "YEKT",
                                                  "Fuso hor\u00e1rio de ver\u00e3o de Yekaterinburgo", "YEKST",
                                                  "Hor\u00E1rio de Yekaterinburg", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"Marshall\u00f6arna, normaltid", "MHT",
                                      "Marshall\u00f6arna, sommartid", "MHST",
                                      "Marshall\u00F6arna-tid", "MHT"};
+        String MMT[] = new String[] {"Myanmar, normaltid", "MMT",
+                                     "Myanmar, sommartid", "MMST",
+                                     "Myanmar-tid", "MMT"};
         String MSK[] = new String[] {"Moskva, normaltid", "MSK",
                                      "Moskva, sommartid", "MSD",
                                      "Moskvas tid", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda, normaltid", "QYZT",
                                              "Qyzylorda, sommartid", "QYZST",
                                              "Qyzylorda-tid", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"Myanmar, normaltid", "MMT",
-                                           "Myanmar, sommartid", "MMST",
-                                           "Myanmar-tid", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"Sakhalin, normaltid", "SAKT",
@@ -719,6 +720,7 @@
                                                "Vladivostok, sommartid", "VLAST",
                                                "Vladivostok-tid", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Jekaterinburg, normaltid", "YEKT",
                                                  "Jekaterinburg, sommartid", "YEKST",
                                                  "Jekaterinburg-tid", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"\u9a6c\u7ecd\u5c14\u7fa4\u5c9b\u65f6\u95f4", "MHT",
                                      "\u9a6c\u7ecd\u5c14\u7fa4\u5c9b\u590f\u4ee4\u65f6", "MHST",
                                      "\u9A6C\u7ECD\u5C14\u7FA4\u5C9B\u65F6\u95F4", "MHT"};
+        String MMT[] = new String[] {"\u7f05\u7538\u65f6\u95f4", "MMT",
+                                     "\u7f05\u7538\u590f\u4ee4\u65f6", "MMST",
+                                     "\u7F05\u7538\u65F6\u95F4", "MMT"};
         String MSK[] = new String[] {"\u83ab\u65af\u79d1\u6807\u51c6\u65f6\u95f4", "MSK",
                                      "\u83ab\u65af\u79d1\u590f\u4ee4\u65f6", "MSD",
                                      "\u83AB\u65AF\u79D1\u65F6\u95F4", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda \u65f6\u95f4", "QYZT",
                                              "Qyzylorda \u590f\u4ee4\u65f6", "QYZST",
                                              "Qyzylorda \u65F6\u95F4", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"\u7f05\u7538\u65f6\u95f4", "MMT",
-                                           "\u7f05\u7538\u590f\u4ee4\u65f6", "MMST",
-                                           "\u7F05\u7538\u65F6\u95F4", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"\u5e93\u9875\u5c9b\u65f6\u95f4", "SAKT",
@@ -719,6 +720,7 @@
                                                "\u6d77\u53c2\u5d34\u590f\u4ee4\u65f6", "VLAST",
                                                "\u6D77\u53C2\u5D34\u65F6\u95F4", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Yekaterinburg \u65f6\u95f4", "YEKT",
                                                  "Yekaterinburg \u590f\u4ee4\u65f6", "YEKST",
                                                  "Yekaterinburg \u65F6\u95F4", "YEKT"}},
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,6 +189,9 @@
         String MHT[] = new String[] {"\u99ac\u7d39\u723e\u7fa4\u5cf6\u6642\u9593", "MHT",
                                      "\u99ac\u7d39\u723e\u7fa4\u5cf6\u590f\u4ee4\u6642\u9593", "MHST",
                                      "\u99AC\u7D39\u723E\u7FA4\u5CF6\u6642\u9593", "MHT"};
+        String MMT[] = new String[] {"\u7dec\u7538\u6642\u9593", "MMT",
+                                     "\u7dec\u7538\u590f\u4ee4\u6642\u9593", "MMST",
+                                     "\u7DEC\u7538\u6642\u9593", "MMT"};
         String MSK[] = new String[] {"\u83ab\u65af\u79d1\u6a19\u6e96\u6642\u9593", "MSK",
                                      "\u83ab\u65af\u79d1\u65e5\u5149\u7bc0\u7d04\u6642\u9593", "MSD",
                                      "\u83AB\u65AF\u79D1\u6642\u9593", "MT"};
@@ -684,9 +687,7 @@
             {"Asia/Qyzylorda", new String[] {"Qyzylorda \u6642\u9593", "QYZT",
                                              "Qyzylorda \u590f\u4ee4\u6642\u9593", "QYZST",
                                              "\u514B\u5B5C\u6D1B\u723E\u9054\u6642\u9593", "QYZT"}},
-            {"Asia/Rangoon", new String[] {"\u7dec\u7538\u6642\u9593", "MMT",
-                                           "\u7dec\u7538\u590f\u4ee4\u6642\u9593", "MMST",
-                                           "\u7DEC\u7538\u6642\u9593", "MMT"}},
+            {"Asia/Rangoon", MMT},
             {"Asia/Riyadh", ARAST},
             {"Asia/Saigon", ICT},
             {"Asia/Sakhalin", new String[] {"\u5eab\u9801\u5cf6\u6642\u9593", "SAKT",
@@ -721,6 +722,7 @@
                                                "\u6d77\u53c3\u5d34\u590f\u4ee4\u6642\u9593", "VLAST",
                                                "\u6D77\u53C3\u5D34\u6642\u9593", "VLAT"}},
             {"Asia/Yakutsk", YAKT},
+            {"Asia/Yangon", MMT},
             {"Asia/Yekaterinburg", new String[] {"Yekaterinburg \u6642\u9593", "YEKT",
                                                  "Yekaterinburg \u590f\u4ee4\u6642\u9593", "YEKST",
                                                  "\u8449\u5361\u6377\u7433\u5821\u6642\u9593", "YEKT"}},
--- a/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Mon Oct 10 13:31:48 2016 -0700
@@ -26,8 +26,6 @@
 package com.sun.security.jgss;
 
 import org.ietf.jgss.*;
-import sun.security.jgss.GSSContextImpl;
-import sun.security.krb5.internal.AuthorizationData;
 
 /**
  * The extended GSSContext interface for supporting additional
@@ -36,40 +34,6 @@
  */
 public interface ExtendedGSSContext extends GSSContext {
 
-    // The impl is almost identical to GSSContextImpl with only 2 differences:
-    // 1. It implements the extended interface
-    // 2. It translates result to data types here in inquireSecContext
-    static class ExtendedGSSContextImpl extends GSSContextImpl
-            implements ExtendedGSSContext {
-
-        public ExtendedGSSContextImpl(GSSContextImpl old) {
-            super(old);
-        }
-
-        @Override
-        public Object inquireSecContext(InquireType type) throws GSSException {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(
-                        new InquireSecContextPermission(type.toString()));
-            }
-            Object output = super.inquireSecContext(type.name());
-            if (output != null) {
-                if (type == InquireType.KRB5_GET_AUTHZ_DATA) {
-                    AuthorizationData ad = (AuthorizationData) output;
-                    AuthorizationDataEntry[] authzData =
-                            new AuthorizationDataEntry[ad.count()];
-                    for (int i = 0; i < ad.count(); i++) {
-                        authzData[i] = new AuthorizationDataEntry(
-                                ad.item(i).adType, ad.item(i).adData);
-                    }
-                    output = authzData;
-                }
-            }
-            return output;
-        }
-    }
-
     /**
      * Return the mechanism-specific attribute associated with {@code type}.
      * <p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContextImpl.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 com.sun.security.jgss;
+
+import org.ietf.jgss.*;
+import sun.security.jgss.GSSContextImpl;
+import sun.security.krb5.internal.AuthorizationData;
+
+// The impl is almost identical to GSSContextImpl with only 2 differences:
+// 1. It implements the extended interface
+// 2. It translates result to data types here in inquireSecContext
+class ExtendedGSSContextImpl extends GSSContextImpl
+        implements ExtendedGSSContext {
+
+    public ExtendedGSSContextImpl(GSSContextImpl old) {
+        super(old);
+    }
+
+    @Override
+    public Object inquireSecContext(InquireType type) throws GSSException {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(
+                    new InquireSecContextPermission(type.toString()));
+        }
+        Object output = super.inquireSecContext(type.name());
+        if (output != null) {
+            if (type == InquireType.KRB5_GET_AUTHZ_DATA) {
+                AuthorizationData ad = (AuthorizationData) output;
+                AuthorizationDataEntry[] authzData =
+                        new AuthorizationDataEntry[ad.count()];
+                for (int i = 0; i < ad.count(); i++) {
+                    authzData[i] = new AuthorizationDataEntry(
+                            ad.item(i).adType, ad.item(i).adData);
+                }
+                output = authzData;
+            }
+        }
+        return output;
+    }
+}
--- a/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Mon Oct 10 13:31:48 2016 -0700
@@ -26,7 +26,6 @@
 package com.sun.security.jgss;
 
 import org.ietf.jgss.*;
-import sun.security.jgss.GSSCredentialImpl;
 
 /**
  * The extended GSSCredential interface for supporting additional
@@ -35,14 +34,6 @@
  */
 public interface ExtendedGSSCredential extends GSSCredential {
 
-    static class ExtendedGSSCredentialImpl extends GSSCredentialImpl
-            implements ExtendedGSSCredential {
-
-        public ExtendedGSSCredentialImpl(GSSCredentialImpl old) {
-            super(old);
-        }
-    }
-
     /**
      * Impersonates a principal. In Kerberos, this can be implemented
      * using the Microsoft S4U2self extension.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredentialImpl.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 com.sun.security.jgss;
+
+import sun.security.jgss.GSSCredentialImpl;
+
+class ExtendedGSSCredentialImpl extends GSSCredentialImpl
+        implements ExtendedGSSCredential {
+
+    public ExtendedGSSCredentialImpl(GSSCredentialImpl old) {
+        super(old);
+    }
+}
--- a/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java	Mon Oct 10 13:31:48 2016 -0700
@@ -39,18 +39,18 @@
     }
 
     public GSSCredential wrap(GSSCredential cred) {
-        if (cred instanceof ExtendedGSSCredential.ExtendedGSSCredentialImpl) {
+        if (cred instanceof ExtendedGSSCredentialImpl) {
             return cred;
         } else {
-            return new ExtendedGSSCredential.ExtendedGSSCredentialImpl((GSSCredentialImpl)cred);
+            return new ExtendedGSSCredentialImpl((GSSCredentialImpl)cred);
         }
     }
 
     public GSSContext wrap(GSSContext ctxt) {
-        if (ctxt instanceof ExtendedGSSContext.ExtendedGSSContextImpl) {
+        if (ctxt instanceof ExtendedGSSContextImpl) {
             return ctxt;
         } else {
-            return new ExtendedGSSContext.ExtendedGSSContextImpl((GSSContextImpl)ctxt);
+            return new ExtendedGSSContextImpl((GSSContextImpl)ctxt);
         }
     }
 }
--- a/jdk/test/ProblemList.txt	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/ProblemList.txt	Mon Oct 10 13:31:48 2016 -0700
@@ -134,8 +134,6 @@
 
 java/lang/instrument/BootClassPath/BootClassPathTest.sh         8072130 macosx-all
 
-java/lang/instrument/DaemonThread/TestDaemonThread.java         8161225 generic-all
-
 java/lang/instrument/DaemonThread/TestDaemonThread.java         8167001 generic-all
 
 java/lang/management/MemoryMXBean/Pending.java                  8158837 generic-all
--- a/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBECons.java	Mon Oct 10 13:31:48 2016 -0700
@@ -36,7 +36,6 @@
  * @author Yun Ke
  * @author Bill Situ
  * @author Yu-Ching (Valerie) PENG
- * @run main TestCipherKeyWrapperPBEKey
  */
 public class TestCipherPBECons {
 
--- a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -197,14 +197,18 @@
         // invoke interface static method A
         testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
 
-        // try to invoke static method A on the instance
-        testInvokePos(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
+        // invoking static method A on the instance fails because static method A is
+        // not inherited by TargetClass.
+        testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
+                "Invalid MethodID");
 
         // invoke interface static method B
         testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
 
-        // try to invoke static method B on the instance
-        testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
+        // invoking static method B on the instance fails because static method B is
+        // not inherited by TargetClass.
+        testInvokeNeg(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A),
+                "Invalid MethodID");
 
         // try to invoke a virtual method
         testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true);
@@ -239,21 +243,25 @@
         testInvokeNeg(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
                 "Static interface methods are not inheritable");
 
-        // however it is possible to call "staticMethodA" on the actual instance
+        // "staticMethodA" is not inherited by InterfaceB even from an actual instance
         testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
                 "Static interface methods are not inheritable");
 
-        // "staticMethodB" is overridden in InterfaceB
+        // "staticMethodB" is re-defined in InterfaceB
         testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
 
-        // the instance invokes the overriden form of "staticMethodB" from InterfaceB
-        testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
+        // the instance fails to invoke the re-defined form of "staticMethodB" from
+        // InterfaceB because staticMethodB is not inherited by TargetClass
+        testInvokeNeg(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
+                "Invalid MethodID");
 
         // "staticMethodC" is present only in InterfaceB
         testInvokePos(ifaceClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
 
-        // "staticMethodC" should be reachable from the instance too
-        testInvokePos(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
+        // "staticMethodC" is not reachable from the instance because staticMethodC
+        // is not inherited by TargetClass.
+        testInvokeNeg(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
+                "Invalid MethodID");
     }
 
     private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/Correctness.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ *
+ * @test
+ * @bug 8164705
+ * @summary Remove pathname canonicalization from FilePermission
+ */
+
+import java.io.FilePermission;
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class Correctness {
+
+    static boolean err = false;
+    static Method containsMethod;
+    static boolean isWindows =
+            System.getProperty("os.name").contains("Windows");
+    public static void main(String args[]) throws Exception {
+        check("/", "/");
+        checkNo("/", "/x");
+        checkNo("/", "/../x");
+
+        checkNo("/", "x");
+
+        check("/-", "/*");
+        checkNo("/*", "/-");
+
+        check("/*", "/x");
+        check("/-", "/x");
+        check("/-", "/x/*");
+        check("/-", "/x/-");
+        check("/-", "/x/y");
+        checkNo("/*", "/x/y");
+        check("/x/*", "/x/x");
+        checkNo("/x/-", "/x");
+        checkNo("/x/*", "/x");
+        check("/x/-", "/x/x");
+        check("/x/-", "/x/x/y");
+        checkNo("/x/*", "/x/x/y");
+        checkNo("/x/*", "/x");
+
+        check("*", "x");
+        checkNo("", "x");
+        check("-", "x");
+        check("-", "*");
+        check("-", "a/-");
+        check("-", "a/*");
+        checkNo("*", "a/b");
+        check("a/*", "a/b");
+        check("a/-", "a/*");
+        check("a/-", "a/b/c");
+        checkNo("a/*", "a/b/c");
+
+        check("../", "../");
+        check("../-", "../*");
+        check("../../*", "../../a");
+
+        // If we allow .. and abs/rel checks
+        check("../-", "a");
+        check("../../-", "-");
+        checkNo("../../*", "a");
+        //check("/-", "a");
+        //checkNo("/*", "a");
+        //check("/-", "-");
+
+        try {
+            // containsPath is broken on Windows.
+            containsMethod = FilePermission.class.getDeclaredMethod(
+                    "containsPath", Path.class, Path.class);
+            containsMethod.setAccessible(true);
+            System.out.println();
+
+            contains("x", "x", 0);
+            contains("x", "x/y", 1);
+            contains("x", "x/y/z", 2);
+            contains("x", "y", -1);
+            contains("x", "", -1);
+            contains("", "", 0);
+            contains("", "x", 1);
+            contains("", "x/y", 2);
+            contains("/", "/", 0);
+            contains("/", "/x", 1);
+            contains("/", "/x/y", 2);
+            contains("/x", "/x/y", 1);
+            contains("/x", "/y", -1);
+            //contains("/", "..", Integer.MAX_VALUE);
+            //contains("/", "x", Integer.MAX_VALUE);
+            //contains("/", "x/y", Integer.MAX_VALUE);
+            //contains("/", "../x", Integer.MAX_VALUE);
+            contains("/x", "y", -1);
+            contains("x", "/y", -1);
+
+            contains("", "..", -1);
+            contains("", "../x", -1);
+            contains("..", "", 1);
+            contains("..", "x", 2);
+            contains("..", "x/y", 3);
+            contains("../x", "x", -1);
+            contains("../x", "y", -1);
+            contains("../x", "../x/y", 1);
+            contains("../../x", "../../x/y", 1);
+            contains("../../../x", "../../../x/y", 1);
+            contains("../x", "../y", -1);
+        } catch (NoSuchMethodException e) {
+            // Ignored
+        }
+        if (err) throw new Exception("Failed.");
+    }
+
+    // Checks if s2 is inside s1 and depth is expected.
+    static void contains(String s1, String s2, int expected) throws Exception {
+        contains0(s1, s2, expected);
+        if (isWindows) {
+            contains0("C:" + s1, s2, -1);
+            contains0(s1, "C:" + s2, -1);
+            contains0("C:" + s1, "D:" + s2, -1);
+            contains0("C:" + s1, "C:" + s2, expected);
+        }
+    }
+
+    static void contains0(String s1, String s2, int expected) throws Exception {
+        Path p1 = Paths.get(s1);
+        Path p2 = Paths.get(s2);
+        int d = (int)containsMethod.invoke(null, p1, p2);
+        Path p;
+        try {
+            p = p2.relativize(p1);
+        } catch (Exception e) {
+            p = null;
+        }
+        System.out.printf("%-20s -> %-20s: %20s %5d %5d %s\n", s1, s2, p,
+                d, expected, d==expected?"":" WRONG");
+        if (d != expected) {
+            err = true;
+        }
+    }
+
+    static void check(String s1, String s2, boolean expected) {
+        FilePermission fp1 = new FilePermission(s1, "read");
+        FilePermission fp2 = new FilePermission(s2, "read");
+        boolean b = fp1.implies(fp2);
+        System.out.printf("%-30s -> %-30s: %5b %s\n",
+                s1, s2, b, b==expected?"":" WRONG");
+        if (b != expected) {
+            err = true;
+            System.out.println(fp1);
+            System.out.println(fp2);
+        }
+    }
+
+    static void check(String s1, String s2) {
+        check(s1, s2, true);
+    }
+
+    static void checkNo(String s1, String s2) {
+        check(s1, s2, false);
+    }
+}
--- a/jdk/test/java/io/FilePermission/FilePermissionCollection.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/io/FilePermission/FilePermissionCollection.java	Mon Oct 10 13:31:48 2016 -0700
@@ -47,14 +47,14 @@
             ("test 1: add throws IllegalArgExc for wrong perm type");
         try {
             perms.add(new SecurityPermission("createAccessControlContext"));
-            System.err.println("Expected IllegalArgumentException");
+            System.out.println("Expected IllegalArgumentException");
             testFail++;
         } catch (IllegalArgumentException iae) {}
 
         // test 2
         System.out.println("test 2: implies returns false for wrong perm type");
         if (perms.implies(new SecurityPermission("getPolicy"))) {
-            System.err.println("Expected false, returned true");
+            System.out.println("Expected false, returned true");
             testFail++;
         }
 
@@ -63,7 +63,7 @@
                            "name and action");
         perms.add(new FilePermission("/tmp/foo", "read"));
         if (!perms.implies(new FilePermission("/tmp/foo", "read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
@@ -71,7 +71,7 @@
         System.out.println("test 4: implies returns false for match on " +
                            "name but not action");
         if (perms.implies(new FilePermission("/tmp/foo", "write"))) {
-            System.err.println("Expected false, returned true");
+            System.out.println("Expected false, returned true");
             testFail++;
         }
 
@@ -80,7 +80,7 @@
                            "name and subset of actions");
         perms.add(new FilePermission("/tmp/bar", "read, write"));
         if (!perms.implies(new FilePermission("/tmp/bar", "write"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
@@ -90,11 +90,11 @@
         perms.add(new FilePermission("/tmp/baz", "read"));
         perms.add(new FilePermission("/tmp/baz", "write"));
         if (!perms.implies(new FilePermission("/tmp/baz", "read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
         if (!perms.implies(new FilePermission("/tmp/baz", "write,read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
@@ -103,7 +103,7 @@
                            "and match on action");
         perms.add(new FilePermission("/usr/tmp/*", "read"));
         if (!perms.implies(new FilePermission("/usr/tmp/foo", "read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
@@ -111,7 +111,7 @@
         System.out.println
             ("test 8: implies returns false for non-match on wildcard");
         if (perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
-            System.err.println("Expected false, returned true");
+            System.out.println("Expected false, returned true");
             testFail++;
         }
 
@@ -120,25 +120,25 @@
             ("test 9: implies returns true for deep wildcard match");
         perms.add(new FilePermission("/usr/tmp/-", "read"));
         if (!perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
         // test 10
-        System.out.println("test 10: implies returns true for relative match");
+        //System.out.println("test 10: implies returns true for relative match");
         perms.add(new FilePermission(".", "read"));
-        if (!perms.implies(new FilePermission(System.getProperty("user.dir"),
-                                              "read"))) {
-            System.err.println("Expected true, returned false");
-            testFail++;
-        }
+        //if (!perms.implies(new FilePermission(System.getProperty("user.dir"),
+        //                                      "read"))) {
+        //    System.out.println("Expected true, returned false");
+        //    testFail++;
+        //}
 
         // test 11
         System.out.println("test 11: implies returns true for all " +
                            "wildcard and match on action");
         perms.add(new FilePermission("<<ALL FILES>>", "read"));
         if (!perms.implies(new FilePermission("/tmp/foobar", "read"))) {
-            System.err.println("Expected true, returned false");
+            System.out.println("Expected true, returned false");
             testFail++;
         }
 
@@ -146,7 +146,7 @@
         System.out.println("test 12: implies returns false for wildcard " +
                            "and non-match on action");
         if (perms.implies(new FilePermission("/tmp/foobar", "write"))) {
-            System.err.println("Expected false, returned true");
+            System.out.println("Expected false, returned true");
             testFail++;
         }
 
@@ -160,7 +160,7 @@
         }
         // the two "/tmp/baz" entries were combined into one
         if (numPerms != 7) {
-            System.err.println("Expected 7, got " + numPerms);
+            System.out.println("Expected 7, got " + numPerms);
             testFail++;
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/FilePermissionTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FilePermission;
+import java.util.Arrays;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8156054
+ * @summary Test some of FilePermission methods when canonicalization property
+ *          set and un-set.
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=true
+ *      FilePermissionTest truetruetruetruetruetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=false
+ *      FilePermissionTest falsefalsefalsefalsefalsefalse
+ * @run main FilePermissionTest falsefalsefalsefalsefalsefalse
+ */
+public class FilePermissionTest {
+
+    public static void main(String[] args) throws Exception {
+
+        final File realFile = new File("exist.file");
+        try {
+            if (!realFile.createNewFile()) {
+                throw new RuntimeException("Unable to create a file.");
+            }
+            check(Arrays.asList(realFile.getName(), "notexist.file"), args[0]);
+        } finally {
+            if (realFile.exists()) {
+                realFile.delete();
+            }
+        }
+    }
+
+    private static void check(List<String> files, String expected) {
+
+        StringBuilder actual = new StringBuilder();
+        files.forEach(f -> {
+            StringBuilder result = new StringBuilder();
+            FilePermission fp1 = new FilePermission(f, "read");
+            FilePermission fp2 = new FilePermission(
+                    new File(f).getAbsolutePath(), "read");
+            result.append(fp1.equals(fp2));
+            result.append(fp1.implies(fp2));
+            result.append(fp1.hashCode() == fp2.hashCode());
+            System.out.println(fp1 + " Vs. " + fp2 + " : Result: " + result);
+            actual.append(result);
+        });
+        if (!expected.equals(actual.toString())) {
+            throw new RuntimeException("Failed: " + expected + "/" + actual);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/ReadFileOnPath.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164705
+ * @library /lib/testlibrary /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @run main ReadFileOnPath
+ * @summary Still able to read file on the same path
+ */
+
+import jdk.test.lib.process.ProcessTools;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ReadFileOnPath {
+
+    private static final Path SRC_DIR    = Paths.get(System.getProperty("test.src"));
+    private static final Path HERE_DIR   = Paths.get(".");
+    private static final Path MODS_DIR   = Paths.get("modules");
+
+    public static void main(String args[]) throws Exception {
+        CompilerUtils.compile(SRC_DIR.resolve("m"), MODS_DIR.resolve("m"));
+        Files.write(MODS_DIR.resolve("m/base"), "base".getBytes());
+        Files.write(MODS_DIR.resolve("m/p/child"), "child".getBytes());
+        JarUtils.createJarFile(HERE_DIR.resolve("old.jar"),
+                MODS_DIR.resolve("m"),
+                "base", "p/App.class", "p/child");
+        JarUtils.createJarFile(HERE_DIR.resolve("new.jar"),
+                MODS_DIR.resolve("m"),
+                "module-info.class", "base", "p/App.class", "p/child");
+
+        // exploded module
+        test("--module-path", "modules", "-m", "m/p.App", "SS+++++");
+
+        // module in jar
+        test("--module-path", "new.jar", "-m", "m/p.App", "SSSS++0");
+
+        // exploded classpath
+        test("-cp", "modules/m", "p.App", "SS+++++");
+
+        // classpath in jar
+        test("-cp", "old.jar", "p.App", "SSSS++0");
+    }
+
+    static void test(String... args) throws Exception {
+        List<String> cmds = new ArrayList<>();
+        cmds.add("-Djava.security.manager");
+        cmds.addAll(Arrays.asList(args));
+        cmds.addAll(List.of(
+                "x", "modules/m", "modules/m/base", "modules/m/p/child",
+                "-", "child", "/base", "../base"));
+        ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()]))
+                .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/m/module-info.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,3 @@
+module m {
+    exports p;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/m/p/App.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,44 @@
+package p;
+import java.io.InputStream;
+import java.io.FileInputStream;
+public class App {
+    public static void main(String[] args) throws Exception {
+        boolean f = true;
+        StringBuilder sb = new StringBuilder();
+        String expected = null;
+        for (String s: args) {
+            if (expected == null) {
+                expected = s;
+            } else if (s.equals("-")) {
+                f = false;
+            } else if (f) {
+                try (InputStream is = new FileInputStream(s)) {
+                    is.readAllBytes();
+                    sb.append('+');
+                } catch (SecurityException se) {
+                    System.out.println(se);
+                    sb.append('S');
+                } catch (Exception e) {
+                    System.out.println(e);
+                    sb.append('-');
+                }
+            } else {
+                try (InputStream is = App.class.getResourceAsStream(s)) {
+                    is.readAllBytes();
+                    sb.append('+');
+                } catch (NullPointerException npe) {
+                    System.out.println(npe);
+                    sb.append('0');
+                } catch (Exception e) {
+                    System.out.println(e);
+                    sb.append('-');
+                }
+            }
+        }
+        if (!sb.toString().equals(expected)) {
+            throw new Exception("Expected " + expected + ", actually " + sb);
+        } else {
+            System.out.println("OK");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/CheckInputOrderTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.security.Security;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+/* @test
+ * @build CheckInputOrderTest SerialFilterTest
+ * @run testng/othervm CheckInputOrderTest
+ *
+ * @summary Test that when both global filter and specific filter are set,
+ *          global filter will not affect specific filter.
+ */
+
+public class CheckInputOrderTest implements Serializable {
+    private static final long serialVersionUID = 12345678901L;
+
+    @DataProvider(name="Patterns")
+    Object[][] patterns() {
+        return new Object[][] {
+                new Object[] { SerialFilterTest.genTestObject("maxarray=1", true), "java.**;java.lang.*;java.lang.Long;maxarray=0", false },
+                new Object[] { SerialFilterTest.genTestObject("maxarray=1", true), "java.**;java.lang.*;java.lang.Long", true },
+                new Object[] { Long.MAX_VALUE, "java.**;java.lang.*;java.lang.Long;maxdepth=0", false },
+                new Object[] { Long.MAX_VALUE, "java.**;java.lang.*;java.lang.Long;maxbytes=0", false },
+                new Object[] { Long.MAX_VALUE, "java.**;java.lang.*;java.lang.Long;maxrefs=0", false },
+
+                new Object[] { Long.MAX_VALUE, "java.**;java.lang.*;java.lang.Long", true },
+
+                new Object[] { Long.MAX_VALUE, "!java.**;java.lang.*;java.lang.Long", false },
+                new Object[] { Long.MAX_VALUE, "java.**;!java.lang.*;java.lang.Long", true },
+
+                new Object[] { Long.MAX_VALUE, "!java.lang.*;java.**;java.lang.Long", false },
+                new Object[] { Long.MAX_VALUE, "java.lang.*;!java.**;java.lang.Long", true },
+
+                new Object[] { Long.MAX_VALUE, "!java.lang.Long;java.**;java.lang.*", false },
+                new Object[] { Long.MAX_VALUE, "java.lang.Long;java.**;!java.lang.*", true },
+
+                new Object[] { Long.MAX_VALUE, "java.lang.Long;!java.**;java.lang.*", false },
+                new Object[] { Long.MAX_VALUE, "java.lang.Long;java.lang.Number;!java.**;java.lang.*", true },
+        };
+    }
+
+    /**
+     * Test:
+     *   "global filter reject" + "specific ObjectInputStream filter is empty" => should reject
+     *   "global filter reject" + "specific ObjectInputStream filter allow"    => should allow
+     */
+    @Test(dataProvider="Patterns")
+    public void testRejectedInGlobal(Object toDeserialized, String pattern, boolean allowed) throws Exception {
+        byte[] bytes = SerialFilterTest.writeObjects(toDeserialized);
+        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ois.setObjectInputFilter(filter);
+            Object o = ois.readObject();
+            assertTrue(allowed, "filter should have thrown an exception");
+        } catch (InvalidClassException ice) {
+            assertFalse(allowed, "filter should have thrown an exception");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputFilter;
+import java.io.ObjectInputStream;
+import java.security.AccessControlException;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+/* @test
+ * @build FilterWithSecurityManagerTest SerialFilterTest
+ * @run testng/othervm FilterWithSecurityManagerTest
+ * @run testng/othervm/policy=security.policy.without.globalFilter
+ *          -Djava.security.manager=default FilterWithSecurityManagerTest
+ * @run testng/othervm/policy=security.policy
+ *          -Djava.security.manager=default
+ *          -Djdk.serialFilter=java.lang.Integer FilterWithSecurityManagerTest
+ *
+ * @summary Test that setting specific filter is checked by security manager,
+ *          setting process-wide filter is checked by security manager.
+ */
+
+@Test
+public class FilterWithSecurityManagerTest {
+
+    byte[] bytes;
+    boolean setSecurityManager;
+    ObjectInputFilter filter;
+
+    @BeforeClass
+    public void setup() throws Exception {
+        setSecurityManager = System.getSecurityManager() != null;
+        Object toDeserialized = Long.MAX_VALUE;
+        bytes = SerialFilterTest.writeObjects(toDeserialized);
+        filter = ObjectInputFilter.Config.createFilter("java.lang.Long");
+    }
+
+    /**
+     * Test that setting process-wide filter is checked by security manager.
+     */
+    @Test
+    public void testGlobalFilter() throws Exception {
+        if (ObjectInputFilter.Config.getSerialFilter() == null) {
+            return;
+        }
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ObjectInputFilter.Config.setSerialFilter(filter);
+            assertFalse(setSecurityManager,
+                    "When SecurityManager exists, without "
+                    + "java.security.SerializablePermission(serialFilter) Exception should be thrown");
+            Object o = ois.readObject();
+        } catch (AccessControlException ex) {
+            assertTrue(setSecurityManager);
+            assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
+            assertTrue(ex.getMessage().contains("serialFilter"));
+        }
+    }
+
+    /**
+     * Test that setting specific filter is checked by security manager.
+     */
+    @Test(dependsOnMethods = { "testGlobalFilter" })
+    public void testSpecificFilter() throws Exception {
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ois.setObjectInputFilter(filter);
+            Object o = ois.readObject();
+        } catch (AccessControlException ex) {
+            assertTrue(setSecurityManager);
+            assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
+            assertTrue(ex.getMessage().contains("serialFilter"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.ObjectInputStream;
+
+import java.io.SerializablePermission;
+import java.security.Security;
+import java.util.Objects;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+/* @test
+ * @build GlobalFilterTest SerialFilterTest
+ * @run testng/othervm GlobalFilterTest
+ * @run testng/othervm -Djdk.serialFilter=java.** GlobalFilterTest
+ * @run testng/othervm/policy=security.policy GlobalFilterTest
+ * @run testng/othervm/policy=security.policy
+ *        -Djava.security.properties=${test.src}/java.security-extra1
+ *        -Djava.security.debug=properties GlobalFilterTest
+ *
+ * @summary Test Global Filters
+ */
+@Test
+public class GlobalFilterTest {
+
+    /**
+     * DataProvider of patterns and objects derived from the configured process-wide filter.
+     * @return Array of arrays of pattern, object, allowed boolean, and API factory
+     */
+    @DataProvider(name="globalPatternElements")
+    Object[][] globalPatternElements() {
+        String globalFilter =
+                System.getProperty("jdk.serialFilter",
+                        Security.getProperty("jdk.serialFilter"));
+        if (globalFilter == null) {
+            return new Object[0][];
+        }
+
+        String[] patterns = globalFilter.split(";");
+        Object[][] objects = new Object[patterns.length][];
+
+        for (int i = 0; i < patterns.length; i++) {
+            Object o;
+            boolean allowed;
+            String pattern = patterns[i].trim();
+            if (pattern.contains("=")) {
+                allowed = false;
+                o = SerialFilterTest.genTestObject(pattern, false);
+            } else {
+                allowed = !pattern.startsWith("!");
+                o = (allowed)
+                    ? SerialFilterTest.genTestObject(pattern, true)
+                    : SerialFilterTest.genTestObject(pattern.substring(1), false);
+
+                Assert.assertNotNull(o, "fail generation failed");
+            }
+            objects[i] = new Object[3];
+            objects[i][0] = pattern;
+            objects[i][1] = allowed;
+            objects[i][2] = o;
+        }
+        return objects;
+    }
+
+    /**
+     * Test that the process-wide filter is set when the properties are set
+     * and has the toString matching the configured pattern.
+     */
+    @Test()
+    static void globalFilter() {
+        String pattern =
+                System.getProperty("jdk.serialFilter",
+                        Security.getProperty("jdk.serialFilter"));
+        ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
+        System.out.printf("global pattern: %s, filter: %s%n", pattern, filter);
+        Assert.assertEquals(pattern, Objects.toString(filter, null),
+                "process-wide filter pattern does not match");
+    }
+
+    /**
+     * If the Global filter is already set, it should always refuse to be
+     * set again.
+     * If there is a security manager, setting the serialFilter should fail
+     * without the appropriate permission.
+     * If there is no security manager then setting it should work.
+     */
+    @Test()
+    static void setGlobalFilter() {
+        SecurityManager sm = System.getSecurityManager();
+        ObjectInputFilter filter = new SerialFilterTest.Validator();
+        ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
+        if (global != null) {
+            // once set, can never be re-set
+            try {
+                ObjectInputFilter.Config.setSerialFilter(filter);
+                Assert.fail("set only once process-wide filter");
+            } catch (IllegalStateException ise) {
+                if (sm != null) {
+                    Assert.fail("wrong exception when security manager is set", ise);
+                }
+            } catch (SecurityException se) {
+                if (sm == null) {
+                    Assert.fail("wrong exception when security manager is not set", se);
+                }
+            }
+        } else {
+            if (sm == null) {
+                // no security manager
+                try {
+                    ObjectInputFilter.Config.setSerialFilter(filter);
+                    // Note once set, it can not be reset; so other tests
+                    System.out.printf("Global Filter set to Validator%n");
+                } catch (SecurityException se) {
+                    Assert.fail("setGlobalFilter should not get SecurityException", se);
+                }
+                try {
+                    // Try to set it again, expecting it to throw
+                    ObjectInputFilter.Config.setSerialFilter(filter);
+                    Assert.fail("set only once process-wide filter");
+                } catch (IllegalStateException ise) {
+                    // Normal case
+                }
+            } else {
+                // Security manager
+                SecurityException expectSE = null;
+                try {
+                    sm.checkPermission(new SerializablePermission("serialFilter"));
+                } catch (SecurityException se1) {
+                    expectSE = se1;
+                }
+                SecurityException actualSE = null;
+                try {
+                    ObjectInputFilter.Config.setSerialFilter(filter);
+                } catch (SecurityException se2) {
+                    actualSE = se2;
+                }
+                if (expectSE == null | actualSE == null) {
+                    Assert.assertEquals(expectSE, actualSE, "SecurityException");
+                } else {
+                    Assert.assertEquals(expectSE.getClass(), actualSE.getClass(),
+                            "SecurityException class");
+                }
+            }
+        }
+    }
+
+    /**
+     * For each pattern in the process-wide filter test a generated object
+     * against the default process-wide filter.
+     *
+     * @param pattern a pattern extracted from the configured global pattern
+     */
+    @Test(dataProvider = "globalPatternElements")
+    static void globalFilterElements(String pattern, boolean allowed,Object obj) {
+        testGlobalPattern(pattern, obj, allowed);
+    }
+
+    /**
+     * Serialize and deserialize an object using the default process-wide filter
+     * and check allowed or reject.
+     *
+     * @param pattern the pattern
+     * @param object the test object
+     * @param allowed the expected result from ObjectInputStream (exception or not)
+     */
+    static void testGlobalPattern(String pattern, Object object, boolean allowed) {
+        try {
+//            System.out.printf("global %s pattern: %s, obj: %s%n", (allowed ? "allowed" : "not allowed"), pattern, object);
+            byte[] bytes = SerialFilterTest.writeObjects(object);
+            try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                 ObjectInputStream ois = new ObjectInputStream(bais)) {
+                Object o = ois.readObject();
+            } catch (EOFException eof) {
+                // normal completion
+            } catch (ClassNotFoundException cnf) {
+                Assert.fail("Deserializing", cnf);
+            }
+            Assert.assertTrue(allowed, "filter should have thrown an exception");
+        } catch (IllegalArgumentException iae) {
+            Assert.fail("bad format pattern", iae);
+        } catch (InvalidClassException ice) {
+            Assert.assertFalse(allowed, "filter should not have thrown an exception: " + ice);
+        } catch (IOException ioe) {
+            Assert.fail("Unexpected IOException", ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/MixedFiltersTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.security.Security;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/* @test
+ * @build MixedFiltersTest SerialFilterTest
+ * @run testng/othervm -Djdk.serialFilter=!java.**;!java.lang.Long;maxdepth=5;maxarray=5;maxbytes=90;maxrefs=5          MixedFiltersTest
+ * @run testng/othervm -Djdk.serialFilter=java.**;java.lang.Long;maxdepth=1000;maxarray=1000;maxbytes=1000;maxrefs=1000 MixedFiltersTest
+ *
+ * @summary Test that when both global filter and specific filter are set,
+ *          global filter will not affect specific filter.
+ */
+
+public class MixedFiltersTest implements Serializable {
+
+    private static final long serialVersionUID = 1234567890L;
+
+
+    boolean globalRejected;
+
+    @BeforeClass
+    public void setup() {
+        String pattern = System.getProperty("jdk.serialFilter",
+                Security.getProperty("jdk.serialFilter"));
+        globalRejected = pattern.startsWith("!");
+    }
+
+    @DataProvider(name="RejectedInGlobal")
+    Object[][] rejectedInGlobal() {
+        if (!globalRejected) {
+            return new Object[0][];
+        }
+        return new Object[][] {
+                new Object[] { Long.MAX_VALUE, "java.**" },
+                new Object[] { Long.MAX_VALUE, "java.lang.Long" },
+                new Object[] { SerialFilterTest.genTestObject("java.lang.**", true), "java.lang.**" },
+                new Object[] { SerialFilterTest.genTestObject("maxdepth=10", true), "maxdepth=100" },
+                new Object[] { SerialFilterTest.genTestObject("maxarray=10", true), "maxarray=100" },
+                new Object[] { SerialFilterTest.genTestObject("maxbytes=100", true), "maxbytes=1000" },
+                new Object[] { SerialFilterTest.genTestObject("maxrefs=10", true), "maxrefs=100" },
+        };
+    }
+
+    /**
+     * Test:
+     *   "global filter reject" + "specific ObjectInputStream filter is empty" => should reject
+     *   "global filter reject" + "specific ObjectInputStream filter allow"    => should allow
+     */
+    @Test(dataProvider="RejectedInGlobal")
+    public void testRejectedInGlobal(Object toDeserialized, String pattern) throws Exception {
+        byte[] bytes = SerialFilterTest.writeObjects(toDeserialized);
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            Object o = ois.readObject();
+            fail("filter should have thrown an exception");
+        } catch (InvalidClassException expected) { }
+
+        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ois.setObjectInputFilter(filter);
+            Object o = ois.readObject();
+        }
+    }
+
+    @DataProvider(name="AllowedInGlobal")
+    Object[][] allowedInGlobal() {
+        if (globalRejected) {
+            return new Object[0][];
+        }
+
+        return new Object[][] {
+                new Object[] { Long.MAX_VALUE, "!java.**" },
+                new Object[] { Long.MAX_VALUE, "!java.lang.Long" },
+                new Object[] { SerialFilterTest.genTestObject("java.lang.**", true), "!java.lang.**" },
+                new Object[] { SerialFilterTest.genTestObject("maxdepth=10", true), "maxdepth=5" },
+                new Object[] { SerialFilterTest.genTestObject("maxarray=10", true), "maxarray=5" },
+                new Object[] { SerialFilterTest.genTestObject("maxbytes=100", true), "maxbytes=5" },
+                new Object[] { SerialFilterTest.genTestObject("maxrefs=10", true), "maxrefs=5" },
+            };
+    }
+
+    /**
+     * Test:
+     *   "global filter allow" + "specific ObjectInputStream filter is empty" => should allow
+     *   "global filter allow" + "specific ObjectInputStream filter reject"   => should reject
+     */
+    @Test(dataProvider="AllowedInGlobal")
+    public void testAllowedInGlobal(Object toDeserialized, String pattern) throws Exception {
+        byte[] bytes = SerialFilterTest.writeObjects(toDeserialized);
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            Object o = ois.readObject();
+        }
+
+        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ois.setObjectInputFilter(filter);
+            Object o = ois.readObject();
+            assertTrue(false, "filter should have thrown an exception");
+        } catch (InvalidClassException expected) { }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/SerialFilterTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,752 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.ObjectInputStream;
+import java.io.ObjectInputFilter;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.invoke.SerializedLambda;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.concurrent.atomic.LongAdder;
+
+import javax.lang.model.SourceVersion;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+/* @test
+ * @build SerialFilterTest
+ * @run testng/othervm  SerialFilterTest
+ *
+ * @summary Test ObjectInputFilters
+ */
+@Test
+public class SerialFilterTest implements Serializable {
+
+    private static final long serialVersionUID = -6999613679881262446L;
+
+    /**
+     * Enable three arg lambda.
+     * @param <T> The pattern
+     * @param <U> The test object
+     * @param <V> Boolean for if the filter should allow or reject
+     */
+    interface TriConsumer< T, U, V> {
+        void accept(T t, U u, V v);
+    }
+
+    /**
+     * Misc object to use that should always be accepted.
+     */
+    private static final Object otherObject = Integer.valueOf(0);
+
+    /**
+     * DataProvider for the individual patterns to test.
+     * Expand the patterns into cases for each of the Std and Compatibility APIs.
+     * @return an array of arrays of the parameters including factories
+     */
+    @DataProvider(name="Patterns")
+    static Object[][] patterns() {
+        Object[][] patterns = new Object[][]{
+                {"java.util.Hashtable"},
+                {"java.util.Hash*"},
+                {"javax.lang.model.*"},
+                {"javax.lang.**"},
+                {"*"},
+                {"maxarray=47"},
+                {"maxdepth=5"},
+                {"maxrefs=10"},
+                {"maxbytes=100"},
+                {"maxbytes=72"},
+                {"maxbytes=+1024"},
+                {"java.base/java.util.Hashtable"},
+        };
+        return patterns;
+    }
+
+    @DataProvider(name="InvalidPatterns")
+    static Object[][] invalidPatterns() {
+        return new Object [][] {
+                {"maxrefs=-1"},
+                {"maxdepth=-1"},
+                {"maxbytes=-1"},
+                {"maxarray=-1"},
+                {"xyz=0"},
+                {"xyz=-1"},
+                {"maxrefs=0xabc"},
+                {"maxrefs=abc"},
+                {"maxrefs="},
+                {"maxrefs=+"},
+                {".*"},
+                {".**"},
+                {"!"},
+                {"/java.util.Hashtable"},
+                {"java.base/"},
+                {"/"},
+        };
+    }
+
+    @DataProvider(name="Limits")
+    static Object[][] limits() {
+        // The numbers are arbitrary > 1
+        return new Object[][]{
+                {"maxrefs", 10},
+                {"maxdepth", 5},
+                {"maxbytes", 100},
+                {"maxarray", 16},
+        };
+    }
+
+    /**
+     * DataProvider of individual objects. Used to check the information
+     * available to the filter.
+     * @return  Arrays of parameters with objects
+     */
+    @DataProvider(name="Objects")
+    static Object[][] objects() {
+        byte[] byteArray = new byte[0];
+        Object[] objArray = new Object[7];
+        objArray[objArray.length - 1] = objArray;
+
+        Class<?> serClass = null;
+        String className = "java.util.concurrent.atomic.LongAdder$SerializationProxy";
+        try {
+            serClass = Class.forName(className);
+        } catch (Exception e) {
+            Assert.fail("missing class: " + className, e);
+        }
+
+        Class<?>[] interfaces = {Runnable.class};
+        Runnable proxy = (Runnable) Proxy.newProxyInstance(null,
+                interfaces, (p, m, args) -> p);
+
+        Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop;
+        Object[][] objects = {
+                { null, 0, -1, 0, 0, 0,
+                        new HashSet<>()},        // no callback, no values
+                { objArray, 3, 7, 8, 2, 55,
+                        new HashSet<>(Arrays.asList(objArray.getClass()))},
+                { Object[].class, 1, -1, 1, 1, 40,
+                        new HashSet<>(Arrays.asList(Object[].class))},
+                { new SerialFilterTest(), 1, -1, 1, 1, 37,
+                        new HashSet<>(Arrays.asList(SerialFilterTest.class))},
+                { new LongAdder(), 2, -1, 1, 1, 93,
+                        new HashSet<>(Arrays.asList(LongAdder.class, serClass))},
+                { new byte[14], 2, 14, 1, 1, 27,
+                        new HashSet<>(Arrays.asList(byteArray.getClass()))},
+                { runnable, 13, 0, 10, 2, 514,
+                        new HashSet<>(Arrays.asList(java.lang.invoke.SerializedLambda.class,
+                                SerialFilterTest.class,
+                                objArray.getClass()))},
+                { deepHashSet(10), 48, -1, 49, 11, 619,
+                        new HashSet<>(Arrays.asList(HashSet.class))},
+                { proxy.getClass(), 3, -1, 1, 1, 114,
+                        new HashSet<>(Arrays.asList(Runnable.class,
+                                java.lang.reflect.Proxy.class))},
+        };
+        return objects;
+    }
+
+    @DataProvider(name="Arrays")
+    static Object[][] arrays() {
+        return new Object[][]{
+                {new Object[16], 16},
+                {new boolean[16], 16},
+                {new byte[16], 16},
+                {new char[16], 16},
+                {new int[16], 16},
+                {new long[16], 16},
+                {new short[16], 16},
+                {new float[16], 16},
+                {new double[16], 16},
+        };
+    }
+
+
+    /**
+     * Test each object and verify the classes identified by the filter,
+     * the count of calls to the filter, the max array size, max refs, max depth,
+     * max bytes.
+     * This test ignores/is not dependent on the global filter settings.
+     *
+     * @param object a Serializable object
+     * @param count the expected count of calls to the filter
+     * @param maxArray the maximum array size
+     * @param maxRefs the maximum references
+     * @param maxDepth the maximum depth
+     * @param maxBytes the maximum stream size
+     * @param classes  the expected (unique) classes
+     * @throws IOException
+     */
+    @Test(dataProvider="Objects")
+    public static void t1(Object object,
+                          long count, long maxArray, long maxRefs, long maxDepth, long maxBytes,
+                          Set<Class<?>> classes) throws IOException {
+        byte[] bytes = writeObjects(object);
+        Validator validator = new Validator();
+        validate(bytes, validator);
+        System.out.printf("v: %s%n", validator);
+        Assert.assertEquals(validator.count, count, "callback count wrong");
+        Assert.assertEquals(validator.classes, classes, "classes mismatch");
+        Assert.assertEquals(validator.maxArray, maxArray, "maxArray mismatch");
+        Assert.assertEquals(validator.maxRefs, maxRefs, "maxRefs wrong");
+        Assert.assertEquals(validator.maxDepth, maxDepth, "depth wrong");
+        Assert.assertEquals(validator.maxBytes, maxBytes, "maxBytes wrong");
+    }
+
+    /**
+     * Test each pattern with an appropriate object.
+     * A filter is created from the pattern and used to serialize and
+     * deserialize a generated object with both the positive and negative case.
+     * This test ignores/is not dependent on the global filter settings.
+     *
+     * @param pattern a pattern
+     */
+    @Test(dataProvider="Patterns")
+    static void testPatterns(String pattern) {
+        evalPattern(pattern, (p, o, neg) -> testPatterns(p, o, neg));
+    }
+
+    /**
+     * Test that the filter on a OIS can be set only on a fresh OIS,
+     * before deserializing any objects.
+     * This test is agnostic the global filter being set or not.
+     */
+    @Test
+    static void nonResettableFilter() {
+        Validator validator1 = new Validator();
+        Validator validator2 = new Validator();
+
+        try {
+            byte[] bytes = writeObjects("text1");    // an object
+
+            try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                 ObjectInputStream ois = new ObjectInputStream(bais)) {
+                // Check the initial filter is the global filter; may be null
+                ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
+                ObjectInputFilter initial = ois.getObjectInputFilter();
+                Assert.assertEquals(global, initial, "initial filter should be the global filter");
+
+                // Check if it can be set to null
+                ois.setObjectInputFilter(null);
+                ObjectInputFilter filter = ois.getObjectInputFilter();
+                Assert.assertNull(filter, "set to null should be null");
+
+                ois.setObjectInputFilter(validator1);
+                Object o = ois.readObject();
+                try {
+                    ois.setObjectInputFilter(validator2);
+                    Assert.fail("Should not be able to set filter twice");
+                } catch (IllegalStateException ise) {
+                    // success, the exception was expected
+                }
+            } catch (EOFException eof) {
+                Assert.fail("Should not reach end-of-file", eof);
+            } catch (ClassNotFoundException cnf) {
+                Assert.fail("Deserializing", cnf);
+            }
+        } catch (IOException ex) {
+            Assert.fail("Unexpected IOException", ex);
+        }
+    }
+
+    /**
+     * Test that if an Objects readReadResolve method returns an array
+     * that the callback to the filter includes the proper array length.
+     * @throws IOException if an error occurs
+     */
+    @Test(dataProvider="Arrays")
+    static void testReadResolveToArray(Object array, int length) throws IOException {
+        ReadResolveToArray object = new ReadResolveToArray(array, length);
+        byte[] bytes = writeObjects(object);
+        Object o = validate(bytes, object);    // the object is its own filter
+        Assert.assertEquals(o.getClass(), array.getClass(), "Filter not called with the array");
+    }
+
+
+    /**
+     * Test repeated limits use the last value.
+     * Construct a filter with the limit and the limit repeated -1.
+     * Invoke the filter with the limit to make sure it is rejected.
+     * Invoke the filter with the limit -1 to make sure it is accepted.
+     * @param name the name of the limit to test
+     * @param value a test value
+     */
+    @Test(dataProvider="Limits")
+    static void testLimits(String name, int value) {
+        Class<?> arrayClass = new int[0].getClass();
+        String pattern = String.format("%s=%d;%s=%d", name, value, name, value - 1);
+        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+        Assert.assertEquals(
+                filter.checkInput(new FilterValues(arrayClass, value, value, value, value)),
+                ObjectInputFilter.Status.REJECTED,
+                "last limit value not used: " + filter);
+        Assert.assertEquals(
+                filter.checkInput(new FilterValues(arrayClass, value-1, value-1, value-1, value-1)),
+                ObjectInputFilter.Status.UNDECIDED,
+                "last limit value not used: " + filter);
+    }
+
+    /**
+     * Test that returning null from a filter causes deserialization to fail.
+     */
+    @Test(expectedExceptions=InvalidClassException.class)
+    static void testNullStatus() throws IOException {
+        byte[] bytes = writeObjects(0); // an Integer
+        try {
+            Object o = validate(bytes, new ObjectInputFilter() {
+                public ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo f) {
+                    return null;
+                }
+            });
+        } catch (InvalidClassException ice) {
+            System.out.printf("Success exception: %s%n", ice);
+            throw ice;
+        }
+    }
+
+    /**
+     * Verify that malformed patterns throw IAE.
+     * @param pattern pattern from the data source
+     */
+    @Test(dataProvider="InvalidPatterns", expectedExceptions=IllegalArgumentException.class)
+    static void testInvalidPatterns(String pattern) {
+        try {
+            ObjectInputFilter.Config.createFilter(pattern);
+        } catch (IllegalArgumentException iae) {
+            System.out.printf("    success exception: %s%n", iae);
+            throw iae;
+        }
+    }
+
+    /**
+     * Test that Config.create returns null if the argument does not contain any patterns or limits.
+     */
+    @Test()
+    static void testEmptyPattern() {
+        ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("");
+        Assert.assertNull(filter, "empty pattern did not return null");
+
+        filter = ObjectInputFilter.Config.createFilter(";;;;");
+        Assert.assertNull(filter, "pattern with only delimiters did not return null");
+    }
+
+    /**
+     * Read objects from the serialized stream, validated with the filter.
+     *
+     * @param bytes a byte array to read objects from
+     * @param filter the ObjectInputFilter
+     * @return the object deserialized if any
+     * @throws IOException can be thrown
+     */
+    static Object validate(byte[] bytes,
+                         ObjectInputFilter filter) throws IOException {
+        try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+             ObjectInputStream ois = new ObjectInputStream(bais)) {
+            ois.setObjectInputFilter(filter);
+
+            Object o = ois.readObject();
+            return o;
+        } catch (EOFException eof) {
+            // normal completion
+        } catch (ClassNotFoundException cnf) {
+            Assert.fail("Deserializing", cnf);
+        }
+        return null;
+    }
+
+    /**
+     * Write objects and return a byte array with the bytes.
+     *
+     * @param objects zero or more objects to serialize
+     * @return the byte array of the serialized objects
+     * @throws IOException if an exception occurs
+     */
+    static byte[] writeObjects(Object... objects)  throws IOException {
+        byte[] bytes;
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+             ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+            for (Object o : objects) {
+                oos.writeObject(o);
+            }
+            bytes = baos.toByteArray();
+        }
+        return bytes;
+    }
+
+    /**
+     * A filter that accumulates information about the checkInput callbacks
+     * that can be checked after readObject completes.
+     */
+    static class Validator implements ObjectInputFilter {
+        long count;          // Count of calls to checkInput
+        HashSet<Class<?>> classes = new HashSet<>();
+        long maxArray = -1;
+        long maxRefs;
+        long maxDepth;
+        long maxBytes;
+
+        Validator() {
+        }
+
+        @Override
+        public ObjectInputFilter.Status checkInput(FilterInfo filter) {
+            count++;
+            if (filter.serialClass() != null) {
+                if (filter.serialClass().getName().contains("$$Lambda$")) {
+                    // TBD: proper identification of serialized Lambdas?
+                    // Fold the serialized Lambda into the SerializedLambda type
+                    classes.add(SerializedLambda.class);
+                } else if (Proxy.isProxyClass(filter.serialClass())) {
+                    classes.add(Proxy.class);
+                } else {
+                    classes.add(filter.serialClass());
+                }
+
+            }
+            this.maxArray = Math.max(this.maxArray, filter.arrayLength());
+            this.maxRefs = Math.max(this.maxRefs, filter.references());
+            this.maxDepth = Math.max(this.maxDepth, filter.depth());
+            this.maxBytes = Math.max(this.maxBytes, filter.streamBytes());
+            return ObjectInputFilter.Status.UNDECIDED;
+        }
+
+        public String toString(){
+            return "count: " + count
+                    + ", classes: " + classes.toString()
+                    + ", maxArray: " + maxArray
+                    + ", maxRefs: " + maxRefs
+                    + ", maxDepth: " + maxDepth
+                    + ", maxBytes: " + maxBytes;
+        }
+    }
+
+
+    /**
+     * Create a filter from a pattern and API factory, then serialize and
+     * deserialize an object and check allowed or reject.
+     *
+     * @param pattern the pattern
+     * @param object the test object
+     * @param allowed the expected result from ObjectInputStream (exception or not)
+     */
+    static void testPatterns(String pattern, Object object, boolean allowed) {
+        try {
+            byte[] bytes = SerialFilterTest.writeObjects(object);
+            ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(pattern);
+            validate(bytes, filter);
+            Assert.assertTrue(allowed, "filter should have thrown an exception");
+        } catch (IllegalArgumentException iae) {
+            Assert.fail("bad format pattern", iae);
+        } catch (InvalidClassException ice) {
+            Assert.assertFalse(allowed, "filter should not have thrown an exception: " + ice);
+        } catch (IOException ioe) {
+            Assert.fail("Unexpected IOException", ioe);
+        }
+    }
+
+    /**
+     * For a filter pattern, generate and apply a test object to the action.
+     * @param pattern a pattern
+     * @param action an action to perform on positive and negative cases
+     */
+    static void evalPattern(String pattern, TriConsumer<String, Object, Boolean> action) {
+        Object o = genTestObject(pattern, true);
+        Assert.assertNotNull(o, "success generation failed");
+        action.accept(pattern, o, true);
+
+        // Test the negative pattern
+        o = genTestObject(pattern, false);
+        Assert.assertNotNull(o, "fail generation failed");
+        String negPattern = pattern.contains("=") ? pattern : "!" + pattern;
+        action.accept(negPattern, o, false);
+    }
+
+    /**
+     * Generate a test object based on the pattern.
+     * Handles each of the forms of the pattern, wildcards,
+     * class name, various limit forms.
+     * @param pattern a pattern
+     * @param allowed a boolean indicating to generate the allowed or disallowed case
+     * @return an object or {@code null} to indicate no suitable object could be generated
+     */
+    static Object genTestObject(String pattern, boolean allowed) {
+        if (pattern.contains("=")) {
+            return genTestLimit(pattern, allowed);
+        } else if (pattern.endsWith("*")) {
+            return genTestObjectWildcard(pattern, allowed);
+        } else {
+            // class
+            // isolate module name, if any
+            int poffset = 0;
+            int soffset = pattern.indexOf('/', poffset);
+            String module = null;
+            if (soffset >= 0) {
+                poffset = soffset + 1;
+                module = pattern.substring(0, soffset);
+            }
+            try {
+                Class<?> clazz = Class.forName(pattern.substring(poffset));
+                Constructor<?> cons = clazz.getConstructor();
+                return cons.newInstance();
+            } catch (ClassNotFoundException ex) {
+                Assert.fail("no such class available: " + pattern);
+            } catch (InvocationTargetException
+                    | NoSuchMethodException
+                    | InstantiationException
+                    | IllegalAccessException ex1) {
+                Assert.fail("newInstance: " + ex1);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Generate an object to be used with the various wildcard pattern forms.
+     * Explicitly supports only specific package wildcards with specific objects.
+     * @param pattern a wildcard pattern ending in "*"
+     * @param allowed a boolean indicating to generate the allowed or disallowed case
+     * @return an object within or outside the wildcard
+     */
+    static Object genTestObjectWildcard(String pattern, boolean allowed) {
+        if (pattern.endsWith(".**")) {
+            // package hierarchy wildcard
+            if (pattern.startsWith("javax.lang.")) {
+                return SourceVersion.RELEASE_5;
+            }
+            if (pattern.startsWith("java.")) {
+                return 4;
+            }
+            if (pattern.startsWith("javax.")) {
+                return SourceVersion.RELEASE_6;
+            }
+            return otherObject;
+        } else if (pattern.endsWith(".*")) {
+            // package wildcard
+            if (pattern.startsWith("javax.lang.model")) {
+                return SourceVersion.RELEASE_6;
+            }
+        } else {
+            // class wildcard
+            if (pattern.equals("*")) {
+                return otherObject; // any object will do
+            }
+            if (pattern.startsWith("java.util.Hash")) {
+                return new Hashtable<String, String>();
+            }
+        }
+        Assert.fail("Object could not be generated for pattern: "
+                + pattern
+                + ", allowed: " + allowed);
+        return null;
+    }
+
+    /**
+     * Generate a limit test object for the pattern.
+     * For positive cases, the object exactly hits the limit.
+     * For negative cases, the object is 1 greater than the limit
+     * @param pattern the pattern, containing "=" and a maxXXX keyword
+     * @param allowed a boolean indicating to generate the allowed or disallowed case
+     * @return a sitable object
+     */
+    static Object genTestLimit(String pattern, boolean allowed) {
+        int ndx = pattern.indexOf('=');
+        Assert.assertNotEquals(ndx, -1, "missing value in limit");
+        long value = Long.parseUnsignedLong(pattern.substring(ndx+1));
+        if (pattern.startsWith("maxdepth=")) {
+            // Return an object with the requested depth (or 1 greater)
+            long depth = allowed ? value : value + 1;
+            Object[] array = new Object[1];
+            for (int i = 1; i < depth; i++) {
+                Object[] n = new Object[1];
+                n[0] = array;
+                array = n;
+            }
+            return array;
+        } else if (pattern.startsWith("maxbytes=")) {
+            // Return a byte array that when written to OOS creates
+            // a stream of exactly the size requested.
+            return genMaxBytesObject(allowed, value);
+        } else if (pattern.startsWith("maxrefs=")) {
+            Object[] array = new Object[allowed ? (int)value - 1 : (int)value];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = otherObject;
+            }
+            return array;
+        } else if (pattern.startsWith("maxarray=")) {
+            return allowed ? new int[(int)value] : new int[(int)value+1];
+        }
+        Assert.fail("Object could not be generated for pattern: "
+                + pattern
+                + ", allowed: " + allowed);
+        return null;
+    }
+
+    /**
+     * Generate an an object that will be serialized to some number of bytes.
+     * Or 1 greater if allowed is false.
+     * It returns a two element Object array holding a byte array sized
+     * to achieve the desired total size.
+     * @param allowed true if the stream should be allowed at that size,
+     *                false if the stream should be larger
+     * @param maxBytes the number of bytes desired in the stream;
+     *                 should not be less than 72 (due to protocol overhead).
+     * @return a object that will be serialized to the length requested
+     */
+    private static Object genMaxBytesObject(boolean allowed, long maxBytes) {
+        Object[] holder = new Object[2];
+        long desiredSize = allowed ? maxBytes : maxBytes + 1;
+        long actualSize = desiredSize;
+        long byteSize = desiredSize - 72;  // estimate needed array size
+        do {
+            byteSize += (desiredSize - actualSize);
+            byte[] a = new byte[(int)byteSize];
+            holder[0] = a;
+            holder[1] = a;
+            try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                 ObjectOutputStream os = new ObjectOutputStream(baos)) {
+                os.writeObject(holder);
+                os.flush();
+                actualSize = baos.size();
+            } catch (IOException ie) {
+                Assert.fail("exception generating stream", ie);
+            }
+        } while (actualSize != desiredSize);
+        return holder;
+    }
+
+    /**
+     * Returns a HashSet of a requested depth.
+     * @param depth the depth
+     * @return a HashSet of HashSets...
+     */
+    static HashSet<Object> deepHashSet(int depth) {
+        HashSet<Object> hashSet = new HashSet<>();
+        HashSet<Object> s1 = hashSet;
+        HashSet<Object> s2 = new HashSet<>();
+        for (int i = 0; i < depth; i++ ) {
+            HashSet<Object> t1 = new HashSet<>();
+            HashSet<Object> t2 = new HashSet<>();
+            // make t1 not equal to t2
+            t1.add("by Jimminy");
+            s1.add(t1);
+            s1.add(t2);
+            s2.add(t1);
+            s2.add(t2);
+            s1 = t1;
+            s2 = t2;
+        }
+        return hashSet;
+    }
+
+    /**
+     * Simple method to use with Serialized Lambda.
+     */
+    private static void noop() {}
+
+
+    /**
+     * Class that returns an array from readResolve and also implements
+     * the ObjectInputFilter to check that it has the expected length.
+     */
+    static class ReadResolveToArray implements Serializable, ObjectInputFilter {
+        private static final long serialVersionUID = 123456789L;
+
+        private final Object array;
+        private final int length;
+
+        ReadResolveToArray(Object array, int length) {
+            this.array = array;
+            this.length = length;
+        }
+
+        Object readResolve() {
+            return array;
+        }
+
+        @Override
+        public ObjectInputFilter.Status checkInput(FilterInfo filter) {
+            if (ReadResolveToArray.class.isAssignableFrom(filter.serialClass())) {
+                return ObjectInputFilter.Status.ALLOWED;
+            }
+            if (filter.serialClass() != array.getClass() ||
+                    (filter.arrayLength() >= 0 && filter.arrayLength() != length)) {
+                return ObjectInputFilter.Status.REJECTED;
+            }
+            return ObjectInputFilter.Status.UNDECIDED;
+        }
+
+    }
+
+    /**
+     * Hold a snapshot of values to be passed to an ObjectInputFilter.
+     */
+    static class FilterValues implements ObjectInputFilter.FilterInfo {
+        private final Class<?> clazz;
+        private final long arrayLength;
+        private final long depth;
+        private final long references;
+        private final long streamBytes;
+
+        public FilterValues(Class<?> clazz, long arrayLength, long depth, long references, long streamBytes) {
+            this.clazz = clazz;
+            this.arrayLength = arrayLength;
+            this.depth = depth;
+            this.references = references;
+            this.streamBytes = streamBytes;
+        }
+
+        @Override
+        public Class<?> serialClass() {
+            return clazz;
+        }
+
+        public long arrayLength() {
+            return arrayLength;
+        }
+
+        public long depth() {
+            return depth;
+        }
+
+        public long references() {
+            return references;
+        }
+
+        public long streamBytes() {
+            return streamBytes;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/java.security-extra1	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,4 @@
+# Serialization Input Process-wide Filter
+# See conf/security/java.security for pattern synatx
+#
+jdk.serialFilter=java.**;javax.**;maxarray=34;maxdepth=7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,12 @@
+// Individual Permissions to for GlobalFilterTest
+grant {
+        // Specific permission under test
+        permission java.security.SerializablePermission "serialFilter";
+        // Permissions needed to run the test
+        permission java.util.PropertyPermission "*", "read";
+        permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
+        permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+        permission java.security.SecurityPermission "*";
+        permission java.lang.RuntimePermission "accessDeclaredMembers";
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy.without.globalFilter	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,9 @@
+// Individual Permissions for FilterWithSecurityManagerTest
+grant {
+        // Permissions needed to run the test
+        permission java.util.PropertyPermission "*", "read";
+        permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
+        permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+        permission java.lang.RuntimePermission "accessDeclaredMembers";
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/forNameLeak/ClassForName.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.URLClassLoader;
+
+/*
+ * This class is loaded by the custom URLClassLoader, and then calls
+ * Class.forName();
+ */
+public class ClassForName implements Runnable {
+    static {
+        if (!(ClassForName.class.getClassLoader() instanceof URLClassLoader)) {
+            throw new RuntimeException("Supposed to be loaded by URLClassLoader");
+        }
+    }
+
+    public void run() {
+        try {
+            Class.forName(java.util.List.class.getName(), false,
+                          ClassLoader.getSystemClassLoader());
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/forNameLeak/ClassForNameLeak.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151486
+ * @summary Call Class.forName() on the system classloader from a class loaded
+ *          from a custom classloader.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.Utils JarUtils
+ * @build ClassForName ClassForNameLeak
+ * @run main/othervm/policy=test.policy -Djava.security.manager ClassForNameLeak
+ */
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import jdk.testlibrary.Utils;
+
+/*
+ * Create .jar, load ClassForName from .jar using a URLClassLoader
+ */
+public class ClassForNameLeak {
+    private static final long TIMEOUT = (long)(5000.0 * Utils.TIMEOUT_FACTOR);
+    private static final String TESTCLASSES = System.getProperty("test.classes", ".");
+    private static final String CLASSFILENAME = "ClassForName.class";
+    private static final int THREADS = 10;
+    private static final ReferenceQueue<ClassLoader> rq = new ReferenceQueue<>();
+
+    // Use a new classloader to load the ClassForName class, then run its
+    // Runnable.
+    public static PhantomReference<ClassLoader> loadAndRun(Path jarFilePath)
+            throws Exception {
+        ClassLoader classLoader = new URLClassLoader(
+                new URL[]{jarFilePath.toUri().toURL()}) {
+            @Override public String toString() { return "LeakedClassLoader"; }
+        };
+
+        Class<?> loadClass = Class.forName("ClassForName", true, classLoader);
+        ((Runnable) loadClass.newInstance()).run();
+
+        PhantomReference<ClassLoader> ref = new PhantomReference<>(classLoader, rq);
+        System.out.println("returning phantom ref: " + ref + " to " + classLoader);
+        return ref;
+    }
+
+    public static void main(final String[] args) throws Exception {
+        // Create a temporary .jar file containing ClassForName.class
+        Path testClassesDir = Paths.get(TESTCLASSES);
+        Path jarFilePath = Files.createTempFile("cfn", ".jar");
+        JarUtils.createJarFile(jarFilePath, testClassesDir, CLASSFILENAME);
+        jarFilePath.toFile().deleteOnExit();
+
+        // Remove the ClassForName.class file that jtreg built, to make sure
+        // we're loading from the tmp .jar
+        Path classFile = FileSystems.getDefault().getPath(TESTCLASSES,
+                                                          CLASSFILENAME);
+        Files.delete(classFile);
+
+        // Make simultaneous calls to the test method, to stress things a bit
+        ExecutorService es = Executors.newFixedThreadPool(THREADS);
+
+        List<Callable<PhantomReference<ClassLoader>>> callables =
+                Stream.generate(() -> {
+                    Callable<PhantomReference<ClassLoader>> cprcl = () -> {
+                        return loadAndRun(jarFilePath);
+                    };
+                    return cprcl;
+                }).limit(THREADS).collect(Collectors.toList());
+
+        List<Future<PhantomReference<ClassLoader>>> refs = es.invokeAll(callables);
+
+        // Give the GC a chance to enqueue the PhantomReferences
+        for (int i = 0; i < 10; i++) {
+            System.gc();
+        }
+        // Make sure all PhantomReferences to the leaked classloader are enqueued
+        for (int j = 0; j < THREADS; j++) {
+            Reference rmRef = rq.remove(TIMEOUT);
+            if (rmRef == null) {
+                throw new RuntimeException("ClassLoader was never enqueued!");
+            } else {
+                System.out.println("Enqueued " + rmRef);
+            }
+        }
+        System.out.println("All Classloaders successfully enqued");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/forNameLeak/test.policy	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,6 @@
+grant {
+  permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete";
+  permission java.lang.RuntimePermission "createClassLoader";
+  permission java.lang.RuntimePermission "getClassLoader";
+  permission java.util.PropertyPermission "*", "read"; /* for Utils */
+};
--- a/jdk/test/java/lang/Math/FusedMultiplyAddTests.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/lang/Math/FusedMultiplyAddTests.java	Mon Oct 10 13:31:48 2016 -0700
@@ -221,6 +221,9 @@
 
             {Double.MIN_VALUE, -0.0, +0.0,
              +0.0},
+
+            {1.0+Math.ulp(1.0), 1.0+Math.ulp(1.0), -1.0-2.0*Math.ulp(1.0),
+             Math.ulp(1.0)*Math.ulp(1.0)},
         };
 
         for (double[] testCase: testCases)
@@ -344,6 +347,9 @@
 
             {Float.MAX_VALUE, 2.0f, 1.0f,
              InfinityF},
+
+            {1.0f+Math.ulp(1.0f), 1.0f+Math.ulp(1.0f), -1.0f-2.0f*Math.ulp(1.0f),
+             Math.ulp(1.0f)*Math.ulp(1.0f)},
         };
 
         for (float[] testCase: testCases)
--- a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,6 +1,6 @@
 /*
  * Copyright 2014 Goldman Sachs.
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,6 +32,7 @@
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-javaagent:DummyAgent.jar", "TestDaemonThread", ".");
             OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
             analyzer.shouldNotContain("ASSERTION FAILED");
+            analyzer.shouldHaveExitValue(0);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/DatagramSocket/ReuseAddressTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,466 @@
+/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MulticastSocket;
+import java.net.SocketException;
+
+/*
+ * @test
+ * @bug 8153674
+ * @summary Expected SocketException not thrown when calling bind() with
+ *   setReuseAddress(false)
+ * @run main/othervm ReuseAddressTest
+ */
+
+public class ReuseAddressTest {
+
+    String getInfo(DatagramSocket soc) {
+        if (soc == null) {
+            return null;
+        }
+
+        return "localPort: " + soc.getLocalPort()
+                + "; localAddress: " + soc.getLocalAddress()
+                + "; remotePort: " + soc.getPort()
+                + "; remoteAddress: " + soc.getInetAddress()
+                + "; isClosed: " + soc.isClosed()
+                + "; isBound: " + soc.isBound();
+    }
+
+    static InetSocketAddress createSocketAddress(int testMcastPort) throws Exception {
+        InetAddress localAddress = InetAddress.getLocalHost();
+        InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress, testMcastPort);
+        return localSocketAddress;
+    }
+
+    /* standalone interface */
+    public static void main(String argv[]) throws Exception {
+        ReuseAddressTest test = new ReuseAddressTest();
+        test.DatagramSocket0029();
+        test.DatagramSocket0030();
+        test.DatagramSocket0031();
+        test.DatagramSocket0032();
+        test.DatagramSocket0034();
+        test.DatagramSocket0035();
+        test.DatagramSocket2028();
+        test.DatagramSocket2029();
+        test.DatagramSocket2030();
+
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setReuseAddress(boolean on) throws SocketException,
+     * <br><b>on</b>: false.
+     * <br><b>Expected results</b>: getReuseAddress() will return false
+     */
+    public void DatagramSocket0029() throws Exception {
+        String testCaseID = "DatagramSocket0029";
+        System.out.println(" >> " + testCaseID + ": " + "public void setReuseAddress(boolean on) throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket(null);
+            ds.setReuseAddress(false);
+            if (ds.getReuseAddress() == true) {
+                throw new RuntimeException("SO_REUSEADDR is not set to false");
+            }
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setReuseAddress(boolean on) throws SocketException,
+     * <br><b>on</b>: true.
+     * <br><b>Expected results</b>: Allows completely duplicate bindings (same
+     * address and port) on multicast sockets
+     */
+    public void DatagramSocket0030() throws Exception {
+        String testCaseID = "DatagramSocket0030";
+        System.out.println(" >> " + testCaseID + ": " + "public void setReuseAddress(boolean on) throws SocketException");
+
+        MulticastSocket ms1 = null;
+        MulticastSocket ms2 = null;
+        try {
+            InetSocketAddress addr = createSocketAddress(5050);
+
+            ms1 = new MulticastSocket(null);
+            ms1.setReuseAddress(true);
+            if (!ms1.getReuseAddress()) {
+                System.out.println("Cannot check: "
+                        + " safety for SO_REUSEADDR option is not guaranteed");
+            }
+
+            try {
+                ms1.bind(addr);
+            } catch (SocketException e) {
+                throw new RuntimeException("cannot bind first socket to " + addr
+                        + " unexpected " + e);
+            }
+
+            ms2 = new MulticastSocket(null);
+            ms2.setReuseAddress(true);
+            if (!ms2.getReuseAddress()) {
+                System.out.println("Cannot check: "
+                        + " safety for SO_REUSEADDR option is not guaranteed");
+            }
+
+            try {
+                ms2.bind(addr);
+            } catch (SocketException e) {
+                throw new RuntimeException("cannot bind second socket to " + addr
+                        + " unexpected " + e);
+            }
+
+            if (ms1.getLocalPort() != addr.getPort() || !ms1.isBound()
+                    || ms2.getLocalPort() != addr.getPort() || !ms2.isBound()) {
+                System.out.println("bind() fails with: " + addr);
+                System.out.println("  ms1 [" + getInfo(ms1) + "]");
+                System.out.println("  ms2 [" + getInfo(ms2) + "]");
+                System.out.println("  getReuseAddress(): " + ms2.getReuseAddress());
+                throw new RuntimeException("bind() fails with: " + addr);
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ms1 != null) {
+                ms1.close();
+            }
+            if (ms2 != null) {
+                ms2.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setReuseAddress(boolean on) throws SocketException,
+     * <br><b>on</b>: false.
+     * <br><b>Expected results</b>: The second bind will throw SocketException,
+     * when SO_REUSEADDR disable
+     */
+    public void DatagramSocket0031() throws Exception {
+        String testCaseID = "DatagramSocket0031";
+        System.out.println(" >> " + testCaseID + ": " + "public void setReuseAddress(boolean on) throws SocketException");
+
+        MulticastSocket ms1 = null;
+        MulticastSocket ms2 = null;
+        try {
+            InetSocketAddress addr = createSocketAddress(6060);
+
+            ms1 = new MulticastSocket(null);
+            try {
+                ms1.bind(addr);
+            } catch (SocketException e) {
+                throw new RuntimeException("cannot bind first socket to " + addr
+                        + " unexpected " + e);
+            }
+
+            ms2 = new MulticastSocket(null);
+            ms2.setReuseAddress(false);  // method under test
+
+            try {
+                ms2.bind(addr);
+                System.out.println("No exceptions: ");
+                System.out.println("  addr: " + addr);
+                System.out.println("  ms1 [" + getInfo(ms1) + "]");
+                System.out.println("  ms2 [" + getInfo(ms2) + "]");
+                System.out.println("  getReuseAddress(): " + ms2.getReuseAddress());
+                throw new RuntimeException("no exceptions from bind() with " + addr);
+            } catch (SocketException e) {
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ms1 != null) {
+                ms1.close();
+            }
+            if (ms2 != null) {
+                ms2.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setReuseAddress(boolean on) throws SocketException,
+     * <br><b>on</b>: true.
+     * <br><b>Expected results</b>: Allows a single process to bind the same
+     * port to multiple sockets as long as each bind specifies a different local
+     * IP address
+     */
+    public void DatagramSocket0032() throws Exception {
+        String testCaseID = "DatagramSocket0032";
+        System.out.println(" >> " + testCaseID + ": " + "public void setReuseAddress(boolean on) throws SocketException");
+
+        DatagramSocket ds1 = null;
+        DatagramSocket ds2 = null;
+        try {
+
+            InetSocketAddress isa = createSocketAddress(7070);
+            InetAddress addr = isa.getAddress();
+            InetAddress wildcard = InetAddress.getByName("0.0.0.0");
+            if (addr.equals(wildcard) || addr.isLoopbackAddress()) {
+                System.out.println("Cannot check: addresses are equal");
+            }
+
+            InetSocketAddress isa1 = new InetSocketAddress(addr, isa.getPort());
+            InetSocketAddress isa2 = new InetSocketAddress(wildcard, isa.getPort());
+
+            ds1 = new DatagramSocket(null);
+            ds1.setReuseAddress(true);    // method under test
+            if (!ds1.getReuseAddress()) {
+                System.out.println("Cannot check: "
+                        + " safety for SO_REUSEADDR option is not guaranteed");
+            }
+            ds1.bind(isa1);
+
+            ds2 = new DatagramSocket(null);
+            ds2.setReuseAddress(true);    // method under test
+            if (!ds2.getReuseAddress()) {
+                System.out.println("Cannot check: "
+                        + " safety for SO_REUSEADDR option is not guaranteed");
+            }
+
+            try {
+                ds2.bind(isa2);
+            } catch (SocketException e) {
+                throw new RuntimeException("cannot bind second socket to " + isa2
+                        + " unexpected " + e);
+            }
+
+            if (ds1.getLocalPort() != isa.getPort() || !ds1.isBound()
+                    || ds2.getLocalPort() != isa.getPort() || !ds2.isBound()) {
+                System.out.println("bind() fails with: " + addr);
+                System.out.println("  ds1 [" + getInfo(ds1) + "]");
+                System.out.println("  ds2 [" + getInfo(ds2) + "]");
+                System.out.println("  getReuseAddress(): " + ds2.getReuseAddress());
+                throw new RuntimeException("bind() fails with: " + addr);
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ds1 != null) {
+                ds1.close();
+            }
+            if (ds2 != null) {
+                ds2.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Assertion testing for public int getTrafficClass() throws
+     * SocketException, will return a number in range from 0 to 255 or throw
+     * SocketException.
+     */
+    public void DatagramSocket2028() throws Exception {
+        String testCaseID = "DatagramSocket2028";
+        System.out.println(" >> " + testCaseID + ": " + "public int getTrafficClass() throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket();
+            int tc = ds.getTrafficClass();
+            if (tc < 0 || tc > 255) {
+                throw new RuntimeException("getTrafficClass() returns: " + tc);
+            }
+        } catch (SecurityException e) {
+            System.out.println("Security restriction: " + e);
+        } catch (SocketException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("Unexpected exception : " + e);
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Assertion testing for public void setTrafficClass(int tc) throws
+     * SocketException, IAE will be thrown with tc less than 0 or greater than
+     * 255.
+     */
+    public void DatagramSocket2029() throws Exception {
+        String testCaseID = "DatagramSocket2029";
+        System.out.println(" >> " + testCaseID + ": " + "public void setTrafficClass(int tc) throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket();
+        } catch (SecurityException e) {
+            System.out.println("Security restriction: " + e);
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("cannot create socket: " + e);
+        }
+
+        int[] values = {
+            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1000, -2, -1,
+            256, 257, 1000, 50000, Integer.MAX_VALUE - 1, Integer.MAX_VALUE
+        };
+
+        for (int i = 0; i < values.length; i++) {
+            try {
+                ds.setTrafficClass(values[i]);
+                System.out.println("No exception with: " + values[i]);
+                System.out.println("getTrafficClass() returns: " + ds.getTrafficClass());
+                ds.close();
+                throw new RuntimeException("setTrafficClass() fails with : " + values[i]);
+            } catch (SocketException e) {
+                ds.close();
+                e.printStackTrace(System.out);
+                throw new RuntimeException("setTrafficClass() throws : " + e);
+            } catch (IllegalArgumentException e) {
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Assertion testing for public void setTrafficClass(int tc) throws
+     * SocketException, only SocketException may be thrown with tc in range from
+     * 0 to 255.
+     */
+    public void DatagramSocket2030() throws Exception {
+        String testCaseID = "DatagramSocket2030";
+        System.out.println(" >> " + testCaseID + ": " + "public void setTrafficClass(int tc) throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket();
+        } catch (SecurityException e) {
+            System.out.println("Security restriction: " + e);
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("cannot create socket: " + e);
+        }
+
+        for (int i = 0; i <= 255; i++) {
+            try {
+                ds.setTrafficClass(i);
+            } catch (SocketException e) {
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setBroadcast(boolean on) throws SocketException,
+     * <br><b>on</b>: false.
+     * <br><b>Expected results</b>: getBroadcast() will return false
+     */
+    public void DatagramSocket0034() throws Exception {
+        String testCaseID = "DatagramSocket0034";
+        System.out.println(" >> " + testCaseID + ": " + "public void setBroadcast(boolean on) throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket();
+            ds.setBroadcast(false);
+            if (ds.getBroadcast() == true) {
+                throw new RuntimeException("SO_BROADCAST is not set to false");
+            }
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+
+    /**
+     * Equivalence class partitioning with input values orientation for public
+     * void setBroadcast(boolean on) throws SocketException,
+     * <br><b>on</b>: true.
+     * <br><b>Expected results</b>: getBroadcast() will return true
+     */
+    public void DatagramSocket0035() throws Exception {
+        String testCaseID = "DatagramSocket0035";
+        System.out.println(" >> " + testCaseID + ": " + "public void setBroadcast(boolean on) throws SocketException");
+
+        DatagramSocket ds = null;
+        try {
+            ds = new DatagramSocket();
+            ds.setBroadcast(true);
+            if (ds.getBroadcast() == false) {
+                throw new RuntimeException("SO_BROADCAST is not set to true");
+            }
+        } catch (IOException e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("unexpected: " + e);
+        } catch (SecurityException e) {
+            System.out.println("Security restriction");
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+        }
+
+        System.out.println("OKAY");
+    }
+}
--- a/jdk/test/java/net/URLClassLoader/getresourceasstream/Test.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/URLClassLoader/getresourceasstream/Test.java	Mon Oct 10 13:31:48 2016 -0700
@@ -26,12 +26,12 @@
 
 public class Test {
     public static void main (String[] args) throws Exception {
-        test1();
+        test1(args[0]);
     }
 
-    public static void test1 () throws Exception {
+    public static void test1 (String s) throws Exception {
         URLClassLoader cl = new URLClassLoader (new URL[] {
-            new URL ("file:./test.jar")
+            new URL ("file:" + s)
         });
         Class clazz = Class.forName ("Test\u00a3", true, cl);
         InputStream is = clazz.getResourceAsStream ("Test\u00a3.class");
--- a/jdk/test/java/net/URLClassLoader/getresourceasstream/test.sh	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/URLClassLoader/getresourceasstream/test.sh	Mon Oct 10 13:31:48 2016 -0700
@@ -39,18 +39,33 @@
 
 checkExit () {
     if [ $? != 0 ]; then
-	exit 1;
+	exit $1;
     fi
 }
 
 ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}/Test.java
 cp ${TESTSRC}/test.jar .
 
-${TESTJAVA}/bin/java ${TESTVMOPTS} Test
-checkExit 
+${TESTJAVA}/bin/java ${TESTVMOPTS} Test ./test.jar
+checkExit 1
 
 # try with security manager
 
-${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.security.policy=file:./policy -Djava.security.manager Test
-checkExit 
+${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.security.policy=file:./policy \
+		-Djava.security.manager Test ./test.jar
+checkExit 2
+
+mkdir tmp
+cd tmp
+${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.security.policy=file:../policy \
+		-cp .. -Djava.security.manager Test ../test.jar
+checkExit 3
+
+cd ..
+THISDIR=$(basename $(pwd))
+cd ..
+${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.security.policy=file:$THISDIR/policy \
+		-cp $THISDIR -Djava.security.manager Test $THISDIR/test.jar
+checkExit 4
+
 exit 0
--- a/jdk/test/java/net/httpclient/http2/ErrorTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/httpclient/http2/ErrorTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -28,6 +28,7 @@
  * @library /lib/testlibrary
  * @build jdk.testlibrary.SimpleSSLContext
  * @modules java.httpclient
+ *          java.security.jgss
  * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
  * @compile/module=java.httpclient java/net/http/BodyInputStream.java
  * @compile/module=java.httpclient java/net/http/EchoHandler.java
@@ -41,18 +42,21 @@
  * @summary check exception thrown when bad TLS parameters selected
  */
 
-import java.io.*;
-import java.net.*;
-import java.net.http.*;
-import static java.net.http.HttpClient.Version.HTTP_2;
-import javax.net.ssl.*;
-import java.nio.file.*;
-import java.util.concurrent.*;
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.EchoHandler;
+import java.net.http.HttpClient;
+import java.net.http.Http2TestServer;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.concurrent.ExecutorService;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
 import jdk.testlibrary.SimpleSSLContext;
 
+import org.testng.annotations.Test;
 
-import org.testng.annotations.Test;
-import org.testng.annotations.Parameters;
+import static java.net.http.HttpClient.Version.HTTP_2;
 
 /**
  * When selecting an unacceptable cipher suite the TLS handshake will fail.
--- a/jdk/test/java/net/httpclient/http2/HpackDriver.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/httpclient/http2/HpackDriver.java	Mon Oct 10 13:31:48 2016 -0700
@@ -33,7 +33,6 @@
  * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.CircularBufferTest
  * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.DecoderTest
  * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.EncoderTest
- * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.HeaderTableTest
  * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.HuffmanTest
  * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.TestHelper
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/HpackDriverHeaderTable.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8153353
+ * @modules java.httpclient/sun.net.httpclient.hpack
+ *          jdk.localedata
+ * @key randomness
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/SpecHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/TestHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/BuffersTestingKit.java
+ * @run testng/othervm java.httpclient/sun.net.httpclient.hpack.HeaderTableTest
+ */
+public class HpackDriverHeaderTable { }
--- a/jdk/test/java/net/httpclient/security/Driver.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/httpclient/security/Driver.java	Mon Oct 10 13:31:48 2016 -0700
@@ -23,10 +23,12 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 8087112
  * @library /lib/testlibrary/
+ * @modules java.httpclient
+ *          jdk.httpserver
  * @build jdk.testlibrary.SimpleSSLContext jdk.testlibrary.Utils
  * @compile ../../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../../com/sun/net/httpserver/FileServerHandler.java
@@ -43,11 +45,14 @@
  * The tests are in Security.java and port number supplied in -Dport.number
  * and -Dport.number1 for tests that require a second free port
  */
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
-import java.io.*;
-import java.net.*;
 
 import jdk.testlibrary.OutputAnalyzer;
 import jdk.testlibrary.Utils;
--- a/jdk/test/java/net/spi/URLStreamHandlerProvider/Basic.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/net/spi/URLStreamHandlerProvider/Basic.java	Mon Oct 10 13:31:48 2016 -0700
@@ -21,11 +21,19 @@
  * questions.
  */
 
-import java.io.*;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Reader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.SequenceInputStream;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.*;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -46,6 +54,7 @@
  * @test
  * @bug 8064924
  * @modules java.compiler
+ *          jdk.compiler
  * @summary Basic test for URLStreamHandlerProvider
  * @library /lib/testlibrary
  * @build jdk.testlibrary.FileUtils jdk.testlibrary.JDKToolFinder
--- a/jdk/test/java/security/AccessController/DoPrivAccompliceTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/security/AccessController/DoPrivAccompliceTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -31,7 +31,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-/**
+/*
  * @test
  * @bug 8048362
  * @compile ../../../lib/testlibrary/JavaToolUtils.java
@@ -41,6 +41,7 @@
  * DoPrivAccmplice.jar for reading user.home property from a PrivilagedAction.
  * Run DoPrivTest.jar and try to access user.home property using
  * DoPrivAccmplice.jar.
+ * @modules jdk.compiler
  * @run main/othervm DoPrivAccompliceTest
  */
 
--- a/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -21,6 +21,17 @@
  * questions.
  */
 
+/*
+ * @test
+ * @bug 8159964
+ * @summary Classes from deprivileged modules should get loaded through
+ *          Platform Classloader.
+ * @modules java.xml.crypto
+ *          jdk.security.auth
+ *          jdk.security.jgss
+ * @run main DeprivilegedModuleLoaderTest
+ */
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -30,13 +41,6 @@
 import com.sun.security.auth.callback.TextCallbackHandler;
 import com.sun.security.jgss.AuthorizationDataEntry;
 
-/*
- * @test
- * @bug 8159964
- * @summary Classes from deprivileged modules should get loaded through
- *          Platform Classloader.
- * @run main DeprivilegedModuleLoaderTest
- */
 public class DeprivilegedModuleLoaderTest {
 
     public static void main(String[] args) {
--- a/jdk/test/java/security/Signature/SignatureLength.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/security/Signature/SignatureLength.java	Mon Oct 10 13:31:48 2016 -0700
@@ -21,15 +21,20 @@
  * questions.
  */
 
-import java.security.*;
-
 /*
  * @test
  * @bug 8161571
  * @summary Reject signatures presented for verification that contain extra
  *          bytes.
+ * @modules jdk.crypto.ec
  * @run main SignatureLength
  */
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.Signature;
+import java.security.SignatureException;
+
 public class SignatureLength {
 
     public static void main(String[] args) throws Exception {
--- a/jdk/test/java/security/testlibrary/Proc.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/security/testlibrary/Proc.java	Mon Oct 10 13:31:48 2016 -0700
@@ -29,6 +29,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.Permission;
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
@@ -37,6 +38,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 /**
@@ -49,7 +51,8 @@
  *        .args("x")            // with args
  *        .env("env", "value")  // and an environment variable
  *        .prop("key","value")  // and a system property
- *        .perm(perm)           // with granted permissions
+ *        .grant(file)          // grant codes in this codebase
+ *        .perm(perm)           // with the permission
  *        .start();             // and start
  *
  * create/start must be called, args/env/prop/perm can be called zero or
@@ -57,7 +60,7 @@
  *
  * The controller can call inheritIO to share its I/O to the process.
  * Otherwise, it can send data into a proc's stdin with write/println, and
- * read its stdout with readLine. stderr is always redirected to DFILE
+ * read its stdout with readLine. stderr is always redirected to a file
  * unless nodump() is called. A protocol is designed to make
  * data exchange among the controller and the processes super easy, in which
  * useful data are always printed with a special prefix ("PROCISFUN:").
@@ -84,10 +87,10 @@
  *
  * As the Proc objects are hidden so deeply, two static methods, d(String) and
  * d(Throwable) are provided to output info into stderr, where they will
- * normally be appended messages to DFILE (unless nodump() is called).
+ * normally be appended messages to a debug file (unless nodump() is called).
  * Developers can view the messages in real time by calling
  *
- *    tail -f proc.debug
+ *    {@code tail -f stderr.<debug>}
  *
  * TODO:
  *
@@ -104,19 +107,24 @@
     private BufferedReader br;      // the stdout of a process
     private String launcher;        // Optional: the java program
 
-    private List<Permission> perms = new ArrayList<>();
     private List<String> args = new ArrayList<>();
     private Map<String,String> env = new HashMap<>();
     private Map<String,String> prop = new HashMap();
     private boolean inheritIO = false;
     private boolean noDump = false;
 
+    private List<String> cp;        // user-provided classpath
     private String clazz;           // Class to launch
     private String debug;           // debug flag, controller will show data
-                                    // transfer between procs
+                                    // transfer between procs. If debug is set,
+                                    // it MUST be different between Procs.
 
     final private static String PREFIX = "PROCISFUN:";
-    final private static String DFILE = "proc.debug";
+
+    // policy file
+    final private StringBuilder perms = new StringBuilder();
+    // temporary saving the grant line in a policy file
+    final private StringBuilder grant = new StringBuilder();
 
     // The following methods are called by controllers
 
@@ -168,10 +176,68 @@
         prop.put(a, b);
         return this;
     }
-    // Adds a perm to policy. Can be called multiple times. In order to make it
-    // effective, please also call prop("java.security.manager", "").
+    // Sets classpath. If not called, Proc will choose a classpath. If called
+    // with no arg, no classpath will be used. Can be called multiple times.
+    public Proc cp(String... s) {
+        if (cp == null) {
+            cp = new ArrayList<>();
+        }
+        cp.addAll(Arrays.asList(s));
+        return this;
+    }
+    // Adds a permission to policy. Can be called multiple times.
+    // All perm() calls after a series of grant() calls are grouped into
+    // a single grant block. perm() calls before any grant() call are grouped
+    // into a grant block with no restriction.
+    // Please note that in order to make permissions effective, also call
+    // prop("java.security.manager", "").
     public Proc perm(Permission p) {
-        perms.add(p);
+        if (grant.length() != 0) {      // Right after grant(s)
+            if (perms.length() != 0) {  // Not first block
+                perms.append("};\n");
+            }
+            perms.append("grant ").append(grant).append(" {\n");
+            grant.setLength(0);
+        } else {
+            if (perms.length() == 0) {  // First block w/o restriction
+                perms.append("grant {\n");
+            }
+        }
+        if (p.getActions().isEmpty()) {
+            String s = String.format("%s \"%s\"",
+                    p.getClass().getCanonicalName(),
+                    p.getName()
+                            .replace("\\", "\\\\").replace("\"", "\\\""));
+            perms.append("    permission ").append(s).append(";\n");
+        } else {
+            String s = String.format("%s \"%s\", \"%s\"",
+                    p.getClass().getCanonicalName(),
+                    p.getName()
+                            .replace("\\", "\\\\").replace("\"", "\\\""),
+                    p.getActions());
+            perms.append("    permission ").append(s).append(";\n");
+        }
+        return this;
+    }
+
+    // Adds a grant option to policy. If called in a row, a single grant block
+    // with all options will be created. If there are perm() call(s) between
+    // grant() calls, they belong to different grant blocks
+
+    // grant on a principal
+    public Proc grant(Principal p) {
+        grant.append("principal ").append(p.getClass().getName())
+                .append(" \"").append(p.getName()).append("\", ");
+        return this;
+    }
+    // grant on a codebase
+    public Proc grant(File f) {
+        grant.append("codebase \"").append(f.toURI()).append("\", ");
+        return this;
+    }
+    // arbitrary grant
+    public Proc grant(String v) {
+        grant.append(v).append(", ");
         return this;
     }
     // Starts the proc
@@ -191,30 +257,22 @@
         Collections.addAll(cmd, splitProperty("test.vm.opts"));
         Collections.addAll(cmd, splitProperty("test.java.opts"));
 
-        cmd.add("-cp");
-        cmd.add(System.getProperty("test.class.path") + File.pathSeparator +
-                System.getProperty("test.src.path"));
+        if (cp == null) {
+            cmd.add("-cp");
+            cmd.add(System.getProperty("test.class.path") + File.pathSeparator +
+                    System.getProperty("test.src.path"));
+        } else if (!cp.isEmpty()) {
+            cmd.add("-cp");
+            cmd.add(cp.stream().collect(Collectors.joining(File.pathSeparator)));
+        }
 
         for (Entry<String,String> e: prop.entrySet()) {
             cmd.add("-D" + e.getKey() + "=" + e.getValue());
         }
-        if (!perms.isEmpty()) {
-            Path p = Files.createTempFile(
-                    Paths.get(".").toAbsolutePath(), "policy", null);
-            StringBuilder sb = new StringBuilder();
-            sb.append("grant {\n");
-            for (Permission perm: perms) {
-                // Sometimes a permission has no name or actions.
-                // but it's safe to use an empty string.
-                String s = String.format("%s \"%s\", \"%s\"",
-                        perm.getClass().getCanonicalName(),
-                        perm.getName()
-                                .replace("\\", "\\\\").replace("\"", "\\\""),
-                        perm.getActions());
-                sb.append("    permission ").append(s).append(";\n");
-            }
-            sb.append("};\n");
-            Files.write(p, sb.toString().getBytes());
+        if (perms.length() > 0) {
+            Path p = Paths.get(getId("policy")).toAbsolutePath();
+            perms.append("};\n");
+            Files.write(p, perms.toString().getBytes());
             cmd.add("-Djava.security.policy=" + p.toString());
         }
         cmd.add(clazz);
@@ -223,6 +281,15 @@
         }
         if (debug != null) {
             System.out.println("PROC: " + debug + " cmdline: " + cmd);
+            for (String c : cmd) {
+                if (c.indexOf('\\') >= 0 || c.indexOf(' ') > 0) {
+                    System.out.print('\'' + c + '\'');
+                } else {
+                    System.out.print(c);
+                }
+                System.out.print(' ');
+            }
+            System.out.println();
         }
         ProcessBuilder pb = new ProcessBuilder(cmd);
         for (Entry<String,String> e: env.entrySet()) {
@@ -233,12 +300,17 @@
         } else if (noDump) {
             pb.redirectError(ProcessBuilder.Redirect.INHERIT);
         } else {
-            pb.redirectError(ProcessBuilder.Redirect.appendTo(new File(DFILE)));
+            pb.redirectError(ProcessBuilder.Redirect
+                    .appendTo(new File(getId("stderr"))));
         }
         p = pb.start();
         br = new BufferedReader(new InputStreamReader(p.getInputStream()));
         return this;
     }
+    String getId(String prefix) {
+        if (debug != null) return prefix + "." + debug;
+        else return prefix + "." + System.identityHashCode(this);
+    }
     // Reads a line from stdout of proc
     public String readLine() throws IOException {
         String s = br.readLine();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/DecimalFormat/Bug8165466.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8165466
+ * @summary Checks the subsequent function calls of the DecimalFormat.format()
+ *          method in which the minimumFractionDigit is set to 0 and one of
+ *          the format() call include formatting of the number with zero
+ *          fraction value e.g. 0.00, 9.00
+ */
+
+import java.text.DecimalFormat;
+import java.util.Locale;
+
+public class Bug8165466 {
+
+    public static void main(String[] args) {
+        DecimalFormat nf = (DecimalFormat) DecimalFormat
+                .getPercentInstance(Locale.US);
+        nf.setMaximumFractionDigits(3);
+        nf.setMinimumFractionDigits(0);
+        nf.setMultiplier(1);
+
+        double d = 0.005678;
+        String result = nf.format(d);
+        if (!result.equals("0.006%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 0.006%, Found: " + result
+                    + "]");
+        }
+
+        d = 0.00;
+        result = nf.format(d);
+        if (!result.equals("0%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 0%, Found: " + result
+                    + "]");
+        }
+
+        d = 0.005678;
+        result = nf.format(d);
+        if (!result.equals("0.006%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 0.006%, Found: " + result
+                    + "]");
+        }
+
+        //checking with the non zero value
+        d = 0.005678;
+        result = nf.format(d);
+        if (!result.equals("0.006%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 0.006%, Found: " + result
+                    + "]");
+        }
+
+        d = 9.00;
+        result = nf.format(d);
+        if (!result.equals("9%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 9%, Found: " + result
+                    + "]");
+        }
+
+        d = 0.005678;
+        result = nf.format(d);
+        if (!result.equals("0.006%")) {
+            throw new RuntimeException("[Failed while formatting the double"
+                    + " value: " + d + " Expected: 0.006%, Found: " + result
+                    + "]");
+        }
+    }
+
+}
+
--- a/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java	Mon Oct 10 13:31:48 2016 -0700
@@ -49,7 +49,7 @@
 
 /*
  * @test
- * @bug 8081022 8151876
+ * @bug 8081022 8151876 8166875
  * @key randomness
  */
 
--- a/jdk/test/java/time/test/java/time/format/ZoneName.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/time/test/java/time/format/ZoneName.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -378,6 +378,7 @@
         "Europe/Helsinki", "Europe_Eastern", "Europe/Bucharest",
         "America/Nome", "Alaska", "America/Juneau",
         "Asia/Yakutsk", "Yakutsk", "Asia/Yakutsk",
+        "Asia/Yangon", "Myanmar", "Asia/Rangoon",
         "Africa/Conakry", "GMT", "Atlantic/Reykjavik",
         "Asia/Seoul", "Korea", "Asia/Seoul",
         "America/Antigua", "Atlantic", "America/Halifax",
@@ -747,6 +748,7 @@
         "NZ", "Pacific/Auckland",
         "Asia/Tel_Aviv", "Asia/Jerusalem",
         "Hongkong", "Asia/Hong_Kong",
+        "Asia/Rangoon", "Asia/Yangon",
     };
 
     private static final Map<String, String> zidToMzone = new HashMap<>();
--- a/jdk/test/java/util/TimeZone/TimeZoneTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/java/util/TimeZone/TimeZoneTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483
- *      8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684
+ *      8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684 8166875
  * @modules java.base/sun.util.resources
  * @library /java/text/testlib
  * @summary test TimeZone
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ToolProviderTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8159855
+ * @summary test ToolProvider SPI
+ * @run main/othervm ToolProviderTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.spi.ToolProvider;
+
+public class ToolProviderTest {
+    public static void main(String... args) throws Exception {
+        ToolProviderTest t = new ToolProviderTest();
+        t.run();
+    }
+
+    void run() throws Exception {
+        initServices();
+
+        System.out.println("test without security manager present:");
+        test();
+
+        System.setSecurityManager(new SecurityManager());
+
+        System.out.println("test with security manager present:");
+        test();
+    }
+
+    private void test() throws Exception {
+        ToolProvider testProvider = ToolProvider.findFirst("test").get();
+        int rc = testProvider.run(System.out, System.err, "hello test");
+        if (rc != 0) {
+            throw new Exception("unexpected exit code: " + rc);
+        }
+    }
+
+    private void initServices() throws IOException {
+        Path testClasses = Paths.get(System.getProperty("test.classes"));
+        Path services = testClasses.resolve(Paths.get("META-INF", "services"));
+        Files.createDirectories(services);
+        Files.write(services.resolve(ToolProvider.class.getName()),
+                Arrays.asList(TestProvider.class.getName()));
+    }
+
+    public static class TestProvider implements ToolProvider {
+        public TestProvider() {
+            checkPrivileges();
+        }
+
+        public String name() {
+            return "test";
+        }
+
+        public int run(PrintWriter out, PrintWriter err, String... args) {
+            out.println("Test: " + Arrays.toString(args));
+            return 0;
+        }
+
+        private void checkPrivileges() {
+            boolean haveSecurityManager = (System.getSecurityManager() != null);
+            try {
+                // validate appropriate privileges by checking access to a
+                // system property
+                System.getProperty("java.home");
+                if (haveSecurityManager) {
+                    throw new Error("exception exception not thrown");
+                }
+            } catch (SecurityException e) {
+                if (!haveSecurityManager) {
+                    throw new Error("unexpected exception: " + e);
+                }
+            }
+        }
+    }
+}
+
--- a/jdk/test/jdk/internal/misc/Unsafe/CopyMemory.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/jdk/internal/misc/Unsafe/CopyMemory.java	Mon Oct 10 13:31:48 2016 -0700
@@ -22,7 +22,6 @@
  */
 
 import jdk.internal.misc.Unsafe;
-import java.lang.reflect.Field;
 
 /*
  * @test
@@ -40,7 +39,6 @@
      */
     private void testPositive() {
         testSmallCopy(false);
-        testLargeCopy(false);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/misc/Unsafe/CopyMemoryLarge.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.internal.misc.Unsafe;
+
+/*
+ * @test
+ * @summary Test Unsafe.copyMemory
+ * @modules java.base/jdk.internal.misc
+ * @requires os.maxMemory > 8G
+ */
+public class CopyMemoryLarge extends CopyCommon {
+    private CopyMemoryLarge() {
+    }
+
+    /**
+     * Run positive tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testPositive() {
+        testLargeCopy(false);
+    }
+
+    /**
+     * Run all tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void test() {
+        testPositive();
+    }
+
+    public static void main(String[] args) {
+        CopyMemoryLarge cs = new CopyMemoryLarge();
+        cs.test();
+    }
+}
--- a/jdk/test/jdk/internal/misc/Unsafe/CopySwap.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/jdk/internal/misc/Unsafe/CopySwap.java	Mon Oct 10 13:31:48 2016 -0700
@@ -22,7 +22,6 @@
  */
 
 import jdk.internal.misc.Unsafe;
-import java.lang.reflect.Field;
 
 /*
  * @test
@@ -40,7 +39,6 @@
      */
     private void testPositive() {
         testSmallCopy(true);
-        testLargeCopy(true);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/misc/Unsafe/CopySwapLarge.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.internal.misc.Unsafe;
+
+/*
+ * @test
+ * @summary Test Unsafe.copySwapMemory
+ * @modules java.base/jdk.internal.misc
+ * @requires os.maxMemory > 8G
+ */
+public class CopySwapLarge extends CopyCommon {
+    private CopySwapLarge() {
+    }
+
+    /**
+     * Run positive tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testPositive() {
+        testLargeCopy(true);
+    }
+
+    /**
+     * Run all tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void test() {
+        testPositive();
+    }
+
+    public static void main(String[] args) {
+        CopySwapLarge cs = new CopySwapLarge();
+        cs.test();
+    }
+}
--- a/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/RGBColorConvertTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -26,7 +26,6 @@
  * @bug 6279846
  * @summary Verifies that transform between the same ICC color spaces does not
  * change pixels
- * @run main ColorConvertTest
  */
 
 import java.awt.image.*;
--- a/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java	Mon Oct 10 13:31:48 2016 -0700
@@ -27,6 +27,7 @@
  * @summary Test that URL connections to multi-release jars can be runtime versioned
  * @library /lib/testlibrary/java/util/jar
  * @modules java.compiler
+ *          jdk.compiler
  *          jdk.httpserver
  *          jdk.jartool
  * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
--- a/jdk/test/sun/security/provider/PolicyFile/CanonPath.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/security/provider/PolicyFile/CanonPath.java	Mon Oct 10 13:31:48 2016 -0700
@@ -150,9 +150,9 @@
             //
             // on unix, /- implies everything
 
-            if (w.implies(u) || !u.implies(w)) {
-                throw new Exception("SLASH/- test failed");
-            }
+            //if (w.implies(u) || !u.implies(w)) {
+            //    throw new Exception("SLASH/- test failed");
+            //}
         }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/util/FilePermCompat/CompatImpact.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8164705
+ * @summary check compatibility after FilePermission change
+ * @library /java/security/testlibrary/
+ * @modules java.base/jdk.internal.misc
+ * @run main CompatImpact prepare
+ * @run main CompatImpact builtin
+ * @run main CompatImpact mine
+ * @run main CompatImpact dopriv
+ */
+
+import java.io.File;
+import java.io.FilePermission;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+
+public class CompatImpact {
+
+    public static void main(String[] args) throws Exception {
+        switch (args[0]) {
+            // copy class files to future classpath
+            case "prepare":
+                // cp in .
+                String cp = System.getProperty("test.classes");
+                Files.copy(Paths.get(cp, "CompatImpact.class"),
+                        Paths.get("CompatImpact.class"));
+                Files.copy(Paths.get(cp, "CompatImpact$MP.class"),
+                        Paths.get("CompatImpact$MP.class"));
+                Files.write(Paths.get("f"), new byte[10]);
+                // cp in ./sub
+                Files.createDirectory(Paths.get("sub"));
+                Files.copy(Paths.get(cp, "CompatImpact.class"),
+                        Paths.get("sub", "CompatImpact.class"));
+                Files.copy(Paths.get(cp, "CompatImpact$MP.class"),
+                        Paths.get("sub", "CompatImpact$MP.class"));
+                Files.write(Paths.get("sub", "f"), new byte[10]);
+                // cp in ./inner
+                Files.createDirectory(Paths.get("inner"));
+                Files.copy(Paths.get(cp, "CompatImpact$DoPrivInner.class"),
+                        Paths.get("inner", "CompatImpact$DoPrivInner.class"));
+                break;
+            // run tests with different policy impls
+            case "builtin":
+            case "mine":
+                cp = System.getProperty("test.classes");
+                Proc p;
+                String failed = "";
+                String testcase = "";
+                String cwd = System.getProperty("user.dir");
+
+                // Granting a FilePermission on an absolute path
+                testcase = "PonA";
+                p = p(args[0], cwd + "/f")
+                        .args("f", cwd + "/f")
+                        .debug(testcase)
+                        .start();
+                if (p.waitFor() != 0) {
+                    Files.copy(Paths.get("stderr." + testcase), System.out);
+                    failed += testcase + " ";
+                }
+
+                // Granting a FilePermission on a relative path
+                testcase = "PonR";
+                p = p(args[0], "f")
+                        .args("f", cwd + "/f")
+                        .debug(testcase)
+                        .start();
+                if (p.waitFor() != 0) {
+                    Files.copy(Paths.get("stderr." + testcase), System.out);
+                    failed += testcase + " ";
+                }
+
+                // Reading file on classpath, not cwd
+                testcase = "cp";
+                String cprel = Paths.get(cwd).relativize(Paths.get(cp))
+                        .normalize().toString();
+                p = p(args[0], "x")
+                        .args(cp + "/f", cprel + "/f")
+                        .debug(testcase)
+                        .start();
+                if (p.waitFor() != 0) {
+                    Files.copy(Paths.get("stderr." + testcase), System.out);
+                    failed += testcase + " ";
+                }
+
+                // Reading file on classpath, cwd
+                testcase = "cpHere";
+                p = p(args[0], "x")
+                        .args(cwd + "/f", "f", "RES")
+                        .cp(".")   // Must! cancel the old CLASSPATH.
+                        .debug(testcase)
+                        .start();
+                if (p.waitFor() != 0) {
+                    Files.copy(Paths.get("stderr." + testcase), System.out);
+                    failed += testcase + " ";
+                }
+
+                // Reading file on classpath, cwd
+                testcase = "cpSub";
+                p = p(args[0], "x")
+                        .args(cwd + "/sub/f", "sub/f", "RES")
+                        .cp("sub")   // Must! There's CLASSPATH.
+                        .debug(testcase)
+                        .start();
+                if (p.waitFor() != 0) {
+                    Files.copy(Paths.get("stderr." + testcase), System.out);
+                    failed += testcase + " ";
+                }
+
+                if (!failed.isEmpty()) {
+                    throw new Exception(failed + "failed");
+                }
+                break;
+            // test <policy_type> <grant> <read...>
+            case "test":
+                if (args[1].equals("mine")) {
+                    Policy.setPolicy(new MP(args[2]));
+                }
+                Exception e = null;
+                for (int i = 3; i < args.length; i++) {
+                    try {
+                        System.out.println(args[i]);
+                        if (args[i].equals("RES")) {
+                            CompatImpact.class.getResourceAsStream("f")
+                                    .close();
+                        } else {
+                            new File(args[i]).exists();
+                        }
+                    } catch (Exception e2) {
+                        e = e2;
+                        e2.printStackTrace(System.out);
+                    }
+                }
+                if (e != null) {
+                    System.err.println("====================");
+                    throw e;
+                }
+                break;
+            // doPrivWithPerm test launcher
+            case "dopriv":
+                cwd = System.getProperty("user.dir");
+                // caller (CompatImpact doprivouter, no permission) in sub,
+                // executor (DoPrivInner, AllPermission) in inner.
+                p = Proc.create("CompatImpact")
+                        .args("doprivouter")
+                        .prop("java.security.manager", "")
+                        .grant(new File("inner"))
+                        .perm(new AllPermission())
+                        .cp("sub", "inner")
+                        .debug("doPriv")
+                        .args(cwd)
+                        .start();
+                if (p.waitFor() != 0) {
+                    throw new Exception("dopriv test fails");
+                }
+                break;
+            // doprivouter <cwd>
+            case "doprivouter":
+                DoPrivInner.main(args);
+                break;
+            default:
+                throw new Exception("unknown " + args[0]);
+        }
+    }
+
+    // Call by CompatImpact doprivouter, with AllPermission
+    public static class DoPrivInner {
+        public static void main(String[] args) throws Exception {
+            AccessController.doPrivileged((PrivilegedAction<Boolean>)
+                            () -> new File("x").exists(),
+                    null,
+                    new FilePermission(args[1] + "/x", "read"));
+            AccessController.doPrivileged((PrivilegedAction<Boolean>)
+                            () -> new File(args[1] + "/x").exists(),
+                    null,
+                    new FilePermission("x", "read"));
+            try {
+                AccessController.doPrivileged((PrivilegedAction<Boolean>)
+                                () -> new File("x").exists(),
+                        null,
+                        new FilePermission("y", "read"));
+                throw new Exception("Should not read");
+            } catch (SecurityException se) {
+                // Expected
+            }
+        }
+    }
+
+    // Return a Proc object for different policy types
+    private static Proc p(String type, String f) throws Exception {
+        Proc p = Proc.create("CompatImpact")
+                .prop("java.security.manager", "");
+        p.args("test", type);
+        switch (type) {
+            case "builtin":
+                // For builtin policy, reading access to f can be
+                // granted as a permission
+                p.perm(new FilePermission(f, "read"));
+                p.args("-");
+                break;
+            case "mine":
+                // For my policy, f is passed into test and new MP(f)
+                // will be set as new policy
+                p.perm(new SecurityPermission("setPolicy"));
+                p.args(f);
+                break;
+            default:
+                throw new Exception("unknown " + type);
+        }
+        return p;
+    }
+
+    // My own Policy impl, with only one granted permission, also not smart
+    // enough to know whether ProtectionDomain grants any permission
+    static class MP extends Policy {
+        final PermissionCollection pc;
+        MP(String f) {
+            FilePermission p = new FilePermission(f, "read");
+            pc = p.newPermissionCollection();
+            pc.add(p);
+        }
+        @Override
+        public PermissionCollection getPermissions(CodeSource codesource) {
+            return pc;
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain domain) {
+            return pc;
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain domain, Permission permission) {
+            return pc.implies(permission);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/util/FilePermCompat/Flag.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 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.
+ *
+ * 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 8164705
+ * @summary check jdk.filepermission.canonicalize
+ * @library /java/security/testlibrary/
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=true Flag truetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=false Flag falsetrue
+ * @run main/othervm Flag falsetrue
+ */
+
+import java.io.File;
+import java.io.FilePermission;
+import java.lang.*;
+import java.security.Permission;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+
+public class Flag {
+    public static void main(String[] args) throws Exception {
+
+        boolean test1;
+        boolean test2;
+
+        String here = System.getProperty("user.dir");
+        File abs = new File(here, "x");
+        FilePermission fp1 = new FilePermission("x", "read");
+        FilePermission fp2 = new FilePermission(abs.toString(), "read");
+        test1 = fp1.equals(fp2);
+
+        Policy pol = new Policy() {
+            @java.lang.Override
+            public boolean implies(ProtectionDomain domain, Permission permission) {
+                return fp1.implies(permission);
+            }
+        };
+
+        Policy.setPolicy(pol);
+        System.setSecurityManager(new SecurityManager());
+        try {
+            System.getSecurityManager().checkPermission(fp2);
+            test2 = true;
+        } catch (SecurityException se) {
+            test2 = false;
+        }
+
+        if (!args[0].equals(test1 + "" + test2)) {
+            throw new Exception("Test failed: " + test1 + test2);
+        }
+    }
+}
--- a/jdk/test/sun/util/calendar/zi/tzdata/VERSION	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/VERSION	Mon Oct 10 13:31:48 2016 -0700
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2016f
+tzdata2016g
--- a/jdk/test/sun/util/calendar/zi/tzdata/africa	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/africa	Mon Oct 10 13:31:48 2016 -0700
@@ -487,7 +487,7 @@
 # http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/
 #
 # From Paul Eggert (2013-10-25):
-# For now, assume they're reverting to the pre-2012 rules of permanent UTC+2.
+# For now, assume they're reverting to the pre-2012 rules of permanent UT +02.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
--- a/jdk/test/sun/util/calendar/zi/tzdata/antarctica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/antarctica	Mon Oct 10 13:31:48 2016 -0700
@@ -33,9 +33,7 @@
 # http://www.spri.cam.ac.uk/bob/periant.htm
 # for information.
 # Unless otherwise specified, we have no time zone information.
-#
-# Except for the French entries,
-# I made up all time zone abbreviations mentioned here; corrections welcome!
+
 # FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
 
 # Argentina - year-round bases
@@ -52,7 +50,7 @@
 #	previously sealers and scientific personnel wintered
 #	Margaret Turner reports
 #	http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html
-#	(1999-09-30) that they're UTC+5, with no DST;
+#	(1999-09-30) that they're UT +05, with no DST;
 #	presumably this is when they have visitors.
 #
 # year-round bases
@@ -91,23 +89,22 @@
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Casey	0	-	-00	1969
-			8:00	-	AWST	2009 Oct 18  2:00
-						# Australian Western Std Time
-			11:00	-	CAST	2010 Mar  5  2:00  # Casey Time
-			8:00	-	AWST	2011 Oct 28  2:00
-			11:00	-	CAST	2012 Feb 21 17:00u
-			8:00	-	AWST
+			8:00	-	+08	2009 Oct 18  2:00
+			11:00	-	+11	2010 Mar  5  2:00
+			8:00	-	+08	2011 Oct 28  2:00
+			11:00	-	+11	2012 Feb 21 17:00u
+			8:00	-	+08
 Zone Antarctica/Davis	0	-	-00	1957 Jan 13
-			7:00	-	DAVT	1964 Nov    # Davis Time
+			7:00	-	+07	1964 Nov
 			0	-	-00	1969 Feb
-			7:00	-	DAVT	2009 Oct 18  2:00
-			5:00	-	DAVT	2010 Mar 10 20:00u
-			7:00	-	DAVT	2011 Oct 28  2:00
-			5:00	-	DAVT	2012 Feb 21 20:00u
-			7:00	-	DAVT
+			7:00	-	+07	2009 Oct 18  2:00
+			5:00	-	+05	2010 Mar 10 20:00u
+			7:00	-	+07	2011 Oct 28  2:00
+			5:00	-	+05	2012 Feb 21 20:00u
+			7:00	-	+07
 Zone Antarctica/Mawson	0	-	-00	1954 Feb 13
-			6:00	-	MAWT	2009 Oct 18  2:00 # Mawson Time
-			5:00	-	MAWT
+			6:00	-	+06	2009 Oct 18  2:00
+			5:00	-	+05
 # References:
 # Casey Weather (1998-02-26)
 # http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html
@@ -161,7 +158,7 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Indian/Kerguelen	0	-	-00	1950 # Port-aux-Français
-			5:00	-	TFT	# ISO code TF Time
+			5:00	-	+05
 #
 # year-round base in the main continent
 # Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11
@@ -172,9 +169,9 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/DumontDUrville 0 -	-00	1947
-			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
+			10:00	-	+10	1952 Jan 14
 			0	-	-00	1956 Nov
-			10:00	-	DDUT	# Dumont-d'Urville Time
+			10:00	-	+10
 
 # France & Italy - year-round base
 # Concordia, -750600+1232000, since 2005
@@ -200,7 +197,7 @@
 # station of Japan, it's appropriate for the principal location.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Syowa	0	-	-00	1957 Jan 29
-			3:00	-	SYOT	# Syowa Time
+			3:00	-	+03
 # See:
 # NIPR Antarctic Research Activities (1999-08-17)
 # http://www.nipr.ac.jp/english/ara01.html
@@ -237,17 +234,17 @@
 # correct, but they should be quite close to the actual dates.
 #
 # From Paul Eggert (2014-03-21):
-# The CET-switching Troll rules require zic from tzcode 2014b or later, so as
+# The CET-switching Troll rules require zic from tz 2014b or later, so as
 # suggested by Bengt-Inge Larsson comment them out for now, and approximate
 # with only UTC and CEST.  Uncomment them when 2014b is more prevalent.
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-#Rule	Troll	2005	max	-	Mar	 1	1:00u	1:00	CET
-Rule	Troll	2005	max	-	Mar	lastSun	1:00u	2:00	CEST
-#Rule	Troll	2005	max	-	Oct	lastSun	1:00u	1:00	CET
-#Rule	Troll	2004	max	-	Nov	 7	1:00u	0:00	UTC
+#Rule	Troll	2005	max	-	Mar	 1	1:00u	1:00	+01
+Rule	Troll	2005	max	-	Mar	lastSun	1:00u	2:00	+02
+#Rule	Troll	2005	max	-	Oct	lastSun	1:00u	1:00	+01
+#Rule	Troll	2004	max	-	Nov	 7	1:00u	0:00	+00
 # Remove the following line when uncommenting the above '#Rule' lines.
-Rule	Troll	2004	max	-	Oct	lastSun	1:00u	0:00	UTC
+Rule	Troll	2004	max	-	Oct	lastSun	1:00u	0:00	+00
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Troll	0	-	-00	2005 Feb 12
 			0:00	Troll	%s
@@ -288,10 +285,10 @@
 # changes during the year and does not necessarily correspond to mean
 # solar noon.  So the Vostok time might have been whatever the clocks
 # happened to be during their visit.  So we still don't really know what time
-# it is at Vostok.  But we'll guess UTC+6.
+# it is at Vostok.  But we'll guess +06.
 #
 Zone Antarctica/Vostok	0	-	-00	1957 Dec 16
-			6:00	-	VOST	# Vostok time
+			6:00	-	+06
 
 # S Africa - year-round bases
 # Marion Island, -4653+03752
@@ -324,7 +321,7 @@
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Rothera	0	-	-00	1976 Dec  1
-			-3:00	-	ROTT	# Rothera time
+			-3:00	-	-03
 
 # Uruguay - year round base
 # Artigas, King George Island, -621104-0585107
--- a/jdk/test/sun/util/calendar/zi/tzdata/asia	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/asia	Mon Oct 10 13:31:48 2016 -0700
@@ -139,13 +139,11 @@
 # http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
-			3:00	-	YERT	1957 Mar    # Yerevan Time
-			4:00 RussiaAsia YER%sT	1991 Mar 31  2:00s
-			3:00	1:00	YERST	1991 Sep 23 # independence
-			3:00 RussiaAsia	AM%sT	1995 Sep 24  2:00s
-			4:00	-	AMT	1997
-			4:00 RussiaAsia	AM%sT	2012 Feb  9
-			4:00	-	AMT
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia	+03/+04	1995 Sep 24  2:00s
+			4:00	-	+04	1997
+			4:00 RussiaAsia	+04/+05
 
 # Azerbaijan
 
@@ -166,13 +164,12 @@
 Rule	Azer	1997	2015	-	Oct	lastSun	 5:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
-			3:00	-	BAKT	1957 Mar    # Baku Time
-			4:00 RussiaAsia BAK%sT	1991 Mar 31  2:00s
-			3:00	1:00	BAKST	1991 Aug 30 # independence
-			3:00 RussiaAsia	AZ%sT	1992 Sep lastSun  2:00s
-			4:00	-	AZT	1996     # Azerbaijan Time
-			4:00	EUAsia	AZ%sT	1997
-			4:00	Azer	AZ%sT
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia	+03/+04	1992 Sep lastSun  2:00s
+			4:00	-	+04	1996
+			4:00	EUAsia	+04/+05	1997
+			4:00	Azer	+04/+05
 
 # Bahrain
 # See Asia/Qatar.
@@ -291,7 +288,7 @@
 # Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Rangoon	6:24:40 -	LMT	1880        # or Yangon
+Zone	Asia/Yangon	6:24:40 -	LMT	1880        # or Rangoon
 			6:24:40	-	RMT	1920        # Rangoon Mean Time?
 			6:30	-	BURT	1942 May    # Burma Time
 			9:00	-	JST	1945 May  3
@@ -406,7 +403,7 @@
 # Lewiston (ME) Daily Sun (1939-05-29), p 17, said "Even the time is
 # different - the occupied districts going by Tokyo time, an hour
 # ahead of that prevailing in the rest of Shanghai."  Guess that the
-# Xujiahui Observatory was under French control and stuck with UT+8.
+# Xujiahui Observatory was under French control and stuck with UT +08.
 #
 # In earlier versions of this file, China had many separate Zone entries, but
 # this was based on what were apparently incorrect data in Shanks & Pottenger.
@@ -415,26 +412,26 @@
 # Proposed in 1918 and theoretically in effect until 1949 (although in practice
 # mainly observed in coastal areas), the five zones were:
 #
-# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT+8.5
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT +08:30
 # Asia/Harbin (currently a link to Asia/Shanghai)
 # Heilongjiang (except Mohe county), Jilin
 #
-# Zhongyuan Time ("Central plain Time") UT+8
+# Zhongyuan Time ("Central plain Time") UT +08
 # Asia/Shanghai
 # most of China
 # This currently represents most other zones as well,
 # as apparently these regions have been the same since 1970.
 # Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest.
-# Guo says Shanghai switched to UT+8 "from the end of the 19th century".
+# Guo says Shanghai switched to UT +08 "from the end of the 19th century".
 #
-# Long-shu Time (probably due to Long and Shu being two names of that area) UT+7
+# Long-shu Time (probably due to Long and Shu being two names of the area) UT +07
 # Asia/Chongqing (currently a link to Asia/Shanghai)
 # Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
 # most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
 # counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
 # Yangchun, Yangjiang, Yu'nan, and Yunfu.
 #
-# Xin-zang Time ("Xinjiang-Tibet Time") UT+6
+# Xin-zang Time ("Xinjiang-Tibet Time") UT +06
 # Asia/Urumqi
 # This currently represents Kunlun Time as well,
 # as apparently the two regions have been the same since 1970.
@@ -447,7 +444,7 @@
 # Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
 # Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
 #
-# Kunlun Time UT+5.5
+# Kunlun Time UT +05:30
 # Asia/Kashgar (currently a link to Asia/Urumqi)
 # West Tibet, including Pulan, Aheqi, Shufu, Shule;
 # West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
@@ -463,7 +460,7 @@
 #
 # On the other hand, ethnic Uyghurs, who make up about half the
 # population of Xinjiang, typically use "Xinjiang time" which is two
-# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
+# hours behind Beijing time, or UT +06. The government of the Xinjiang
 # Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
 # local governments such as the Ürümqi city government use both times in
 # publications, referring to what is popularly called Xinjiang time as
@@ -519,8 +516,8 @@
 # having the same time as Beijing.
 
 # From Paul Eggert (2014-06-30):
-# In the early days of the PRC, Tibet was given its own time zone (UT+6) but
-# this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
+# In the early days of the PRC, Tibet was given its own time zone (UT +06)
+# but this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
 # Memories of life in Lhasa under Chinese Rule, Columbia U Press, ISBN
 # 978-0231142861 (2008), translator's introduction by Matthew Akester, p x.
 # As this is before our 1970 cutoff, Tibet doesn't need a separate zone.
@@ -534,12 +531,12 @@
 # Republics, the Soviet Union, the Kuomintang, and the People's Republic of
 # China, and tracking down all these organizations' timekeeping rules would be
 # quite a trick.  Approximate this lost history by a transition from LMT to
-# XJT at the start of 1928, the year of accession of the warlord Jin Shuren,
+# UT +06 at the start of 1928, the year of accession of the warlord Jin Shuren,
 # which happens to be the date given by Shanks & Pottenger (no doubt as a
-# guess) as the transition from LMT.  Ignore the usage of UT+8 before
-# 1986-02-01 under the theory that the transition date to UT+8 is unknown and
+# guess) as the transition from LMT.  Ignore the usage of +08 before
+# 1986-02-01 under the theory that the transition date to +08 is unknown and
 # that the sort of users who prefer Asia/Urumqi now typically ignored the
-# UT+8 mandate back then.
+# +08 mandate back then.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # Beijing time, used throughout China; represented by Shanghai.
@@ -744,7 +741,7 @@
 # be found from historical government announcement database.
 
 # From Paul Eggert (2014-07-03):
-# As per Yu-Cheng Chuang, say that Taiwan was at UT+9 from 1937-10-01
+# As per Yu-Cheng Chuang, say that Taiwan was at UT +09 from 1937-10-01
 # until 1945-09-21 at 01:00, overriding Shanks & Pottenger.
 # Likewise, use Yu-Cheng Chuang's data for DST in Taiwan.
 
@@ -858,16 +855,15 @@
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Tbilisi	2:59:11 -	LMT	1880
 			2:59:11	-	TBMT	1924 May  2 # Tbilisi Mean Time
-			3:00	-	TBIT	1957 Mar    # Tbilisi Time
-			4:00 RussiaAsia TBI%sT	1991 Mar 31  2:00s
-			3:00	1:00	TBIST	1991 Apr  9 # independence
-			3:00 RussiaAsia GE%sT	1992        # Georgia Time
-			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
-			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
-			4:00	1:00	GEST	1997 Mar lastSun
-			4:00 E-EurAsia	GE%sT	2004 Jun 27
-			3:00 RussiaAsia	GE%sT	2005 Mar lastSun  2:00
-			4:00	-	GET
+			3:00	-	+03	1957 Mar
+			4:00 RussiaAsia +04/+05	1991 Mar 31  2:00s
+			3:00 RussiaAsia +03/+04	1992
+			3:00 E-EurAsia	+03/+04	1994 Sep lastSun
+			4:00 E-EurAsia	+04/+05	1996 Oct lastSun
+			4:00	1:00	+05	1997 Mar lastSun
+			4:00 E-EurAsia	+04/+05	2004 Jun 27
+			3:00 RussiaAsia	+03/+04	2005 Mar lastSun  2:00
+			4:00	-	+04
 
 # East Timor
 
@@ -944,7 +940,7 @@
 # These would be the earliest possible times for a change.
 # Régimes horaires pour le monde entier, by Henri Le Corre, (Éditions
 # Traditionnelles, 1987, Paris) says that Java and Madura switched
-# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
+# from UT +09 to +07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
 # (Hollandia).  For now, assume all Indonesian locations other than Jayapura
 # switched on 1945-09-23.
 #
@@ -955,11 +951,11 @@
 # summary published by the Time and Frequency Laboratory of the
 # Research Center for Calibration, Instrumentation and Metrology,
 # Indonesia, <http://time.kim.lipi.go.id/time-eng.php> (2006-09-29).
-# The abbreviations are:
+# The time zone abbreviations and UT offsets are:
 #
-# WIB  - UTC+7 - Waktu Indonesia Barat (Indonesia western time)
-# WITA - UTC+8 - Waktu Indonesia Tengah (Indonesia central time)
-# WIT  - UTC+9 - Waktu Indonesia Timur (Indonesia eastern time)
+# WIB  - +07 - Waktu Indonesia Barat (Indonesia western time)
+# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time)
+# WIT  - +09 - Waktu Indonesia Timur (Indonesia eastern time)
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # Java, Sumatra
@@ -1848,11 +1844,11 @@
 Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
-			5:00	-	FRUT	1930 Jun 21 # Frunze Time
-			6:00 RussiaAsia FRU%sT	1991 Mar 31  2:00s
-			5:00	1:00	FRUST	1991 Aug 31  2:00 # independence
-			5:00	Kyrgyz	KG%sT	2005 Aug 12 # Kyrgyzstan Time
-			6:00	-	KGT
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia +06/+07	1991 Mar 31  2:00s
+			5:00 RussiaAsia	+05/+06	1991 Aug 31  2:00
+			5:00	Kyrgyz	+05/+06	2005 Aug 12
+			6:00	-	+06
 
 ###############################################################################
 
@@ -1891,25 +1887,24 @@
 Rule	ROK	1987	1988	-	May	Sun>=8	2:00	1:00	D
 Rule	ROK	1987	1988	-	Oct	Sun>=8	3:00	0	S
 
-# From Paul Eggert (2014-10-30):
+# From Paul Eggert (2016-08-23):
 # The Korean Wikipedia entry gives the following sources for UT offsets:
 #
-# 1908: Official Journal Article No. 3994 (Edict No. 5)
+# 1908: Official Journal Article No. 3994 (decree No. 5)
 # 1912: Governor-General of Korea Official Gazette Issue No. 367
 #       (Announcement No. 338)
 # 1954: Presidential Decree No. 876 (1954-03-17)
 # 1961: Law No. 676 (1961-08-07)
-# 1987: Law No. 3919 (1986-12-31)
 #
-# The Wikipedia entry also has confusing information about a change
-# to UT+9 in April 1910, but then what would be the point of the later change
-# to UT+9 on 1912-01-01?  Omit the 1910 change for now.
+# (Another source "1987: Law No. 3919 (1986-12-31)" was in the 2014-10-30
+# edition of the Korean Wikipedia entry.)
 #
 # I guessed that time zone abbreviations through 1945 followed the same
 # rules as discussed under Taiwan, with nominal switches from JST to KST
 # when the respective cities were taken over by the Allies after WWII.
 #
-# For Pyongyang we have no information; guess no changes since World War II.
+# For Pyongyang, guess no changes from World War II until 2015, as we
+# have no information otherwise.
 
 # From Steffen Thorsen (2015-08-07):
 # According to many news sources, North Korea is going to change to
@@ -2069,7 +2064,7 @@
 # Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
 # there is only one time zone and that DST is observed, citing Microsoft
 # Windows XP as the source.  Risto Nykänen (2005-05-16) reports that
-# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
+# travelmongolia.org says there are two time zones (UT +07, +08) with no DST.
 # Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
 # Washington, DC says there are two time zones, with DST observed.
 # He also found
@@ -2705,7 +2700,7 @@
 # earlier date.
 #
 # Shanks & Pottenger also state that until 1968-05-01 Saudi Arabia had two
-# time zones; the other zone, at UTC+4, was in the far eastern part of
+# time zones; the other zone, at UT +04, was in the far eastern part of
 # the country.  Ignore this, as it's before our 1970 cutoff.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2974,10 +2969,10 @@
 # From Shanks & Pottenger.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
-			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
-			6:00 RussiaAsia DUS%sT	1991 Mar 31  2:00s
-			5:00	1:00	DUSST	1991 Sep  9  2:00s
-			5:00	-	TJT	# Tajikistan Time
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia +06/+07	1991 Mar 31  2:00s
+			5:00	1:00	+05/+06	1991 Sep  9  2:00s
+			5:00	-	+05
 
 # Thailand
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2991,11 +2986,10 @@
 # From Shanks & Pottenger.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
-			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
-			5:00 RussiaAsia	ASH%sT	1991 Mar 31  2:00
-			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
-			4:00 RussiaAsia	TM%sT	1992 Jan 19  2:00
-			5:00	-	TMT
+			4:00	-	+04	1930 Jun 21
+			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00
+			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00
+			5:00	-	+05
 
 # United Arab Emirates
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -3007,20 +3001,18 @@
 # Byalokoz 1919 says Uzbekistan was 4:27:53.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Samarkand	4:27:53 -	LMT	1924 May  2
-			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
-			5:00	-	SAMT	1981 Apr  1
-			5:00	1:00	SAMST	1981 Oct  1
-			6:00	-	TAST	1982 Apr  1 # Tashkent Time
-			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
+			4:00	-	+04	1930 Jun 21
+			5:00	-	+05	1981 Apr  1
+			5:00	1:00	+06	1981 Oct  1
+			6:00	-	+06	1982 Apr  1
+			5:00 RussiaAsia	+05/+06	1992
+			5:00	-	+05
 # Milne says Tashkent was 4:37:10.8; round to nearest.
 Zone	Asia/Tashkent	4:37:11 -	LMT	1924 May  2
-			5:00	-	TAST	1930 Jun 21 # Tashkent Time
-			6:00 RussiaAsia	TAS%sT	1991 Mar 31  2:00
-			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
-			5:00 RussiaAsia	UZ%sT	1992
-			5:00	-	UZT
+			5:00	-	+05	1930 Jun 21
+			6:00 RussiaAsia	+06/+07	1991 Mar 31  2:00
+			5:00 RussiaAsia	+05/+06	1992
+			5:00	-	+05
 
 # Vietnam
 
--- a/jdk/test/sun/util/calendar/zi/tzdata/australasia	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/australasia	Mon Oct 10 13:31:48 2016 -0700
@@ -568,7 +568,7 @@
 # Base the Bougainville entry on the Arawa-Kieta region, which appears to have
 # the most people even though it was devastated in the Bougainville Civil War.
 #
-# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates
+# Although Shanks gives 1942-03-15 / 1943-11-01 for UT +09, these dates
 # are apparently rough guesswork from the starts of military campaigns.
 # The World War II entries below are instead based on Arawa-Kieta.
 # The Japanese occupied Kieta in July 1942,
@@ -576,8 +576,8 @@
 # http://pwencycl.kgbudge.com/B/o/Bougainville.htm
 # and seem to have controlled it until their 1945-08-21 surrender.
 #
-# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11
-# on 2014-12-28 at 02:00.  They call UTC+11 "Bougainville Standard Time";
+# The Autonomous Region of Bougainville switched from UT +10 to +11
+# on 2014-12-28 at 02:00.  They call +11 "Bougainville Standard Time";
 # abbreviate this as BST.  See:
 # http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/
 #
@@ -643,7 +643,7 @@
 # From Paul Eggert (2014-06-27):
 # The International Date Line Act 2011
 # http://www.parliament.gov.ws/images/ACTS/International_Date_Line_Act__2011_-_Eng.pdf
-# changed Samoa from UTC-11 to UTC+13, effective "12 o'clock midnight, on
+# changed Samoa from UT -11 to +13, effective "12 o'clock midnight, on
 # Thursday 29th December 2011".  The International Date Line was adjusted
 # accordingly.
 
@@ -738,7 +738,7 @@
 # 1886-1891; Baker was similar but exact dates are not known.
 # Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
 # uninhabited thereafter.
-# Howland observed Hawaii Standard Time (UT-10:30) in 1937;
+# Howland observed Hawaii Standard Time (UT -10:30) in 1937;
 # see page 206 of Elgen M. Long and Marie K. Long,
 # Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
 # So most likely Howland and Baker observed Hawaii Time from 1935
@@ -1496,7 +1496,7 @@
 # Zealand time.  I understand that is the time they keep locally, anyhow."
 # For now, assume this practice goes back to the introduction of standard time
 # in New Zealand, as this would make Chatham Islands time almost exactly match
-# LMT back when New Zealand was at UTC+11:30; also, assume Chatham Islands did
+# LMT back when New Zealand was at UT +11:30; also, assume Chatham Islands did
 # not observe New Zealand's prewar DST.
 
 ###############################################################################
@@ -1552,7 +1552,7 @@
 # For now, we assume the Ladrones switched at the same time as the Philippines;
 # see Asia/Manila.
 
-# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
+# US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
 # under the name "Chamorro Standard Time".  There is no official abbreviation,
 # but Congressman Robert A. Underwood, author of the bill that became law,
 # wrote in a press release (2000-12-27) that he will seek the use of "ChST".
@@ -1564,15 +1564,15 @@
 # "I am certain, having lived there for the past decade, that 'Truk'
 # (now properly known as Chuuk) ... is in the time zone GMT+10."
 #
-# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
+# Shanks & Pottenger write that Truk switched from UT +10 to +11
 # on 1978-10-01; ignore this for now.
 
 # From Paul Eggert (1999-10-29):
 # The Federated States of Micronesia Visitors Board writes in
 # The Federated States of Micronesia - Visitor Information (1999-01-26)
 # http://www.fsmgov.org/info/clocks.html
-# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
-# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
+# We don't know when Kosrae switched from +12; assume January 1 for now.
 
 
 # Midway
@@ -1638,11 +1638,11 @@
 # ordaining - by a masterpiece of diplomatic flattery - that
 # the Fourth of July should be celebrated twice in that year."
 
-# Although Shanks & Pottenger says they both switched to UTC-11:30
-# in 1911, and to UTC-11 in 1950. many earlier sources give UTC-11
+# Although Shanks & Pottenger says they both switched to UT -11:30
+# in 1911, and to -11 in 1950. many earlier sources give -11
 # for American Samoa, e.g., the US National Bureau of Standards
 # circular "Standard Time Throughout the World", 1932.
-# Assume American Samoa switched to UTC-11 in 1911, not 1950,
+# Assume American Samoa switched to -11 in 1911, not 1950,
 # and that after 1950 they agreed until (western) Samoa skipped a
 # day in 2011.  Assume also that the Samoas follow the US and New
 # Zealand's "ST"/"DT" style of daylight-saving abbreviations.
--- a/jdk/test/sun/util/calendar/zi/tzdata/backward	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/backward	Mon Oct 10 13:31:48 2016 -0700
@@ -59,6 +59,7 @@
 Link	Asia/Urumqi		Asia/Kashgar
 Link	Asia/Kathmandu		Asia/Katmandu
 Link	Asia/Macau		Asia/Macao
+Link	Asia/Yangon		Asia/Rangoon
 Link	Asia/Ho_Chi_Minh	Asia/Saigon
 Link	Asia/Jerusalem		Asia/Tel_Aviv
 Link	Asia/Thimphu		Asia/Thimbu
--- a/jdk/test/sun/util/calendar/zi/tzdata/etcetera	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/etcetera	Mon Oct 10 13:31:48 2016 -0700
@@ -31,6 +31,13 @@
 # need now for the entries that are not on UTC are for ships at sea
 # that cannot use POSIX TZ settings.
 
+# Starting with POSIX 1003.1-2001, the entries below are all
+# unnecessary as settings for the TZ environment variable.  E.g.,
+# instead of TZ='Etc/GMT+4' one can use the POSIX setting TZ='<-04>+4'.
+#
+# Do not use a POSIX TZ setting like TZ='GMT+4', which is four hours
+# behind GMT but uses the completely misleading abbreviation "GMT".
+
 Zone	Etc/GMT		0	-	GMT
 Zone	Etc/UTC		0	-	UTC
 Zone	Etc/UCT		0	-	UCT
@@ -49,23 +56,13 @@
 Link	Etc/GMT				Etc/GMT+0
 Link	Etc/GMT				Etc/GMT0
 
-# We use POSIX-style signs in the Zone names and the output abbreviations,
+# Be consistent with POSIX TZ settings in the Zone names,
 # even though this is the opposite of what many people expect.
 # POSIX has positive signs west of Greenwich, but many people expect
 # positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
-# the abbreviation "GMT+4" and corresponds to 4 hours behind UT
+# the abbreviation "-04" and corresponds to 4 hours behind UT
 # (i.e. west of Greenwich) even though many people would expect it to
 # mean 4 hours ahead of UT (i.e. east of Greenwich).
-#
-# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
-# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
-# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
-# offset is kept within the angle bracket (and is used for display)
-# while the POSIX sign is kept outside the angle bracket (and is used
-# for calculation).
-#
-# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
-# GMT but uses the completely misleading abbreviation "GMT".
 
 # Earlier incarnations of this package were not POSIX-compliant,
 # and had lines such as
@@ -74,30 +71,31 @@
 # way does a
 #		zic -l GMT-12
 # so we moved the names into the Etc subdirectory.
+# Also, the time zone abbreviations are now compatible with %z.
 
-Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
-Zone	Etc/GMT-13	13	-	GMT-13
-Zone	Etc/GMT-12	12	-	GMT-12
-Zone	Etc/GMT-11	11	-	GMT-11
-Zone	Etc/GMT-10	10	-	GMT-10
-Zone	Etc/GMT-9	9	-	GMT-9
-Zone	Etc/GMT-8	8	-	GMT-8
-Zone	Etc/GMT-7	7	-	GMT-7
-Zone	Etc/GMT-6	6	-	GMT-6
-Zone	Etc/GMT-5	5	-	GMT-5
-Zone	Etc/GMT-4	4	-	GMT-4
-Zone	Etc/GMT-3	3	-	GMT-3
-Zone	Etc/GMT-2	2	-	GMT-2
-Zone	Etc/GMT-1	1	-	GMT-1
-Zone	Etc/GMT+1	-1	-	GMT+1
-Zone	Etc/GMT+2	-2	-	GMT+2
-Zone	Etc/GMT+3	-3	-	GMT+3
-Zone	Etc/GMT+4	-4	-	GMT+4
-Zone	Etc/GMT+5	-5	-	GMT+5
-Zone	Etc/GMT+6	-6	-	GMT+6
-Zone	Etc/GMT+7	-7	-	GMT+7
-Zone	Etc/GMT+8	-8	-	GMT+8
-Zone	Etc/GMT+9	-9	-	GMT+9
-Zone	Etc/GMT+10	-10	-	GMT+10
-Zone	Etc/GMT+11	-11	-	GMT+11
-Zone	Etc/GMT+12	-12	-	GMT+12
+Zone	Etc/GMT-14	14	-	+14
+Zone	Etc/GMT-13	13	-	+13
+Zone	Etc/GMT-12	12	-	+12
+Zone	Etc/GMT-11	11	-	+11
+Zone	Etc/GMT-10	10	-	+10
+Zone	Etc/GMT-9	9	-	+09
+Zone	Etc/GMT-8	8	-	+08
+Zone	Etc/GMT-7	7	-	+07
+Zone	Etc/GMT-6	6	-	+06
+Zone	Etc/GMT-5	5	-	+05
+Zone	Etc/GMT-4	4	-	+04
+Zone	Etc/GMT-3	3	-	+03
+Zone	Etc/GMT-2	2	-	+02
+Zone	Etc/GMT-1	1	-	+01
+Zone	Etc/GMT+1	-1	-	-01
+Zone	Etc/GMT+2	-2	-	-02
+Zone	Etc/GMT+3	-3	-	-03
+Zone	Etc/GMT+4	-4	-	-04
+Zone	Etc/GMT+5	-5	-	-05
+Zone	Etc/GMT+6	-6	-	-06
+Zone	Etc/GMT+7	-7	-	-07
+Zone	Etc/GMT+8	-8	-	-08
+Zone	Etc/GMT+9	-9	-	-09
+Zone	Etc/GMT+10	-10	-	-10
+Zone	Etc/GMT+11	-11	-	-11
+Zone	Etc/GMT+12	-12	-	-12
--- a/jdk/test/sun/util/calendar/zi/tzdata/europe	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/europe	Mon Oct 10 13:31:48 2016 -0700
@@ -98,8 +98,7 @@
 #        1:00       CET CEST CEMT Central Europe
 #        1:00:14    SET           Swedish (1879-1899)*
 #        2:00       EET EEST      Eastern Europe
-#        3:00       FET           Further-eastern Europe (2011-2014)*
-#        3:00       MSK MSD  MSM* Minsk, Moscow
+#        3:00       MSK MSD       Moscow
 
 # From Peter Ilieve (1994-12-04),
 # The original six [EU members]: Belgium, France, (West) Germany, Italy,
@@ -606,16 +605,33 @@
 Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
 Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
 
+
+# Daylight saving time for Russia and the Soviet Union
+#
+# The 1917-1921 decree URLs are from Alexander Belopolsky (2016-08-23).
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST  # Moscow Summer Time
+#
+# Decree No. 142 (1917-12-22) http://istmat.info/node/28137
 Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT  # Moscow Mean Time
+#
+# Decree No. 497 (1918-05-30) http://istmat.info/node/30001
 Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST # Moscow Double Summer Time
 Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
+#
+# Decree No. 258 (1919-05-29) http://istmat.info/node/37949
 Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
-Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	MSD
+#
+Rule	Russia	1919	only	-	Jul	 1	 0:00u	1:00	MSD
 Rule	Russia	1919	only	-	Aug	16	 0:00	0	MSK
+#
+# Decree No. 63 (1921-02-03) http://istmat.info/node/45840
 Rule	Russia	1921	only	-	Feb	14	23:00	1:00	MSD
-Rule	Russia	1921	only	-	Mar	20	23:00	2:00	MSM  # Midsummer
+#
+# Decree No. 121 (1921-03-07) http://istmat.info/node/45949
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	+05
+#
 Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	MSD
 Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
 # Act No. 925 of the Council of Ministers of the USSR (1980-10-24):
@@ -798,8 +814,6 @@
 # From Alexander Bokovoy (2014-10-09):
 # Belarussian government decided against changing to winter time....
 # http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
-# From Paul Eggert (2014-10-08):
-# Hence Belarus can share time zone abbreviations with Moscow again.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Minsk	1:50:16 -	LMT	1880
@@ -810,8 +824,7 @@
 			3:00	Russia	MSK/MSD	1990
 			3:00	-	MSK	1991 Mar 31  2:00s
 			2:00	Russia	EE%sT	2011 Mar 27  2:00s
-			3:00	-	FET	2014 Oct 26  1:00s
-			3:00	-	MSK
+			3:00	-	+03
 
 # Belgium
 #
@@ -1319,7 +1332,7 @@
 # http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
 # says that Bersarin issued an order to use Moscow time on May 20.
 # However, Moscow did not observe daylight saving in 1945, so
-# this was equivalent to CEMT (GMT+3), not GMT+4.
+# this was equivalent to UT +03, not +04.
 
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -2283,7 +2296,6 @@
 # http://www.worldtimezone.com/dst_news/dst_news_russia-map-2014-07.html
 
 # From Paul Eggert (2006-03-22):
-# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
 # Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
 # are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
 # except we follow Chernov's report that 1992 DST transitions were Sat
@@ -2359,7 +2371,7 @@
 			 2:00	Poland	CE%sT	1946
 			 3:00	Russia	MSK/MSD	1989 Mar 26  2:00s
 			 2:00	Russia	EE%sT	2011 Mar 27  2:00s
-			 3:00	-	FET	2014 Oct 26  2:00s
+			 3:00	-	+03	2014 Oct 26  2:00s
 			 2:00	-	EET
 
 
@@ -2412,6 +2424,16 @@
 # 78	RU-SPE	Saint Petersburg
 # 83	RU-NEN	Nenets Autonomous Okrug
 
+# From Paul Eggert (2016-08-23):
+# The Soviets switched to UT-based time in 1919.  Decree No. 59
+# (1919-02-08) http://istmat.info/node/35567 established UT-based time
+# zones, and Decree No. 147 (1919-03-29) http://istmat.info/node/35854
+# specified a transition date of 1919-07-01, apparently at 00:00 UT.
+# No doubt only the Soviet-controlled regions switched on that date;
+# later transitions to UT-based time in other parts of Russia are
+# taken from what appear to be guesses by Shanks.
+# (Thanks to Alexander Belopolsky for pointers to the decrees.)
+
 # From Stepan Golosunov (2016-03-07):
 # 11. Regions-violators, 1981-1982.
 # Wikipedia refers to
@@ -2453,7 +2475,7 @@
 # attributes the 1982 changes to the Act of the Council of Ministers
 # of the USSR No. 126 from 18.02.1982.  1980-925.txt also adds
 # Udmurtia to the list of affected territories and lists Khatangsky
-# district separately from Taymyr Autonomous Okurg.  Probably erroneously.
+# district separately from Taymyr Autonomous Okrug.  Probably erroneously.
 #
 # The affected territories are currently listed under Europe/Moscow,
 # Asia/Yekaterinburg and Asia/Krasnoyarsk.
@@ -2513,7 +2535,7 @@
 
 Zone Europe/Moscow	 2:30:17 -	LMT	1880
 			 2:30:17 -	MMT	1916 Jul  3 # Moscow Mean Time
-			 2:31:19 Russia	%s	1919 Jul  1  2:00
+			 2:31:19 Russia	%s	1919 Jul  1  0:00u
 			 3:00	Russia	%s	1921 Oct
 			 3:00	Russia	MSK/MSD	1922 Oct
 			 2:00	-	EET	1930 Jun 21
@@ -2596,22 +2618,21 @@
 # The 1988 transition is from USSR act No. 5 (1988-01-04).
 
 Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
-			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
-			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
-			 4:00	-	STAT	1961 Nov 11
-			 4:00	Russia	VOL%sT	1988 Mar 27  2:00s # Volgograd T
-			 3:00	Russia	VOL%sT	1991 Mar 31  2:00s
-			 4:00	-	VOLT	1992 Mar 29  2:00s
-			 3:00	Russia	MSK/MSD	2011 Mar 27  2:00s
-			 4:00	-	MSK	2014 Oct 26  2:00s
-			 3:00	-	MSK
+			 3:00	-	+03	1930 Jun 21
+			 4:00	-	+04	1961 Nov 11
+			 4:00	Russia	+04/+05	1988 Mar 27  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 4:00	-	+04	1992 Mar 29  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04	2014 Oct 26  2:00s
+			 3:00	-	+03
 
 # From Paul Eggert (2016-03-18):
 # Europe/Kirov covers:
 # 43	RU-KIR	Kirov Oblast
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
 #
-Zone Europe/Kirov	 3:18:48 -	LMT	1919 Jul  1  2:00
+Zone Europe/Kirov	 3:18:48 -	LMT	1919 Jul  1  0:00u
 			 3:00	-	+03	1930 Jun 21
 			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
 			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
@@ -2629,16 +2650,16 @@
 # Byalokoz 1919 says Samara was 3:20:20.
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
 
-Zone Europe/Samara	 3:20:20 -	LMT	1919 Jul  1  2:00
-			 3:00	-	SAMT	1930 Jun 21 # Samara Time
-			 4:00	-	SAMT	1935 Jan 27
-			 4:00	Russia	KUY%sT	1989 Mar 26  2:00s # Kuybyshev
-			 3:00	Russia	MSK/MSD	1991 Mar 31  2:00s
-			 2:00	Russia	EE%sT	1991 Sep 29  2:00s
-			 3:00	-	SAMT	1991 Oct 20  3:00
-			 4:00	Russia	SAM%sT	2010 Mar 28  2:00s
-			 3:00	Russia	SAM%sT	2011 Mar 27  2:00s
-			 4:00	-	SAMT
+Zone Europe/Samara	 3:20:20 -	LMT	1919 Jul  1  0:00u
+			 3:00	-	+03	1930 Jun 21
+			 4:00	-	+04	1935 Jan 27
+			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
+			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
+			 2:00	Russia	+02/+03	1991 Sep 29  2:00s
+			 3:00	-	+03	1991 Oct 20  3:00
+			 4:00	Russia	+04/+05	2010 Mar 28  2:00s
+			 3:00	Russia	+03/+04	2011 Mar 27  2:00s
+			 4:00	-	+04
 
 # From Paul Eggert (2016-03-18):
 # Europe/Ulyanovsk covers:
@@ -2653,7 +2674,7 @@
 # From Matt Johnson (2016-03-09):
 # http://publication.pravo.gov.ru/Document/View/0001201603090051
 
-Zone Europe/Ulyanovsk	 3:13:36 -	LMT	1919 Jul  1  2:00
+Zone Europe/Ulyanovsk	 3:13:36 -	LMT	1919 Jul  1  0:00u
 			 3:00	-	+03	1930 Jun 21
 			 4:00	Russia	+04/+05	1989 Mar 26  2:00s
 			 3:00	Russia	+03/+04	1991 Mar 31  2:00s
@@ -2685,12 +2706,12 @@
 
 Zone Asia/Yekaterinburg	 4:02:33 -	LMT	1916 Jul  3
 			 3:45:05 -	PMT	1919 Jul 15  4:00
-			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
-			 5:00	Russia	SVE%sT	1991 Mar 31  2:00s
-			 4:00	Russia	SVE%sT	1992 Jan 19  2:00s
-			 5:00	Russia	YEK%sT	2011 Mar 27  2:00s
-			 6:00	-	YEKT	2014 Oct 26  2:00s
-			 5:00	-	YEKT
+			 4:00	-	+04	1930 Jun 21
+			 5:00	Russia	+05/+06	1991 Mar 31  2:00s
+			 4:00	Russia	+04/+05	1992 Jan 19  2:00s
+			 5:00	Russia	+05/+06	2011 Mar 27  2:00s
+			 6:00	-	+06	2014 Oct 26  2:00s
+			 5:00	-	+05
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -2700,12 +2721,12 @@
 # Byalokoz 1919 says Omsk was 4:53:30.
 
 Zone Asia/Omsk		 4:53:30 -	LMT	1919 Nov 14
-			 5:00	-	OMST	1930 Jun 21 # Omsk Time
-			 6:00	Russia	OMS%sT	1991 Mar 31  2:00s
-			 5:00	Russia	OMS%sT	1992 Jan 19  2:00s
-			 6:00	Russia	OMS%sT	2011 Mar 27  2:00s
-			 7:00	-	OMST	2014 Oct 26  2:00s
-			 6:00	-	OMST
+			 5:00	-	+05	1930 Jun 21
+			 6:00	Russia	+06/+07	1991 Mar 31  2:00s
+			 5:00	Russia	+05/+06	1992 Jan 19  2:00s
+			 6:00	Russia	+06/+07	2011 Mar 27  2:00s
+			 7:00	-	+07	2014 Oct 26  2:00s
+			 6:00	-	+06
 
 # From Paul Eggert (2016-02-22):
 # Asia/Barnaul covers:
@@ -2785,7 +2806,7 @@
 # Note that time belts (numbered from 2 (Moscow) to 12 according to their
 # GMT/UTC offset and having too many exceptions like regions formally
 # belonging to one belt but using time from another) were replaced
-# with time zones in 2011 with different numberings (there was a
+# with time zones in 2011 with different numbering (there was a
 # 2-hour gap between second and third zones in 2011-2014).
 
 # From Stepan Golosunov (2016-04-12):
@@ -2868,12 +2889,12 @@
 # Byalokoz 1919 says Krasnoyarsk was 6:11:26.
 
 Zone Asia/Krasnoyarsk	 6:11:26 -	LMT	1920 Jan  6
-			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
-			 7:00	Russia	KRA%sT	1991 Mar 31  2:00s
-			 6:00	Russia	KRA%sT	1992 Jan 19  2:00s
-			 7:00	Russia	KRA%sT	2011 Mar 27  2:00s
-			 8:00	-	KRAT	2014 Oct 26  2:00s
-			 7:00	-	KRAT
+			 6:00	-	+06	1930 Jun 21
+			 7:00	Russia	+07/+08	1991 Mar 31  2:00s
+			 6:00	Russia	+06/+07	1992 Jan 19  2:00s
+			 7:00	Russia	+07/+08	2011 Mar 27  2:00s
+			 8:00	-	+08	2014 Oct 26  2:00s
+			 7:00	-	+07
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -2890,12 +2911,12 @@
 
 Zone Asia/Irkutsk	 6:57:05 -	LMT	1880
 			 6:57:05 -	IMT	1920 Jan 25 # Irkutsk Mean Time
-			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
-			 8:00	Russia	IRK%sT	1991 Mar 31  2:00s
-			 7:00	Russia	IRK%sT	1992 Jan 19  2:00s
-			 8:00	Russia	IRK%sT	2011 Mar 27  2:00s
-			 9:00	-	IRKT	2014 Oct 26  2:00s
-			 8:00	-	IRKT
+			 7:00	-	+07	1930 Jun 21
+			 8:00	Russia	+08/+09	1991 Mar 31  2:00s
+			 7:00	Russia	+07/+08	1992 Jan 19  2:00s
+			 8:00	Russia	+08/+09	2011 Mar 27  2:00s
+			 9:00	-	+09	2014 Oct 26  2:00s
+			 8:00	-	+08
 
 
 # From Tim Parenti (2014-07-06):
@@ -2912,13 +2933,13 @@
 # http://publication.pravo.gov.ru/Document/View/0001201512300107
 
 Zone Asia/Chita	 7:33:52 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2011 Mar 27  2:00s
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 8:00	-	IRKT	2016 Mar 27  2:00
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2011 Mar 27  2:00s
+			10:00	-	+10	2014 Oct 26  2:00s
+			 8:00	-	+08	2016 Mar 27  2:00
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -2958,12 +2979,12 @@
 # Byalokoz 1919 says Yakutsk was 8:38:58.
 
 Zone Asia/Yakutsk	 8:38:58 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2011 Mar 27  2:00s
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2011 Mar 27  2:00s
+			10:00	-	+10	2014 Oct 26  2:00s
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -2981,12 +3002,12 @@
 # Go with Byalokoz.
 
 Zone Asia/Vladivostok	 8:47:31 -	LMT	1922 Nov 15
-			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
-			10:00	Russia	VLA%sT	1991 Mar 31  2:00s
-			 9:00	Russia	VLA%sT	1992 Jan 19  2:00s
-			10:00	Russia	VLA%sT	2011 Mar 27  2:00s
-			11:00	-	VLAT	2014 Oct 26  2:00s
-			10:00	-	VLAT
+			 9:00	-	+09	1930 Jun 21
+			10:00	Russia	+10/+11	1991 Mar 31  2:00s
+			 9:00	Russia	+09/+10	1992 Jan 19  2:00s
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10
 
 
 # From Tim Parenti (2014-07-03):
@@ -3004,14 +3025,14 @@
 # This transition is no doubt wrong, but we have no better info.
 
 Zone Asia/Khandyga	 9:02:13 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAK%sT	1991 Mar 31  2:00s
-			 8:00	Russia	YAK%sT	1992 Jan 19  2:00s
-			 9:00	Russia	YAK%sT	2004
-			10:00	Russia	VLA%sT	2011 Mar 27  2:00s
-			11:00	-	VLAT	2011 Sep 13  0:00s # Decree 725?
-			10:00	-	YAKT	2014 Oct 26  2:00s
-			 9:00	-	YAKT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1991 Mar 31  2:00s
+			 8:00	Russia	+08/+09	1992 Jan 19  2:00s
+			 9:00	Russia	+09/+10	2004
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2011 Sep 13  0:00s # Decree 725?
+			10:00	-	+10	2014 Oct 26  2:00s
+			 9:00	-	+09
 
 
 # From Tim Parenti (2014-07-03):
@@ -3027,15 +3048,14 @@
 
 # The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long.
 Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
-			 9:00	-	JCST	1937 Oct  1
-			 9:00	-	JST	1945 Aug 25
-			11:00	Russia	SAK%sT	1991 Mar 31  2:00s # Sakhalin T
-			10:00	Russia	SAK%sT	1992 Jan 19  2:00s
-			11:00	Russia	SAK%sT	1997 Mar lastSun  2:00s
-			10:00	Russia	SAK%sT	2011 Mar 27  2:00s
-			11:00	-	SAKT	2014 Oct 26  2:00s
-			10:00	-	SAKT	2016 Mar 27  2:00s
-			11:00	-	SAKT
+			 9:00	-	+09	1945 Aug 25
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s # Sakhalin T
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	1997 Mar lastSun  2:00s
+			10:00	Russia	+10/+11	2011 Mar 27  2:00s
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10	2016 Mar 27  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
@@ -3058,13 +3078,13 @@
 # http://publication.pravo.gov.ru/Document/View/0001201604050038
 
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
-			10:00	-	MAGT	1930 Jun 21 # Magadan Time
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2014 Oct 26  2:00s
-			10:00	-	MAGT	2016 Apr 24  2:00s
-			11:00	-	MAGT
+			10:00	-	+10	1930 Jun 21 # Magadan Time
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2014 Oct 26  2:00s
+			10:00	-	+10	2016 Apr 24  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-06):
@@ -3107,17 +3127,14 @@
 # in Russian.)  In addition, Srednekolymsk appears to be a much older
 # settlement and the population of Zyryanka seems to be declining.
 # Go with Srednekolymsk.
-#
-# Since Magadan Oblast moves to UTC+10 on 2014-10-26, we cannot keep using MAGT
-# as the abbreviation.  Use SRET instead.
 
 Zone Asia/Srednekolymsk	10:14:52 -	LMT	1924 May  2
-			10:00	-	MAGT	1930 Jun 21 # Magadan Time
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2014 Oct 26  2:00s
-			11:00	-	SRET	# Srednekolymsk Time
+			10:00	-	+10	1930 Jun 21
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2014 Oct 26  2:00s
+			11:00	-	+11
 
 
 # From Tim Parenti (2014-07-03):
@@ -3135,14 +3152,14 @@
 # UTC+12 since at least then, too.
 
 Zone Asia/Ust-Nera	 9:32:54 -	LMT	1919 Dec 15
-			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
-			 9:00	Russia	YAKT	1981 Apr  1
-			11:00	Russia	MAG%sT	1991 Mar 31  2:00s
-			10:00	Russia	MAG%sT	1992 Jan 19  2:00s
-			11:00	Russia	MAG%sT	2011 Mar 27  2:00s
-			12:00	-	MAGT	2011 Sep 13  0:00s # Decree 725?
-			11:00	-	VLAT	2014 Oct 26  2:00s
-			10:00	-	VLAT
+			 8:00	-	+08	1930 Jun 21
+			 9:00	Russia	+09/+10	1981 Apr  1
+			11:00	Russia	+11/+12	1991 Mar 31  2:00s
+			10:00	Russia	+10/+11	1992 Jan 19  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12	2011 Sep 13  0:00s # Decree 725?
+			11:00	-	+11	2014 Oct 26  2:00s
+			10:00	-	+10
 
 
 # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
@@ -3155,12 +3172,12 @@
 # The Zone name should be Asia/Petropavlovsk-Kamchatski or perhaps
 # Asia/Petropavlovsk-Kamchatsky, but these are too long.
 Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
-			11:00	-	PETT	1930 Jun 21 # P-K Time
-			12:00	Russia	PET%sT	1991 Mar 31  2:00s
-			11:00	Russia	PET%sT	1992 Jan 19  2:00s
-			12:00	Russia	PET%sT	2010 Mar 28  2:00s
-			11:00	Russia	PET%sT	2011 Mar 27  2:00s
-			12:00	-	PETT
+			11:00	-	+11	1930 Jun 21
+			12:00	Russia	+12/+13	1991 Mar 31  2:00s
+			11:00	Russia	+11/+12	1992 Jan 19  2:00s
+			12:00	Russia	+12/+13	2010 Mar 28  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12
 
 
 # From Tim Parenti (2014-07-03):
@@ -3168,13 +3185,13 @@
 # 87	RU-CHU	Chukotka Autonomous Okrug
 
 Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
-			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
-			13:00	Russia	ANA%sT	1982 Apr  1  0:00s
-			12:00	Russia	ANA%sT	1991 Mar 31  2:00s
-			11:00	Russia	ANA%sT	1992 Jan 19  2:00s
-			12:00	Russia	ANA%sT	2010 Mar 28  2:00s
-			11:00	Russia	ANA%sT	2011 Mar 27  2:00s
-			12:00	-	ANAT
+			12:00	-	+12	1930 Jun 21
+			13:00	Russia	+13/+14	1982 Apr  1  0:00s
+			12:00	Russia	+12/+13	1991 Mar 31  2:00s
+			11:00	Russia	+11/+12	1992 Jan 19  2:00s
+			12:00	Russia	+12/+13	2010 Mar 28  2:00s
+			11:00	Russia	+11/+12	2011 Mar 27  2:00s
+			12:00	-	+12
 
 
 # San Marino
@@ -3495,6 +3512,14 @@
 # Engineered Standard Time," said Twitter user @aysekarahasan.
 # http://www.bbc.com/news/world-europe-34631326
 
+# From Burak AYDIN (2016-09-08):
+# Turkey will stay in Daylight Saving Time even in winter....
+# http://www.resmigazete.gov.tr/eskiler/2016/09/20160908-2.pdf
+#
+# From Paul Eggert (2016-09-07):
+# The change is permanent, so this is the new standard time in Turkey.
+# It takes effect today, which is not much notice.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
 Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
@@ -3558,7 +3583,7 @@
 Zone	Europe/Istanbul	1:55:52 -	LMT	1880
 			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
 			2:00	Turkey	EE%sT	1978 Oct 15
-			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
+			3:00	Turkey	+03/+04	1985 Apr 20
 			2:00	Turkey	EE%sT	2007
 			2:00	EU	EE%sT	2011 Mar 27  1:00u
 			2:00	-	EET	2011 Mar 28  1:00u
@@ -3566,7 +3591,8 @@
 			2:00	-	EET	2014 Mar 31  1:00u
 			2:00	EU	EE%sT	2015 Oct 25  1:00u
 			2:00	1:00	EEST	2015 Nov  8  1:00u
-			2:00	EU	EE%sT
+			2:00	EU	EE%sT	2016 Sep  7
+			3:00	-	+03
 Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
 
 # Ukraine
--- a/jdk/test/sun/util/calendar/zi/tzdata/factory	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/factory	Mon Oct 10 13:31:48 2016 -0700
@@ -24,9 +24,10 @@
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
-# For companies who don't want to put time zone specification in
-# their installation procedures.  When users run date, they'll get the message.
-# Also useful for the "comp.sources" version.
+# For distributors who don't want to put time zone specification in
+# their installation procedures.  Users that run 'date' will get the
+# time zone abbreviation "-00", indicating that the actual time zone
+# is unknown.
 
 # Zone	NAME	GMTOFF	RULES	FORMAT
-Zone	Factory	0	- "Local time zone must be set--see zic manual page"
+Zone	Factory	0	-	-00
--- a/jdk/test/sun/util/calendar/zi/tzdata/leapseconds	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/leapseconds	Mon Oct 10 13:31:48 2016 -0700
@@ -79,6 +79,7 @@
 Leap	2008	Dec	31	23:59:60	+	S
 Leap	2012	Jun	30	23:59:60	+	S
 Leap	2015	Jun	30	23:59:60	+	S
+Leap	2016	Dec	31	23:59:60	+	S
 
-#	Updated through IERS Bulletin C51
-#	File expires on:  28 December 2016
+#	Updated through IERS Bulletin C52
+#	File expires on:  28 June 2017
--- a/jdk/test/sun/util/calendar/zi/tzdata/northamerica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/northamerica	Mon Oct 10 13:31:48 2016 -0700
@@ -436,11 +436,42 @@
 # north of the Salmon River, and the towns of Burgdorf and Warren),
 # Nevada (except West Wendover), Oregon (except the northern 3/4 of
 # Malheur county), and Washington
+
+# From Paul Eggert (2016-08-20):
+# In early February 1948, in response to California's electricity shortage,
+# PG&E changed power frequency from 60 to 59.5 Hz during daylight hours,
+# causing electric clocks to lose six minutes per day.  (This did not change
+# legal time, and is not part of the data here.)  See:
+# Ross SA. An energy crisis from the past: Northern California in 1948.
+# Working Paper No. 8, Institute of Governmental Studies, UC Berkeley,
+# 1973-11.  http://escholarship.org/uc/item/8x22k30c
+#
+# In another measure to save electricity, DST was instituted from 1948-03-14
+# at 02:01 to 1949-01-16 at 02:00, with the governor having the option to move
+# the fallback transition earlier.  See pages 3-4 of:
+# http://clerk.assembly.ca.gov/sites/clerk.assembly.ca.gov/files/archive/Statutes/1948/48Vol1_Chapters.pdf
+#
+# In response:
+#
+#   Governor Warren received a torrent of objecting mail, and it is not too much
+#   to speculate that the objections to Daylight Saving Time were one important
+#   factor in the defeat of the Dewey-Warren Presidential ticket in California.
+#     -- Ross, p 25
+#
+# On December 8 the governor exercised the option, setting the date to January 1
+# (LA Times 1948-12-09).  The transition time was 02:00 (LA Times 1949-01-01).
+#
+# Despite the controversy, in 1949 California voters approved Proposition 12,
+# which established DST from April's last Sunday at 01:00 until September's
+# last Sunday at 02:00. This was amended by 1962's Proposition 6, which changed
+# the fall-back date to October's last Sunday. See:
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props
+# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
-Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
+Rule	CA	1948	only	-	Mar	14	2:01	1:00	D
 Rule	CA	1949	only	-	Jan	 1	2:00	0	S
-Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	CA	1950	1966	-	Apr	lastSun	1:00	1:00	D
 Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
 Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -3304,7 +3335,7 @@
 # indicating that the normal ET rules are followed.
 #
 # From Paul Eggert (2014-08-19):
-# The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round.  See:
+# The 2014-08-13 Cabinet meeting decided to stay on UT -04 year-round.  See:
 # http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
 # Model this as a switch from EST/EDT to AST ...
 # From Chris Walton (2014-11-04):
--- a/jdk/test/sun/util/calendar/zi/tzdata/southamerica	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/southamerica	Mon Oct 10 13:31:48 2016 -0700
@@ -433,9 +433,9 @@
 # stuck on Summer daylight savings time even though the summer is over.
 
 # From Paul Eggert (2013-09-05):
-# Perhaps San Luis operates on the legal fiction that it is at UTC-4
+# Perhaps San Luis operates on the legal fiction that it is at -04
 # with perpetual summer time, but ordinary usage typically seems to
-# just say it's at UTC-3; see, for example,
+# just say it's at -03; see, for example,
 # http://es.wikipedia.org/wiki/Hora_oficial_argentina
 # We've documented similar situations as being plain changes to
 # standard time, so let's do that here too.  This does not change UTC
--- a/jdk/test/sun/util/calendar/zi/tzdata/zone.tab	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/sun/util/calendar/zi/tzdata/zone.tab	Mon Oct 10 13:31:48 2016 -0700
@@ -284,7 +284,7 @@
 MH	+0905+16720	Pacific/Kwajalein	Kwajalein
 MK	+4159+02126	Europe/Skopje
 ML	+1239-00800	Africa/Bamako
-MM	+1647+09610	Asia/Rangoon
+MM	+1647+09610	Asia/Yangon
 MN	+4755+10653	Asia/Ulaanbaatar	Mongolia (most areas)
 MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
 MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jjs/addmodulesrepeat.js	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,17 @@
+/*
+ * This is the test JavaScript program used in jjs-modulepathTest.sh
+ */
+
+print("--module-path passed: " + $OPTIONS._module_path);
+print("--add-modules passed: " + $OPTIONS._add_modules);
+
+if ($OPTIONS._add_modules != "java.base,com.greetings") {
+    throw new Error("--add-modules values are not merged!");
+}
+
+var Hello = com.greetings.Hello;
+
+var moduleName = Hello.class.module.name;
+if (moduleName != "com.greetings") {
+    throw new Error("Expected module name to be com.greetings");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jjs/com.greetings/com/greetings/Hello.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.greetings;
+
+public class Hello {
+    public static String greet() {
+        return "Hello World!";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jjs/com.greetings/module-info.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module com.greetings {
+    exports com.greetings;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jjs/jjs-modulepathTest.sh	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+
+# @test
+# @bug 8167018
+# @summary Nashorn and jjs should support --module-path and --add-modules options
+# @run shell jjs-modulepathTest.sh
+# Tests --module-path option to set the module path for jjs
+
+. ${TESTSRC-.}/common.sh
+
+setup
+
+mkdir -p ${TESTCLASSES}/com.greetings
+rm -rf ${TESTCLASSES}/com.greetings
+
+${JAVAC} ${TESTSRC}/com.greetings/module-info.java \
+    ${TESTSRC}/com.greetings/com/greetings/*.java   \
+     -d ${TESTCLASSES}/com.greetings
+
+# no --add-modules passed. This should result in error.
+${JJS} -scripting --module-path ${TESTCLASSES} ${TESTSRC}/modulepath.js
+
+if [ $? -ne 0 ]; then
+   echo "Error thrown as expected when --add-modules is missing!"
+else
+   echo "Should have thrown error for missing --add-modules!"
+   exit 1
+fi
+
+# proper usage of --module-path with --add-modules
+${JJS} -scripting --module-path ${TESTCLASSES} --add-modules com.greetings ${TESTSRC}/modulepath.js
+if [ $? -ne 0 ]; then
+   exit 1
+fi
+
+# check that repeated --add-modules values are combined
+${JJS} -scripting --module-path ${TESTCLASSES} --add-modules java.base --add-modules com.greetings ${TESTSRC}/addmodulesrepeat.js
+if [ $? -ne 0 ]; then
+   exit 1
+fi
+
+rm -rf ${TESTCLASSES}/com.greetings
+echo "Passed"
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jjs/modulepath.js	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,21 @@
+/*
+ * This is the test JavaScript program used in jjs-modulepathTest.sh
+ */
+
+print("--module-path passed: " + $OPTIONS._module_path);
+print("--add-modules passed: " + $OPTIONS._add_modules);
+
+var Hello = com.greetings.Hello;
+var moduleName = Hello.class.module.name;
+if (moduleName != "com.greetings") {
+    throw new Error("Expected module name to be com.greetings");
+} else {
+    print("Module name is " + moduleName);
+}
+
+var msg = Hello.greet();
+if (msg != "Hello World!") {
+    throw new Error("Expected 'Hello World!'");
+} else {
+    print(msg);
+}
--- a/jdk/test/tools/jlink/JLinkNegativeTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/tools/jlink/JLinkNegativeTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -191,7 +191,7 @@
                     .output(imageFile)
                     .addMods("not_zip")
                     .modulePath(helper.defaultModulePath())
-                    .call().assertFailure("Error: java.util.zip.ZipException: zip file is empty");
+                    .call().assertFailure("Error: java.io.IOException: Invalid jmod file");
         } finally {
             deleteDirectory(jmod);
         }
@@ -236,13 +236,10 @@
         JImageGenerator.addFiles(module, new InMemoryFile("unknown/A.class", new byte[0]));
         try {
             Result result = helper.generateDefaultImage(moduleName);
-            if (result.getExitCode() != 4) {
+            System.err.println(result.getMessage());
+            if (result.getExitCode() == 0) {
                 throw new AssertionError("Crash expected");
             }
-            if (!result.getMessage().contains("java.lang.InternalError: unexpected entry: unknown")) {
-                System.err.println(result.getMessage());
-                throw new AssertionError("InternalError expected");
-            }
         } finally {
             deleteDirectory(module);
         }
@@ -250,7 +247,7 @@
 
     @Test(enabled = true)
     public void testSectionsAreFiles() throws IOException {
-        String moduleName = "module";
+        String moduleName = "hacked4";
         Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
         JImageGenerator.addFiles(jmod,
                 new InMemoryFile("/native", new byte[0]),
@@ -258,13 +255,10 @@
                 new InMemoryFile("/bin", new byte[0]));
         try {
             Result result = helper.generateDefaultImage(moduleName);
-            if (result.getExitCode() != 4) {
+            System.err.println(result.getMessage());
+            if (result.getExitCode() == 0) {
                 throw new AssertionError("Crash expected");
             }
-            if (!result.getMessage().contains("java.lang.InternalError: unexpected entry: ")) {
-                System.err.println(result.getMessage());
-                throw new AssertionError("InternalError expected");
-            }
         } finally {
             deleteDirectory(jmod);
         }
--- a/jdk/test/tools/jlink/JLinkTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/tools/jlink/JLinkTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -122,15 +122,6 @@
         }
 
         {
-            String moduleName = "filter";
-            Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
-            String className = "_A.class";
-            JImageGenerator.addFiles(jmod, new InMemoryFile(className, new byte[0]));
-            Path image = helper.generateDefaultImage(moduleName).assertSuccess();
-            helper.checkImage(image, moduleName, new String[] {"/" + moduleName + "/" + className}, null);
-        }
-
-        {
             String moduleName = "m"; // 8163382
             Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
             JImageGenerator.getJLinkTask()
--- a/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -92,7 +92,7 @@
 
         // Asterisk works exactly the same as above
         {
-            "*",
+            "--include-locales=*",
             "jdk.localedata",
             List.of(
                 "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
--- a/langtools/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -380,3 +380,4 @@
 af5eb8f3ffd21288305a54ea177ffad75021a741 jdk-9+135
 c8f02f0ecbd7cd6700f47416e4b7e9d5ec20ad77 jdk-9+136
 dd56c243c199a540c9f1fbff4855f0934b32a9d0 jdk-9+137
+90dd93e668a521642382561c47abe96ee2e065b7 jdk-9+138
--- a/langtools/make/gendata/Gendata-jdk.compiler.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/make/gendata/Gendata-jdk.compiler.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -52,7 +52,7 @@
 	$(RM) -r $(@D)
 	$(MKDIR) -p $(@D)
 	$(ECHO) Creating ct.sym classes
-	$(JAVA) $(INTERIM_LANGTOOLS_ARGS) \
+	$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
 	    $(COMPILECREATESYMBOLS_ADD_EXPORTS) \
 	    -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \
 	    build.tools.symbolgenerator.CreateSymbols \
--- a/langtools/make/gensrc/GensrcCommon.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/make/gensrc/GensrcCommon.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -32,12 +32,12 @@
 
 ################################################################################
 # The compileprops tools compiles a properties file into a resource bundle.
-TOOL_COMPILEPROPS_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
+TOOL_COMPILEPROPS_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
     compileproperties.CompileProperties -quiet
 
 ################################################################################
 # The compileprops tools compiles a properties file into an enum-like class.
-TOOL_PARSEPROPS_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
+TOOL_PARSEPROPS_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
     propertiesparser.PropertiesParser
 
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Mon Oct 10 13:31:48 2016 -0700
@@ -31,6 +31,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
+import java.util.function.Function;
 
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileManager.Location;
@@ -38,10 +39,14 @@
 import javax.tools.JavaFileObject.Kind;
 import javax.tools.StandardLocation;
 
+import com.sun.tools.javac.code.Symbol.Completer;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.jvm.ModuleNameReader;
+import com.sun.tools.javac.jvm.ModuleNameReader.BadClassFile;
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
+import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.JCDiagnostic;
 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
@@ -50,7 +55,6 @@
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
-import com.sun.tools.javac.util.StringUtils;
 
 import static com.sun.tools.javac.code.Kinds.Kind.*;
 
@@ -84,6 +88,10 @@
 
     private final JCDiagnostic.Factory diags;
 
+    private ModuleNameReader moduleNameReader;
+
+    public ModuleInfoSourceFileCompleter sourceFileCompleter;
+
     /** Get the ModuleFinder instance for this invocation. */
     public static ModuleFinder instance(Context context) {
         ModuleFinder instance = context.get(moduleFinderKey);
@@ -182,6 +190,8 @@
         return list;
     }
 
+    private boolean inFindSingleModule;
+
     public ModuleSymbol findSingleModule() {
         try {
             JavaFileObject src_fo = getModuleInfoFromLocation(StandardLocation.SOURCE_PATH, Kind.SOURCE);
@@ -194,26 +204,41 @@
             if (fo == null) {
                 msym = syms.unnamedModule;
             } else {
-                // Note: the following may trigger a re-entrant call to Modules.enter
-//                msym = new ModuleSymbol();
-//                ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym);
-//                info.modle = msym;
-//                info.classfile = fo;
-//                info.members_field = WriteableScope.create(info);
-//                msym.module_info = info;
-                msym = ModuleSymbol.create(null, names.module_info);
-                msym.module_info.classfile = fo;
-                msym.completer = sym -> classFinder.fillIn(msym.module_info);
-//                // TODO: should we do the following here, or as soon as we find the name in
-//                // the source or class file?
-//                // Consider the case when the class/source path module shadows one on the
-//                // module source path
-//                if (syms.modules.get(msym.name) != null) {
-//                    // error: module already defined
-//                    System.err.println("ERROR: module already defined: " + msym);
-//                } else {
-//                    syms.modules.put(msym.name, msym);
-//                }
+                switch (fo.getKind()) {
+                    case SOURCE:
+                        if (!inFindSingleModule) {
+                            try {
+                                inFindSingleModule = true;
+                                // Note: the following will trigger a re-entrant call to Modules.enter
+                                msym = sourceFileCompleter.complete(fo);
+                                msym.module_info.classfile = fo;
+                            } finally {
+                                inFindSingleModule = false;
+                            }
+                        } else {
+                            //the module-info.java does not contain a module declaration,
+                            //avoid infinite recursion:
+                            msym = syms.unnamedModule;
+                        }
+                        break;
+                    case CLASS:
+                        Name name;
+                        try {
+                            name = names.fromString(readModuleName(fo));
+                        } catch (BadClassFile | IOException ex) {
+                            //fillIn will report proper errors:
+                            name = names.error;
+                        }
+                        msym = syms.enterModule(name);
+                        msym.module_info.classfile = fo;
+                        msym.completer = Completer.NULL_COMPLETER;
+                        classFinder.fillIn(msym.module_info);
+                        break;
+                    default:
+                        Assert.error();
+                        msym = syms.unnamedModule;
+                        break;
+                }
             }
 
             msym.classLocation = StandardLocation.CLASS_OUTPUT;
@@ -224,6 +249,12 @@
         }
     }
 
+    private String readModuleName(JavaFileObject jfo) throws IOException, ModuleNameReader.BadClassFile {
+        if (moduleNameReader == null)
+            moduleNameReader = new ModuleNameReader();
+        return moduleNameReader.readModuleName(jfo);
+    }
+
     private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind) throws IOException {
         if (!fileManager.hasLocation(location))
             return null;
@@ -332,4 +363,8 @@
         }
     }
 
+    public interface ModuleInfoSourceFileCompleter {
+        public ModuleSymbol complete(JavaFileObject file);
+    }
+
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Oct 10 13:31:48 2016 -0700
@@ -916,7 +916,6 @@
 
         /**
          * Create a ModuleSymbol with an associated module-info ClassSymbol.
-         * The name of the module may be null, if it is not known yet.
          */
         public static ModuleSymbol create(Name name, Name module_info) {
             ModuleSymbol msym = new ModuleSymbol(name, null);
@@ -930,6 +929,7 @@
 
         public ModuleSymbol(Name name, Symbol owner) {
             super(MDL, 0, name, null, owner);
+            Assert.checkNonNull(name);
             this.type = new ModuleType(this);
         }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Oct 10 13:31:48 2016 -0700
@@ -764,17 +764,6 @@
         return msym;
     }
 
-    public void enterModule(ModuleSymbol msym, Name name) {
-        Assert.checkNull(modules.get(name));
-        Assert.checkNull(msym.name);
-        msym.name = name;
-        addRootPackageFor(msym);
-        ClassSymbol info = msym.module_info;
-        info.fullname = msym.name.append('.', names.module_info);
-        info.flatname = info.fullname;
-        modules.put(name, msym);
-    }
-
     public ModuleSymbol getModule(Name name) {
         return modules.get(name);
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Mon Oct 10 13:31:48 2016 -0700
@@ -292,15 +292,12 @@
             Name name = TreeInfo.fullName(decl.qualId);
             ModuleSymbol sym;
             if (c != null) {
-               sym = (ModuleSymbol) c.owner;
-               if (sym.name == null) {
-                   //ModuleFinder.findSingleModule creates a stub of a ModuleSymbol without a name,
-                   //fill the name here after the module-info.java has been parsed
-                   //also enter the ModuleSymbol among modules:
-                   syms.enterModule(sym, name);
-               } else {
-                   // TODO: validate name
-               }
+                sym = (ModuleSymbol) c.owner;
+                Assert.checkNonNull(sym.name);
+                Name treeName = TreeInfo.fullName(decl.qualId);
+                if (sym.name != treeName) {
+                    log.error(decl.pos(), Errors.ModuleNameMismatch(name, sym.name));
+                }
             } else {
                 sym = syms.enterModule(name);
                 if (sym.module_info.sourcefile != null && sym.module_info.sourcefile != toplevel.sourcefile) {
@@ -1006,6 +1003,10 @@
         return new Symbol.Completer() {
             @Override
             public void complete(Symbol sym) throws CompletionFailure {
+                if (inInitModules) {
+                    sym.completer = this;
+                    return ;
+                }
                 ModuleSymbol msym = (ModuleSymbol) sym;
                 Set<ModuleSymbol> allModules = allModules();
                 for (ModuleSymbol m : allModules) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Oct 10 13:31:48 2016 -0700
@@ -415,10 +415,10 @@
                 if (!isSameMemberWhenErased(dest, impl, impl_erasure))
                     return true;
 
-                // If the erasure of the return type is different, a
-                // bridge is needed.
-                return !types.isSameType(impl_erasure.getReturnType(),
-                                         method_erasure.getReturnType());
+                /* Bottom line: A bridge is needed if the erasure of the implementation
+                   is different from that of the method that it overrides.
+                */
+                return !types.isSameType(impl_erasure, method_erasure);
             } else {
                // method and impl are the same...
                 if ((method.flags() & ABSTRACT) != 0) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Oct 10 13:31:48 2016 -0700
@@ -80,6 +80,7 @@
 import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.jvm.ModuleNameReader;
 import com.sun.tools.javac.util.Pair;
 import com.sun.tools.javac.util.StringUtils;
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ModuleNameReader.java	Mon Oct 03 14:10:40 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-package com.sun.tools.javac.file;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import com.sun.tools.javac.jvm.ClassFile;
-
-import static com.sun.tools.javac.jvm.ClassFile.*;
-
-
-/**
- * Stripped down ClassReader, just sufficient to read module names from module-info.class files
- * while analyzing the module path.
- *
- * <p>
- * <b>This is NOT part of any supported API. If you write code that depends on this, you do so at
- * your own risk. This code and its internal interfaces are subject to change or deletion without
- * notice.</b>
- */
-public class ModuleNameReader {
-    static class BadClassFile extends Exception {
-        private static final long serialVersionUID = 0;
-        BadClassFile(String msg) {
-            super(msg);
-        }
-    }
-
-    private static final int INITIAL_BUFFER_SIZE = 0x0fff0;
-
-    /** The buffer containing the currently read class file.
-     */
-    private byte[] buf = new byte[INITIAL_BUFFER_SIZE];
-
-    /** The current input pointer.
-     */
-    private int bp;
-
-    /** The objects of the constant pool.
-     */
-    private Object[] poolObj;
-
-    /** For every constant pool entry, an index into buf where the
-     *  defining section of the entry is found.
-     */
-    private int[] poolIdx;
-
-    ModuleNameReader() {
-    }
-
-    String readModuleName(Path p) throws IOException, BadClassFile {
-        try (InputStream in = Files.newInputStream(p)) {
-            bp = 0;
-            buf = readInputStream(buf, in);
-
-            int magic = nextInt();
-            if (magic != JAVA_MAGIC)
-                throw new BadClassFile("illegal.start.of.class.file");
-
-            int minorVersion = nextChar();
-            int majorVersion = nextChar();
-
-            indexPool();
-
-            int accessflags = nextChar();
-            return readModuleInfoName(nextChar());
-        }
-    }
-
-    /** Extract a character at position bp from buf.
-     */
-    char getChar(int bp) {
-        return
-            (char)(((buf[bp] & 0xFF) << 8) + (buf[bp+1] & 0xFF));
-    }
-
-    /** Read a character.
-     */
-    char nextChar() {
-        return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
-    }
-
-    /** Read an integer.
-     */
-    int nextInt() {
-        return
-            ((buf[bp++] & 0xFF) << 24) +
-            ((buf[bp++] & 0xFF) << 16) +
-            ((buf[bp++] & 0xFF) << 8) +
-            (buf[bp++] & 0xFF);
-    }
-
-    /** Index all constant pool entries, writing their start addresses into
-     *  poolIdx.
-     */
-    void indexPool() throws BadClassFile {
-        poolIdx = new int[nextChar()];
-        poolObj = new Object[poolIdx.length];
-        int i = 1;
-        while (i < poolIdx.length) {
-            poolIdx[i++] = bp;
-            byte tag = buf[bp++];
-            switch (tag) {
-            case CONSTANT_Utf8: case CONSTANT_Unicode: {
-                int len = nextChar();
-                bp = bp + len;
-                break;
-            }
-            case CONSTANT_Class:
-            case CONSTANT_String:
-            case CONSTANT_MethodType:
-                bp = bp + 2;
-                break;
-            case CONSTANT_MethodHandle:
-                bp = bp + 3;
-                break;
-            case CONSTANT_Fieldref:
-            case CONSTANT_Methodref:
-            case CONSTANT_InterfaceMethodref:
-            case CONSTANT_NameandType:
-            case CONSTANT_Integer:
-            case CONSTANT_Float:
-            case CONSTANT_InvokeDynamic:
-                bp = bp + 4;
-                break;
-            case CONSTANT_Long:
-            case CONSTANT_Double:
-                bp = bp + 8;
-                i++;
-                break;
-            default:
-                throw new BadClassFile("malformed constant pool");
-            }
-        }
-    }
-
-    /** Read the class name of a module-info.class file.
-     * The name is stored in a CONSTANT_Class entry, where the
-     * class name is of the form module-name/module-info.
-     */
-    String readModuleInfoName(int i) throws BadClassFile {
-        int classIndex = poolIdx[i];
-        if (buf[classIndex] == CONSTANT_Class) {
-            int utf8Index = poolIdx[getChar(classIndex + 1)];
-            if (buf[utf8Index] == CONSTANT_Utf8) {
-                int len = getChar(utf8Index + 1);
-                int start = utf8Index + 3;
-                String suffix = "/module-info";
-                if (endsWith(buf, start, len, suffix))
-                    return new String(ClassFile.internalize(buf, start, len - suffix.length()));
-            }
-        }
-        throw new BadClassFile("bad module-info name");
-    }
-
-    private boolean endsWith(byte[] buf, int start, int len, String suffix) {
-        if (len <= suffix.length())
-            return false;
-        for (int i = 0; i < suffix.length(); i++) {
-            if (buf[start + len - suffix.length() + i] != suffix.charAt(i))
-                return false;
-        }
-        return true;
-    }
-
-    private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
-        try {
-            buf = ensureCapacity(buf, s.available());
-            int r = s.read(buf);
-            int bp = 0;
-            while (r != -1) {
-                bp += r;
-                buf = ensureCapacity(buf, bp);
-                r = s.read(buf, bp, buf.length - bp);
-            }
-            return buf;
-        } finally {
-            try {
-                s.close();
-            } catch (IOException e) {
-                /* Ignore any errors, as this stream may have already
-                 * thrown a related exception which is the one that
-                 * should be reported.
-                 */
-            }
-        }
-    }
-
-    /*
-     * ensureCapacity will increase the buffer as needed, taking note that
-     * the new buffer will always be greater than the needed and never
-     * exactly equal to the needed size or bp. If equal then the read (above)
-     * will infinitely loop as buf.length - bp == 0.
-     */
-    private static byte[] ensureCapacity(byte[] buf, int needed) {
-        if (buf.length <= needed) {
-            byte[] old = buf;
-            buf = new byte[Integer.highestOneBit(needed) << 1];
-            System.arraycopy(old, 0, buf, 0, old.length);
-        }
-        return buf;
-    }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Oct 10 13:31:48 2016 -0700
@@ -2396,12 +2396,15 @@
         } else {
             c.flags_field = flags;
             Name modInfoName = readModuleInfoName(nextChar());
-            if (c.owner.name == null) {
-                syms.enterModule((ModuleSymbol) c.owner, Convert.packagePart(modInfoName));
-            } else {
-                // TODO: validate name
+            currentModule = (ModuleSymbol) c.owner;
+            if (currentModule.name.append('.', names.module_info) != modInfoName) {
+                //strip trailing .module-info, if exists:
+                int modInfoStart = modInfoName.length() - names.module_info.length();
+                modInfoName = modInfoName.subName(modInfoStart, modInfoName.length()) == names.module_info &&
+                              modInfoName.charAt(modInfoStart - 1) == '.' ?
+                                  modInfoName.subName(0, modInfoStart - 1) : modInfoName;
+                throw badClassFile("module.name.mismatch", modInfoName, currentModule.name);
             }
-            currentModule = (ModuleSymbol) c.owner;
         }
 
         // class attributes must be read before class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ModuleNameReader.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 1999, 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.
+ */
+package com.sun.tools.javac.jvm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.jvm.ClassFile;
+
+import static com.sun.tools.javac.jvm.ClassFile.*;
+
+
+/**
+ * Stripped down ClassReader, just sufficient to read module names from module-info.class files
+ * while analyzing the module path.
+ *
+ * <p>
+ * <b>This is NOT part of any supported API. If you write code that depends on this, you do so at
+ * your own risk. This code and its internal interfaces are subject to change or deletion without
+ * notice.</b>
+ */
+public class ModuleNameReader {
+    public static class BadClassFile extends Exception {
+        private static final long serialVersionUID = 0;
+        BadClassFile(String msg) {
+            super(msg);
+        }
+    }
+
+    private static final int INITIAL_BUFFER_SIZE = 0x0fff0;
+
+    /** The buffer containing the currently read class file.
+     */
+    private byte[] buf = new byte[INITIAL_BUFFER_SIZE];
+
+    /** The current input pointer.
+     */
+    private int bp;
+
+    /** For every constant pool entry, an index into buf where the
+     *  defining section of the entry is found.
+     */
+    private int[] poolIdx;
+
+    public ModuleNameReader() {
+    }
+
+    public String readModuleName(Path p) throws IOException, BadClassFile {
+        try (InputStream in = Files.newInputStream(p)) {
+            return readModuleName(in);
+        }
+    }
+
+    public String readModuleName(JavaFileObject jfo) throws IOException, BadClassFile {
+        try (InputStream in = jfo.openInputStream()) {
+            return readModuleName(in);
+        }
+    }
+
+    public String readModuleName(InputStream in) throws IOException, BadClassFile {
+        bp = 0;
+        buf = readInputStream(buf, in);
+
+        int magic = nextInt();
+        if (magic != JAVA_MAGIC)
+            throw new BadClassFile("illegal.start.of.class.file");
+
+        int minorVersion = nextChar();
+        int majorVersion = nextChar();
+
+        indexPool();
+
+        int accessflags = nextChar();
+        return readModuleInfoName(nextChar());
+    }
+
+    /** Extract a character at position bp from buf.
+     */
+    char getChar(int bp) {
+        return
+            (char)(((buf[bp] & 0xFF) << 8) + (buf[bp+1] & 0xFF));
+    }
+
+    /** Read a character.
+     */
+    char nextChar() {
+        return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
+    }
+
+    /** Read an integer.
+     */
+    int nextInt() {
+        return
+            ((buf[bp++] & 0xFF) << 24) +
+            ((buf[bp++] & 0xFF) << 16) +
+            ((buf[bp++] & 0xFF) << 8) +
+            (buf[bp++] & 0xFF);
+    }
+
+    /** Index all constant pool entries, writing their start addresses into
+     *  poolIdx.
+     */
+    void indexPool() throws BadClassFile {
+        poolIdx = new int[nextChar()];
+        int i = 1;
+        while (i < poolIdx.length) {
+            poolIdx[i++] = bp;
+            byte tag = buf[bp++];
+            switch (tag) {
+            case CONSTANT_Utf8: case CONSTANT_Unicode: {
+                int len = nextChar();
+                bp = bp + len;
+                break;
+            }
+            case CONSTANT_Class:
+            case CONSTANT_String:
+            case CONSTANT_MethodType:
+                bp = bp + 2;
+                break;
+            case CONSTANT_MethodHandle:
+                bp = bp + 3;
+                break;
+            case CONSTANT_Fieldref:
+            case CONSTANT_Methodref:
+            case CONSTANT_InterfaceMethodref:
+            case CONSTANT_NameandType:
+            case CONSTANT_Integer:
+            case CONSTANT_Float:
+            case CONSTANT_InvokeDynamic:
+                bp = bp + 4;
+                break;
+            case CONSTANT_Long:
+            case CONSTANT_Double:
+                bp = bp + 8;
+                i++;
+                break;
+            default:
+                throw new BadClassFile("malformed constant pool");
+            }
+        }
+    }
+
+    /** Read the class name of a module-info.class file.
+     * The name is stored in a CONSTANT_Class entry, where the
+     * class name is of the form module-name/module-info.
+     */
+    String readModuleInfoName(int i) throws BadClassFile {
+        int classIndex = poolIdx[i];
+        if (buf[classIndex] == CONSTANT_Class) {
+            int utf8Index = poolIdx[getChar(classIndex + 1)];
+            if (buf[utf8Index] == CONSTANT_Utf8) {
+                int len = getChar(utf8Index + 1);
+                int start = utf8Index + 3;
+                String suffix = "/module-info";
+                if (endsWith(buf, start, len, suffix))
+                    return new String(ClassFile.internalize(buf, start, len - suffix.length()));
+            }
+        }
+        throw new BadClassFile("bad module-info name");
+    }
+
+    private boolean endsWith(byte[] buf, int start, int len, String suffix) {
+        if (len <= suffix.length())
+            return false;
+        for (int i = 0; i < suffix.length(); i++) {
+            if (buf[start + len - suffix.length() + i] != suffix.charAt(i))
+                return false;
+        }
+        return true;
+    }
+
+    private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
+        try {
+            buf = ensureCapacity(buf, s.available());
+            int r = s.read(buf);
+            int bp = 0;
+            while (r != -1) {
+                bp += r;
+                buf = ensureCapacity(buf, bp);
+                r = s.read(buf, bp, buf.length - bp);
+            }
+            return buf;
+        } finally {
+            try {
+                s.close();
+            } catch (IOException e) {
+                /* Ignore any errors, as this stream may have already
+                 * thrown a related exception which is the one that
+                 * should be reported.
+                 */
+            }
+        }
+    }
+
+    /*
+     * ensureCapacity will increase the buffer as needed, taking note that
+     * the new buffer will always be greater than the needed and never
+     * exactly equal to the needed size or bp. If equal then the read (above)
+     * will infinitely loop as buf.length - bp == 0.
+     */
+    private static byte[] ensureCapacity(byte[] buf, int needed) {
+        if (buf.length <= needed) {
+            byte[] old = buf;
+            buf = new byte[Integer.highestOneBit(needed) << 1];
+            System.arraycopy(old, 0, buf, 0, old.length);
+        }
+        return buf;
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Oct 10 13:31:48 2016 -0700
@@ -37,6 +37,7 @@
 import java.util.Queue;
 import java.util.ResourceBundle;
 import java.util.Set;
+import java.util.function.Function;
 
 import javax.annotation.processing.Processor;
 import javax.lang.model.SourceVersion;
@@ -67,7 +68,9 @@
 import com.sun.tools.javac.tree.JCTree.JCLambda;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.Tag;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.JCDiagnostic.Factory;
@@ -341,6 +344,13 @@
                 }
             };
 
+    protected final ModuleFinder.ModuleInfoSourceFileCompleter moduleInfoSourceFileCompleter =
+            fo -> (ModuleSymbol) readSourceFile(parseImplicitFile(fo), null, tl -> {
+                return tl.defs.nonEmpty() && tl.defs.head.hasTag(Tag.MODULEDEF) ?
+                        ((JCModuleDecl) tl.defs.head).sym.module_info :
+                        syms.defineClass(names.module_info, syms.errModule);
+            }).owner;
+
     /**
      * Command line options.
      */
@@ -411,6 +421,7 @@
         diags = Factory.instance(context);
 
         finder.sourceCompleter = sourceCompleter;
+        moduleFinder.sourceFileCompleter = moduleInfoSourceFileCompleter;
 
         options = Options.instance(context);
 
@@ -779,6 +790,19 @@
         readSourceFile(null, c);
     }
 
+    private JCTree.JCCompilationUnit parseImplicitFile(JavaFileObject filename) {
+        JavaFileObject prev = log.useSource(filename);
+        try {
+            JCTree.JCCompilationUnit t = parse(filename, filename.getCharContent(false));
+            return t;
+        } catch (IOException e) {
+            log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
+            return make.TopLevel(List.<JCTree>nil());
+        } finally {
+            log.useSource(prev);
+        }
+    }
+
     /** Compile a ClassSymbol from source, optionally using the given compilation unit as
      *  the source tree.
      *  @param tree the compilation unit in which the given ClassSymbol resides,
@@ -789,20 +813,20 @@
         if (completionFailureName == c.fullname) {
             throw new CompletionFailure(c, "user-selected completion failure by class name");
         }
-        JavaFileObject filename = c.classfile;
-        JavaFileObject prev = log.useSource(filename);
 
         if (tree == null) {
-            try {
-                tree = parse(filename, filename.getCharContent(false));
-            } catch (IOException e) {
-                log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
-                tree = make.TopLevel(List.<JCTree>nil());
-            } finally {
-                log.useSource(prev);
-            }
+            tree = parseImplicitFile(c.classfile);
         }
 
+        readSourceFile(tree, c, cut -> c);
+    }
+
+    private ClassSymbol readSourceFile(JCCompilationUnit tree,
+                                       ClassSymbol expectedSymbol,
+                                       Function<JCCompilationUnit, ClassSymbol> symbolGetter)
+                                           throws CompletionFailure {
+        Assert.checkNonNull(tree);
+
         if (!taskListener.isEmpty()) {
             TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
             taskListener.started(e);
@@ -814,18 +838,20 @@
         // Note that if module resolution failed, we may not even
         // have enough modules available to access java.lang, and
         // so risk getting FatalError("no.java.lang") from MemberEnter.
-        if (!modules.enter(List.of(tree), c)) {
-            throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
+        if (!modules.enter(List.of(tree), expectedSymbol)) {
+            throw new CompletionFailure(symbolGetter.apply(tree),
+                                        diags.fragment("cant.resolve.modules"));
         }
 
-        enter.complete(List.of(tree), c);
+        enter.complete(List.of(tree), expectedSymbol);
 
         if (!taskListener.isEmpty()) {
             TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
             taskListener.finished(e);
         }
 
-        if (enter.getEnv(c) == null) {
+        ClassSymbol sym = symbolGetter.apply(tree);
+        if (sym == null || enter.getEnv(sym) == null) {
             boolean isPkgInfo =
                 tree.sourcefile.isNameCompatible("package-info",
                                                  JavaFileObject.Kind.SOURCE);
@@ -836,24 +862,26 @@
                 if (enter.getEnv(tree.modle) == null) {
                     JCDiagnostic diag =
                         diagFactory.fragment("file.does.not.contain.module");
-                    throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
+                    throw new ClassFinder.BadClassFile(sym, tree.sourcefile, diag, diagFactory);
                 }
             } else if (isPkgInfo) {
                 if (enter.getEnv(tree.packge) == null) {
                     JCDiagnostic diag =
                         diagFactory.fragment("file.does.not.contain.package",
-                                                 c.location());
-                    throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
+                                                 sym.location());
+                    throw new ClassFinder.BadClassFile(sym, tree.sourcefile, diag, diagFactory);
                 }
             } else {
                 JCDiagnostic diag =
                         diagFactory.fragment("file.doesnt.contain.class",
-                                            c.getQualifiedName());
-                throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
+                                            sym.getQualifiedName());
+                throw new ClassFinder.BadClassFile(sym, tree.sourcefile, diag, diagFactory);
             }
         }
 
         implicitSourceFilesRead = true;
+
+        return sym;
     }
 
     /** Track when the JavaCompiler has been used to compile something. */
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Mon Oct 10 13:31:48 2016 -0700
@@ -425,8 +425,7 @@
     J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) {
         @Override
         public boolean process(OptionHelper helper, String option) {
-            throw new AssertionError
-                ("the -J flag should be caught by the launcher.");
+            throw new AssertionError("the -J flag should be caught by the launcher.");
         }
     },
 
@@ -691,7 +690,7 @@
          * This option takes an argument.
          * If the name of option ends with ':' or '=', the argument must be provided directly
          * after that separator.
-         * Otherwise, if may appear after an '=' or in the following argument position.
+         * Otherwise, it may appear after an '=' or in the following argument position.
          */
         REQUIRED,
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1336,8 +1336,7 @@
 
         errorStatus = errorStatus || (compiler.errorCount() > 0);
 
-        if (!errorStatus)
-            round.finalCompiler();
+        round.finalCompiler();
 
         if (newSourceFiles.size() > 0)
             roots = roots.appendList(compiler.parseFiles(newSourceFiles));
@@ -1350,10 +1349,8 @@
         if (!taskListener.isEmpty())
             taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
 
-        if (errorStatus) {
-            if (compiler.errorCount() == 0)
-                compiler.log.nerrors++;
-            return true;
+        if (errorStatus && compiler.errorCount() == 0) {
+            compiler.log.nerrors++;
         }
 
         compiler.enterTreesIfNeeded(roots);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Oct 10 13:31:48 2016 -0700
@@ -2770,6 +2770,10 @@
 compiler.err.module.name.mismatch=\
     module name {0} does not match expected name {1}
 
+# 0: name, 1: name
+compiler.misc.module.name.mismatch=\
+    module name {0} does not match expected name {1}
+
 compiler.err.module.decl.sb.in.module-info.java=\
     module declarations should be in a file named module-info.java
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTool.java	Mon Oct 10 13:31:48 2016 -0700
@@ -165,9 +165,11 @@
     public int isSupportedOption(String option) {
         if (option == null)
             throw new NullPointerException();
-        for (ToolOption o: ToolOption.values()) {
-            if (o.opt.equals(option))
-                return o.hasArg ? 1 : 0;
+        for (ToolOption o : ToolOption.values()) {
+            for (String name : o.names) {
+                if (name.equals(option))
+                    return o.hasArg ? 1 : 0;
+            }
         }
         return -1;
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Mon Oct 10 13:31:48 2016 -0700
@@ -595,8 +595,9 @@
 
     @Override
     public Set<Doclet.Option> getSupportedOptions() {
+        Resources resources = getResources();
         Doclet.Option[] options = {
-            new Option(this, "-bottom", 1) {
+            new Option(resources, "-bottom", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -604,7 +605,7 @@
                     return true;
                 }
             },
-            new Option(this, "-charset", 1) {
+            new Option(resources, "-charset", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -612,7 +613,7 @@
                     return true;
                 }
             },
-            new Option(this, "-doctitle", 1) {
+            new Option(resources, "-doctitle", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -620,7 +621,7 @@
                     return true;
                 }
             },
-            new Option(this, "-footer", 1) {
+            new Option(resources, "-footer", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -628,7 +629,7 @@
                     return true;
                 }
             },
-            new Option(this, "-header", 1) {
+            new Option(resources, "-header", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -636,7 +637,7 @@
                     return true;
                 }
             },
-            new Option(this, "-helpfile", 1) {
+            new Option(resources, "-helpfile", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -644,7 +645,7 @@
                     return true;
                 }
             },
-            new Option(this, "-html4") {
+            new Option(resources, "-html4") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -652,7 +653,7 @@
                     return true;
                 }
             },
-            new Option(this, "-html5") {
+            new Option(resources, "-html5") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -660,7 +661,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nohelp") {
+            new Option(resources, "-nohelp") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -668,7 +669,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nodeprecatedlist") {
+            new Option(resources, "-nodeprecatedlist") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -676,7 +677,7 @@
                     return true;
                 }
             },
-            new Option(this, "-noindex") {
+            new Option(resources, "-noindex") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -684,7 +685,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nonavbar") {
+            new Option(resources, "-nonavbar") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -692,7 +693,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-nooverview") {
+            new Hidden(resources, "-nooverview") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -700,7 +701,7 @@
                     return true;
                 }
             },
-            new Option(this, "-notree") {
+            new Option(resources, "-notree") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -708,7 +709,7 @@
                     return true;
                 }
             },
-            new Option(this, "-overview", 1) {
+            new Option(resources, "-overview", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -716,7 +717,7 @@
                     return true;
                 }
             },
-            new Option(this, "--frames") {
+            new Option(resources, "--frames") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -724,7 +725,7 @@
                     return true;
                 }
             },
-            new Option(this, "--no-frames") {
+            new Option(resources, "--no-frames") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -732,7 +733,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-packagesheader", 1) {
+            new Hidden(resources, "-packagesheader", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -740,7 +741,7 @@
                     return true;
                 }
             },
-            new Option(this, "-splitindex") {
+            new Option(resources, "-splitindex") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -748,7 +749,7 @@
                     return true;
                 }
             },
-            new Option(this, "-stylesheetfile", 1) {
+            new Option(resources, "-stylesheetfile", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -756,7 +757,7 @@
                     return true;
                 }
             },
-            new Option(this, "-top", 1) {
+            new Option(resources, "-top", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -764,7 +765,7 @@
                     return true;
                 }
             },
-            new Option(this, "-use") {
+            new Option(resources, "-use") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -772,7 +773,7 @@
                     return true;
                 }
             },
-            new Option(this, "-windowtitle", 1) {
+            new Option(resources, "-windowtitle", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -780,7 +781,7 @@
                     return true;
                 }
             },
-            new XOption(this, "-Xdoclint") {
+            new XOption(resources, "-Xdoclint") {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -788,7 +789,7 @@
                     return true;
                 }
             },
-            new XOption(this, "-Xdocrootparent", 1) {
+            new XOption(resources, "-Xdocrootparent", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -796,7 +797,7 @@
                     return true;
                 }
             },
-            new XOption(this, "doclet.xusage.xdoclint-extended.", "-Xdoclint:", 0) {
+            new XOption(resources, "doclet.usage.xdoclint-extended", "-Xdoclint:", 0) {
                 @Override
                 public boolean matches(String option) {
                     return option.toLowerCase().startsWith(getName().toLowerCase());
@@ -809,7 +810,7 @@
                     return true;
                 }
             },
-            new XOption(this, "doclet.xusage.xdoclint-package.", "-Xdoclint/package:", 0) {
+            new XOption(resources, "doclet.usage.xdoclint-package", "-Xdoclint/package:", 0) {
                 @Override
                 public boolean matches(String option) {
                     return option.toLowerCase().startsWith(getName().toLowerCase());
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Mon Oct 10 13:31:48 2016 -0700
@@ -191,144 +191,196 @@
 doclet.Same_package_name_used=Package name format used twice: {0}
 
 # option specifiers
-doclet.usage.d.parameters=<directory>
-doclet.usage.d.description=Destination directory for output files
+doclet.usage.d.parameters=\
+    <directory>
+doclet.usage.d.description=\
+    Destination directory for output files
 
-doclet.usage.use.description=Create class and package usage pages
-
-doclet.usage.version.description=Include @version paragraphs
+doclet.usage.use.description=\
+    Create class and package usage pages
 
-doclet.usage.author.description=Include @author paragraphs
+doclet.usage.version.description=\
+    Include @version paragraphs
 
-doclet.usage.docfilessubdirs.description=Recursively copy doc-file subdirectories
+doclet.usage.author.description=\
+    Include @author paragraphs
 
-doclet.usage.splitindex.description=Split index into one file per letter
+doclet.usage.docfilessubdirs.description=\
+    Recursively copy doc-file subdirectories
 
-doclet.usage.overview.parameters=<file>
-doclet.usage.overview.description=Read overview documentation from HTML file
+doclet.usage.splitindex.description=\
+    Split index into one file per letter
 
+doclet.usage.overview.parameters=\
+    <file>
+doclet.usage.overview.description=\
+    Read overview documentation from HTML file
 
-doclet.usage.windowtitle.parameters=<text>
-doclet.usage.windowtitle.description=Browser window title for the documentation
-
-doclet.usage.doctitle.parameters=<html-code>
-doclet.usage.doctitle.description=Include title for the overview page
+doclet.usage.windowtitle.parameters=\
+    <text>
+doclet.usage.windowtitle.description=\
+    Browser window title for the documentation
 
-doclet.usage.header.parameters=<html-code>
-doclet.usage.header.description=Include header text for each page
-
-doclet.usage.html4.description=Generate HTML 4.01 output
+doclet.usage.doctitle.parameters=\
+    <html-code>
+doclet.usage.doctitle.description=\
+    Include title for the overview page
 
-doclet.usage.html5.description=Generate HTML 5 output
+doclet.usage.header.parameters=\
+    <html-code>
+doclet.usage.header.description=\
+    Include header text for each page
 
-doclet.usage.footer.parameters=<html-code>
-doclet.usage.footer.description=Include footer text for each page
+doclet.usage.html4.description=\
+    Generate HTML 4.01 output
+
+doclet.usage.html5.description=\
+    Generate HTML 5 output
 
-doclet.usage.top.parameters=<html-code>
-doclet.usage.top.description=Include top text for each page
+doclet.usage.footer.parameters=\
+    <html-code>
+doclet.usage.footer.description=\
+    Include footer text for each page
 
-doclet.usage.bottom.parameters=<html-code>
-doclet.usage.bottom.description=Include bottom text for each page
-
-doclet.usage.link.parameters=<url>
-doclet.usage.link.description=Create links to javadoc output at <url>
+doclet.usage.top.parameters=\
+    <html-code>
+doclet.usage.top.description=\
+    Include top text for each page
 
-doclet.usage.linkoffline.parameters=<url1> <url2>
-doclet.usage.linkoffline.description=Link to docs at <url1> using package list\n\
-\                                   at <url2>
+doclet.usage.bottom.parameters=\
+    <html-code>
+doclet.usage.bottom.description=\
+    Include bottom text for each page
 
-doclet.usage.excludedocfilessubdir.parameters=<name>:..
-doclet.usage.excludedocfilessubdir.description=\n\
-\                                   Exclude any doc-files subdirectories with\n\
-\                                   given name
+doclet.usage.link.parameters=\
+    <url>
+doclet.usage.link.description=\
+    Create links to javadoc output at <url>
 
-doclet.usage.group.parameters=<name> <p1>:<p2>..
-doclet.usage.group.description=Group specified packages together\n\
-\                                   in overview page
+doclet.usage.linkoffline.parameters=\
+    <url1> <url2>
+doclet.usage.linkoffline.description=\
+    Link to docs at <url1> using package list at <url2>
 
-doclet.usage.nocomment.description=Suppress description and tags, generate\n\
-\                                   only declarations
-
-doclet.usage.nodeprecated.description=Do not include @deprecated information
+doclet.usage.excludedocfilessubdir.parameters=\
+    <name>:..
+doclet.usage.excludedocfilessubdir.description=\
+    Exclude any doc-files subdirectories with given name
 
-doclet.usage.noqualifier.parameters=<name1>:<name2>:..
-doclet.usage.noqualifier.description=Exclude the list of qualifiers from the output
+doclet.usage.group.parameters=\
+    <name> <p1>:<p2>..
+doclet.usage.group.description=\
+    Group specified packages together in overview page
 
-doclet.usage.nosince.description=Do not include @since information
+doclet.usage.nocomment.description=\
+    Suppress description and tags, generate only declarations
 
-doclet.usage.notimestamp.description=Do not include hidden time stamp
+doclet.usage.nodeprecated.description=\
+    Do not include @deprecated information
 
-doclet.usage.nodeprecatedlist.description=Do not generate deprecated list
+doclet.usage.noqualifier.parameters=\
+    <name1>:<name2>:..
+doclet.usage.noqualifier.description=\
+    Exclude the list of qualifiers from the output
 
-doclet.usage.notree.description=Do not generate class hierarchy
+doclet.usage.nosince.description=\
+    Do not include @since information
 
-doclet.usage.noindex.description=Do not generate index
+doclet.usage.notimestamp.description=\
+    Do not include hidden time stamp
 
-doclet.usage.nohelp.description=Do not generate help link
+doclet.usage.nodeprecatedlist.description=\
+    Do not generate deprecated list
 
-doclet.usage.nonavbar.description=Do not generate navigation bar
+doclet.usage.notree.description=\
+    Do not generate class hierarchy
 
-doclet.usage.nooverview.description=Do not generate overview pages
+doclet.usage.noindex.description=\
+    Do not generate index
 
-doclet.usage.serialwarn.description=Generate warning about @serial tag
+doclet.usage.nohelp.description=\
+    Do not generate help link
+
+doclet.usage.nonavbar.description=\
+    Do not generate navigation bar
 
-doclet.usage.tag.parameters=<name>:<locations>:<header>
-doclet.usage.tag.description=\n\
-\                                   Specify single argument custom tags
+doclet.usage.nooverview.description=\
+    Do not generate overview pages
 
-doclet.usage.taglet.description=The fully qualified name of Taglet to register
+doclet.usage.serialwarn.description=\
+    Generate warning about @serial tag
 
-doclet.usage.tagletpath.description=The path to Taglets
+doclet.usage.tag.parameters=\
+    <name>:<locations>:<header>
+doclet.usage.tag.description=\
+    Specify single argument custom tags
 
-doclet.usage.charset.parameters=<charset>
-doclet.usage.charset.description=Charset for cross-platform viewing of\n\
-\                                   generated documentation
+doclet.usage.taglet.description=\
+    The fully qualified name of Taglet to register
 
-doclet.usage.helpfile.parameters=<file>
-doclet.usage.helpfile.description=Include file that help link links to
+doclet.usage.tagletpath.description=\
+    The path to Taglets
 
-doclet.usage.linksource.description=Generate source in HTML
+doclet.usage.charset.parameters=\
+    <charset>
+doclet.usage.charset.description=\
+    Charset for cross-platform viewing of generated documentation
 
-doclet.usage.sourcetab.parameters=<tab length>
-doclet.usage.sourcetab.description=Specify the number of spaces each tab\n\
-\                                   takes up in the source
+doclet.usage.helpfile.parameters=\
+    <file>
+doclet.usage.helpfile.description=\
+    Include file that help link links to
 
-doclet.usage.keywords.description=Include HTML meta tags with package,\n\
-\                                   class and member info
+doclet.usage.linksource.description=\
+    Generate source in HTML
 
-doclet.usage.stylesheetfile.parameters=<path>
-doclet.usage.stylesheetfile.description=File to change style of the generated\n\
-\                                   documentation
+doclet.usage.sourcetab.parameters=\
+    <tab length>
+doclet.usage.sourcetab.description=\
+    Specify the number of spaces each tab takes up in the source
 
-doclet.usage.docencoding.parameters=<name>
-doclet.usage.docencoding.description=Specify the character encoding for the output
-
-doclet.usage.frames.description=Enable the use of frames in the generated output (default)
+doclet.usage.keywords.description=\
+    Include HTML meta tags with package, class and member info
 
-doclet.usage.no-frames.description=Disable the use of frames in the generated output
+doclet.usage.stylesheetfile.parameters=\
+    <path>
+doclet.usage.stylesheetfile.description=\
+    File to change style of the generated documentation
 
-doclet.xusage.xdocrootparent.parameters=<url>
-doclet.xusage.xdocrootparent.description=Replaces all @docRoot followed by /..\n\
-\                                   in doc comments with <url>
+doclet.usage.docencoding.parameters=\
+    <name>
+doclet.usage.docencoding.description=\
+    Specify the character encoding for the output
 
-doclet.xusage.xdoclint.description=Enable recommended checks for problems in\n\
-\                                   javadoc comments
+doclet.usage.frames.description=\
+    Enable the use of frames in the generated output (default)
+
+doclet.usage.no-frames.description=\
+    Disable the use of frames in the generated output
 
-doclet.xusage.xdoclint-extended.parameters=(all|none|[-]<group>)
-# L10N: do not localize these words: all none accessibility html missing reference syntax
-doclet.xusage.xdoclint-extended.description=Enable or disable specific checks\n\
-\                                   for problems in javadoc comments, where \n\
-\                                   <group> is one of accessibility, html,\n\
-\                                   missing, reference, or syntax.\n
+doclet.usage.xdocrootparent.parameters=\
+    <url>
+doclet.usage.xdocrootparent.description=\
+    Replaces all @docRoot followed by /.. in doc comments with\n\
+    <url>
+
+doclet.usage.xdoclint.description=\
+    Enable recommended checks for problems in javadoc comments
 
-doclet.xusage.xdoclint-package.parameters=([-]<packages>)
-doclet.xusage.xdoclint-package.description=\n\
-\                                   Enable or disable checks in specific\n\
-\                                   packages. <packages> is a comma separated\n\
-\                                   list of package specifiers. Package\n\
-\                                   specifier is either a qualified name of a\n\
-\                                   package or a package name prefix followed\n\
-\                                   by .*, which expands to all sub-packages\n\
-\                                   of the given package. Prefix the package\n\
-\                                   specifier with - to disable checks for\n\
-\                                   the specified packages.\n
+doclet.usage.xdoclint-extended.parameters=\
+    (all|none|[-]<group>)
+# L10N: do not localize these words: all none accessibility html missing reference syntax
+doclet.usage.xdoclint-extended.description=\
+    Enable or disable specific checks for problems in javadoc\n\
+    comments, where <group> is one of accessibility, html,\n\
+    missing, reference, or syntax.
+
+doclet.usage.xdoclint-package.parameters=\
+    ([-]<packages>)
+doclet.usage.xdoclint-package.description=\
+    Enable or disable checks in specific packages. <packages> is a\n\
+    comma separated list of package specifiers. A package\n\
+    specifier is either a qualified name of a package or a package\n\
+    name prefix followed by .*, which expands to all sub-packages\n\
+    of the given package. Prefix the package specifier with - to\n\
+    disable checks for the specified packages.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Mon Oct 10 13:31:48 2016 -0700
@@ -404,8 +404,9 @@
     }
 
     public Set<Doclet.Option> getSupportedOptions() {
+        Resources resources = getResources();
         Doclet.Option[] options = {
-            new Option(this, "-author") {
+            new Option(resources, "-author") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -413,7 +414,7 @@
                     return true;
                 }
             },
-            new Option(this, "-d", 1) {
+            new Option(resources, "-d", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -421,7 +422,7 @@
                     return true;
                 }
             },
-            new Option(this, "-docencoding", 1) {
+            new Option(resources, "-docencoding", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -429,7 +430,7 @@
                     return true;
                 }
             },
-            new Option(this, "-docfilessubdirs") {
+            new Option(resources, "-docfilessubdirs") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -437,7 +438,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-encoding", 1) {
+            new Hidden(resources, "-encoding", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -445,7 +446,7 @@
                     return true;
                 }
             },
-            new Option(this, "-excludedocfilessubdir", 1) {
+            new Option(resources, "-excludedocfilessubdir", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -453,7 +454,7 @@
                     return true;
                 }
             },
-            new Option(this, "-group", 2) {
+            new Option(resources, "-group", 2) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -461,7 +462,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-javafx") {
+            new Hidden(resources, "-javafx") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -469,7 +470,7 @@
                     return true;
                 }
             },
-            new Option(this, "-keywords") {
+            new Option(resources, "-keywords") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -477,7 +478,7 @@
                     return true;
                 }
             },
-            new Option(this, "-link", 1) {
+            new Option(resources, "-link", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -486,7 +487,7 @@
                     return true;
                 }
             },
-            new Option(this, "-linksource") {
+            new Option(resources, "-linksource") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -494,7 +495,7 @@
                     return true;
                 }
             },
-            new Option(this, "-linkoffline", 2) {
+            new Option(resources, "-linkoffline", 2) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -503,7 +504,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nocomment") {
+            new Option(resources, "-nocomment") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -511,7 +512,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nodeprecated") {
+            new Option(resources, "-nodeprecated") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -519,7 +520,7 @@
                     return true;
                 }
             },
-            new Option(this, "-nosince") {
+            new Option(resources, "-nosince") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -527,7 +528,7 @@
                     return true;
                 }
             },
-            new Option(this, "-notimestamp") {
+            new Option(resources, "-notimestamp") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -535,7 +536,7 @@
                     return true;
                 }
             },
-            new Option(this, "-noqualifier", 1) {
+            new Option(resources, "-noqualifier", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -543,7 +544,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-quiet") {
+            new Hidden(resources, "-quiet") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -551,7 +552,7 @@
                     return true;
                 }
             },
-            new Option(this, "-serialwarn") {
+            new Option(resources, "-serialwarn") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -559,7 +560,7 @@
                     return true;
                 }
             },
-            new Option(this, "-sourcetab", 1) {
+            new Option(resources, "-sourcetab", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -578,7 +579,7 @@
                     return true;
                 }
             },
-            new Option(this, "-tag", 1) {
+            new Option(resources, "-tag", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -589,7 +590,7 @@
                     return true;
                 }
             },
-             new Option(this, "-taglet", 1) {
+             new Option(resources, "-taglet", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -600,7 +601,7 @@
                     return true;
                 }
             },
-            new Option(this, "-tagletpath", 1) {
+            new Option(resources, "-tagletpath", 1) {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -608,7 +609,7 @@
                     return true;
                 }
             },
-            new Option(this, "-version") {
+            new Option(resources, "-version") {
                 @Override
                 public boolean process(String opt, ListIterator<String> args) {
                     optionsProcessed.add(this);
@@ -1057,37 +1058,30 @@
         private final String description;
         private final int argCount;
 
-        protected final Configuration c;
+        protected Option(Resources resources, String name, int argCount) {
+            this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-*", ""), name, argCount);
+        }
 
-        protected Option(Configuration config, String keyName, String name, int argCount) {
-            c = config;
+        protected Option(Resources resources, String keyBase, String name, int argCount) {
             this.name = name;
-            String desc = getOptionsMessage(keyName + "description");
+            String desc = getOptionsMessage(resources, keyBase + ".description");
             if (desc.isEmpty()) {
                 this.description = "<MISSING KEY>";
                 this.parameters = "<MISSING KEY>";
             } else {
                 this.description = desc;
-                this.parameters = getOptionsMessage(keyName + "parameters");
+                this.parameters = getOptionsMessage(resources, keyBase + ".parameters");
             }
             this.argCount = argCount;
         }
 
-        protected Option(String prefix, Configuration config, String name, int argCount) {
-            this(config, prefix + name.toLowerCase().replaceAll("^-*", "") + ".", name, argCount);
-        }
-
-        protected Option(Configuration config, String name, int argCount) {
-            this("doclet.usage.", config,  name, argCount);
+        protected Option(Resources resources, String name) {
+            this(resources, name, 0);
         }
 
-        protected Option(Configuration config, String name) {
-            this(config, name, 0);
-        }
-
-        private String getOptionsMessage(String key) {
+        private String getOptionsMessage(Resources resources, String key) {
             try {
-                return c.getResources().getText(key);
+                return resources.getText(key);
             } catch (MissingResourceException ignore) {
                 return "";
             }
@@ -1113,19 +1107,9 @@
             return parameters;
         }
 
-        /**
-         * Maintains the formatting for javadoc -help. Note the space
-         * alignment.
-         */
         @Override
         public String toString() {
-            String opt = name + (name.endsWith(":") ? "" : " ") + parameters;
-            StringBuffer sb = new StringBuffer("  ").append(opt).append(" ");
-            for (int i = opt.length(); i < 32; i++) {
-                sb.append(" ");
-            }
-            sb.append(description);
-            return sb.toString();
+            return name;
         }
 
         @Override
@@ -1135,7 +1119,14 @@
 
         @Override
         public boolean matches(String option) {
-            return name.toLowerCase().equals(option.toLowerCase());
+            boolean matchCase = name.startsWith("--");
+            if (option.startsWith("--") && option.contains("=")) {
+                return name.equals(option.substring(option.indexOf("=") + 1));
+            } else if (matchCase) {
+                return name.equals(option);
+            } else {
+                return name.toLowerCase().equals(option.toLowerCase());
+            }
         }
 
         @Override
@@ -1146,16 +1137,16 @@
 
     public abstract class XOption extends Option {
 
-        public XOption(Configuration config, String keyname, String name, int argCount) {
-            super(config, keyname, name, argCount);
+        public XOption(Resources resources, String prefix, String name, int argCount) {
+            super(resources, prefix, name, argCount);
         }
 
-        public XOption(Configuration config, String name, int argCount) {
-            super("doclet.xusage.", config, name, argCount);
+        public XOption(Resources resources, String name, int argCount) {
+            super(resources, name, argCount);
         }
 
-        public XOption(Configuration config, String name) {
-            this(config, name, 0);
+        public XOption(Resources resources, String name) {
+            this(resources, name, 0);
         }
 
         @Override
@@ -1166,12 +1157,12 @@
 
     public abstract class Hidden extends Option {
 
-        public Hidden(Configuration config, String name, int argCount) {
-            super("doclet.xusage.", config, name, argCount);
+        public Hidden(Resources resources, String name, int argCount) {
+            super(resources, name, argCount);
         }
 
-        public Hidden(Configuration config, String name) {
-            this(config, name, 0);
+        public Hidden(Resources resources, String name) {
+            this(resources, name, 0);
         }
 
         @Override
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Mon Oct 10 13:31:48 2016 -0700
@@ -255,7 +255,7 @@
     private void incrementErrorCount(String prefix, String msg) {
         if (nerrors < MaxErrors) {
             PrintWriter errWriter = getWriter(WriterKind.ERROR);
-            errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg);
+            printRawLines(errWriter, prefix + ": " + getText("javadoc.error") + " - " + msg);
             errWriter.flush();
             prompt();
             nerrors++;
@@ -293,7 +293,7 @@
     private void incrementWarningCount(String prefix, String msg) {
         if (nwarnings < MaxWarnings) {
             PrintWriter warnWriter = getWriter(WriterKind.WARNING);
-            warnWriter.println(prefix + ": " + getText("javadoc.warning") + " - " + msg);
+            printRawLines(warnWriter, prefix + ": " + getText("javadoc.warning") + " - " + msg);
             warnWriter.flush();
             nwarnings++;
         }
@@ -318,9 +318,9 @@
 
         PrintWriter noticeWriter = getWriter(WriterKind.NOTICE);
         if (path == null) {
-            noticeWriter.println(msg);
+            printRawLines(noticeWriter, msg);
         } else {
-            noticeWriter.println(prefix + ": " + msg);
+            printRawLines(noticeWriter, prefix + ": " + msg);
         }
         noticeWriter.flush();
     }
@@ -334,9 +334,9 @@
 
         PrintWriter noticeWriter = getWriter(WriterKind.NOTICE);
         if (e == null) {
-            noticeWriter.println(msg);
+            printRawLines(noticeWriter, msg);
         } else {
-            noticeWriter.println(pos + ": " + msg);
+            printRawLines(noticeWriter, pos + ": " + msg);
         }
         noticeWriter.flush();
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Mon Oct 10 13:31:48 2016 -0700
@@ -31,14 +31,18 @@
 import java.io.PrintWriter;
 import java.nio.file.Path;
 import java.text.BreakIterator;
+import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
@@ -61,6 +65,7 @@
 import jdk.javadoc.doclet.Doclet;
 import jdk.javadoc.doclet.Doclet.Option;
 import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.internal.doclets.toolkit.Resources;
 
 import static javax.tools.DocumentationTool.Location.*;
 
@@ -168,7 +173,10 @@
     }
 
     void usage(boolean exit) {
-        usage("main.usage", "-help", "main.usage.foot", exit);
+        usage("main.usage", "-help", "main.usage.foot");
+
+        if (exit)
+            throw new Messager.ExitJavadoc();
     }
 
     @Override
@@ -177,30 +185,128 @@
     }
 
     void Xusage(boolean exit) {
-        usage("main.Xusage", "-X", "main.Xusage.foot", exit);
-    }
-
-    private void usage(String main, String option, String foot, boolean exit) {
-        messager.notice(main);
-        // let doclet print usage information (does nothing on error)
-        if (docletClass != null) {
-            String name = doclet.getName();
-            Set<Option> supportedOptions = doclet.getSupportedOptions();
-            messager.notice("main.doclet.usage.header", name);
-            Option.Kind myKind = option.equals("-X")
-                    ? Option.Kind.EXTENDED
-                    : Option.Kind.STANDARD;
-            supportedOptions.stream()
-                    .filter(opt -> opt.getKind() == myKind)
-                    .forEach(opt -> messager.printNotice(opt.toString()));
-        }
-        if (foot != null)
-            messager.notice(foot);
+        usage("main.Xusage", "-X", "main.Xusage.foot");
 
         if (exit)
             throw new Messager.ExitJavadoc();
     }
 
+    private void usage(String header, String option, String footer) {
+        messager.notice(header);
+        showToolOptions(option.equals("-X") ? OptionKind.EXTENDED : OptionKind.STANDARD);
+
+        // let doclet print usage information
+        if (docletClass != null) {
+            String name = doclet.getName();
+            messager.notice("main.doclet.usage.header", name);
+            showDocletOptions(option.equals("-X") ? Option.Kind.EXTENDED : Option.Kind.STANDARD);
+        }
+
+        if (footer != null)
+            messager.notice(footer);
+    }
+
+    void showToolOptions(OptionKind kind) {
+        Comparator<ToolOption> comp = new Comparator<ToolOption>() {
+            final Collator collator = Collator.getInstance(Locale.US);
+            { collator.setStrength(Collator.PRIMARY); }
+
+            @Override
+            public int compare(ToolOption o1, ToolOption o2) {
+                return collator.compare(o1.primaryName, o2.primaryName);
+            }
+        };
+
+        Stream.of(ToolOption.values())
+                    .filter(opt -> opt.kind == kind)
+                    .sorted(comp)
+                    .forEach(opt -> showToolOption(opt));
+    }
+
+    void showToolOption(ToolOption option) {
+        List<String> names = option.getNames();
+        String parameters;
+        if (option.hasArg || option.primaryName.endsWith(":")) {
+            String sep = (option == ToolOption.J) || option.primaryName.endsWith(":") ? "" : " ";
+            parameters = sep + option.getParameters(messager);
+        } else {
+            parameters = "";
+        }
+        String description = option.getDescription(messager);
+        showUsage(names, parameters, description);
+    }
+
+    void showDocletOptions(Option.Kind kind) {
+        Comparator<Doclet.Option> comp = new Comparator<Doclet.Option>() {
+            final Collator collator = Collator.getInstance(Locale.US);
+            { collator.setStrength(Collator.PRIMARY); }
+
+            @Override
+            public int compare(Doclet.Option o1, Doclet.Option o2) {
+                return collator.compare(o1.getName(), o2.getName());
+            }
+        };
+
+        doclet.getSupportedOptions().stream()
+                .filter(opt -> opt.getKind() == kind)
+                .sorted(comp)
+                .forEach(opt -> showDocletOption(opt));
+    }
+
+    void showDocletOption(Doclet.Option option) {
+        List<String> names = Arrays.asList(option.getName());
+        String parameters;
+        if (option.getArgumentCount() > 0 || option.getName().endsWith(":")) {
+            String sep = option.getName().endsWith(":") ? "" : " ";
+            parameters = sep + option.getParameters();
+        } else {
+            parameters = "";
+        }
+        String description = option.getDescription();
+        showUsage(names, parameters, description);
+    }
+
+    // The following constants are intended to format the output to
+    // be similar to that of the java launcher: i.e. "java -help".
+
+    /** The indent for the option synopsis. */
+    private static final String SMALL_INDENT = "    ";
+    /** The automatic indent for the description. */
+    private static final String LARGE_INDENT = "                  ";
+    /** The space allowed for the synopsis, if the description is to be shown on the same line. */
+    private static final int DEFAULT_SYNOPSIS_WIDTH = 13;
+    /** The nominal maximum line length, when seeing if text will fit on a line. */
+    private static final int DEFAULT_MAX_LINE_LENGTH = 80;
+    /** The format for a single-line help entry. */
+    private static final String COMPACT_FORMAT = SMALL_INDENT + "%-" + DEFAULT_SYNOPSIS_WIDTH + "s %s";
+
+    void showUsage(List<String> names, String parameters, String description) {
+        String synopses = names.stream()
+                .map(s -> s + parameters)
+                .collect(Collectors.joining(", "));
+        // If option synopses and description fit on a single line of reasonable length,
+        // display using COMPACT_FORMAT
+        if (synopses.length() < DEFAULT_SYNOPSIS_WIDTH
+                && !description.contains("\n")
+                && (SMALL_INDENT.length() + DEFAULT_SYNOPSIS_WIDTH + 1 + description.length() <= DEFAULT_MAX_LINE_LENGTH)) {
+            messager.printNotice(String.format(COMPACT_FORMAT, synopses, description));
+            return;
+        }
+
+        // If option synopses fit on a single line of reasonable length, show that;
+        // otherwise, show 1 per line
+        if (synopses.length() <= DEFAULT_MAX_LINE_LENGTH) {
+            messager.printNotice(SMALL_INDENT + synopses);
+        } else {
+            for (String name: names) {
+                messager.printNotice(SMALL_INDENT + name + parameters);
+            }
+        }
+
+        // Finally, show the description
+        messager.printNotice(LARGE_INDENT + description.replace("\n", "\n" + LARGE_INDENT));
+    }
+
 
     /**
      * Main program - external wrapper. In order to maintain backward
@@ -433,14 +539,37 @@
             docletOptions = doclet.getSupportedOptions();
         }
         String arg = args.get(idx);
+        String argBase, argVal;
+        if (arg.startsWith("--") && arg.contains("=")) {
+            int sep = arg.indexOf("=");
+            argBase = arg.substring(0, sep);
+            argVal = arg.substring(sep + 1);
+        } else {
+            argBase = arg;
+            argVal = null;
+        }
 
         for (Doclet.Option opt : docletOptions) {
-            if (opt.matches(arg)) {
-                if (args.size() - idx < opt.getArgumentCount()) {
-                    usageError("main.requires_argument", arg);
+            if (opt.matches(argBase)) {
+                if (argVal != null) {
+                    switch (opt.getArgumentCount()) {
+                        case 0:
+                            usageError("main.unnecessary_arg_provided", argBase);
+                            break;
+                        case 1:
+                            opt.process(arg, Arrays.asList(argVal).listIterator());
+                            break;
+                        default:
+                            usageError("main.only_one_argument_with_equals", argBase);
+                            break;
+                    }
+                } else {
+                    if (args.size() - idx -1 < opt.getArgumentCount()) {
+                        usageError("main.requires_argument", arg);
+                    }
+                    opt.process(arg, args.listIterator(idx + 1));
+                    idx += opt.getArgumentCount();
                 }
-                opt.process(arg, args.listIterator(idx + 1));
-                idx += opt.getArgumentCount();
                 return idx;
             }
         }
@@ -463,11 +592,11 @@
         // Step 1: loop through the args, set locale early on, if found.
         for (int i = 0 ; i < argv.size() ; i++) {
             String arg = argv.get(i);
-            if (arg.equals(ToolOption.LOCALE.opt)) {
+            if (arg.equals(ToolOption.LOCALE.primaryName)) {
                 checkOneArg(argv, i++);
                 String lname = argv.get(i);
                 locale = getLocale(lname);
-            } else if (arg.equals(ToolOption.DOCLET.opt)) {
+            } else if (arg.equals(ToolOption.DOCLET.primaryName)) {
                 checkOneArg(argv, i++);
                 if (userDocletName != null) {
                     usageError("main.more_than_one_doclet_specified_0_and_1",
@@ -478,7 +607,7 @@
                             docletName, argv.get(i));
                 }
                 userDocletName = argv.get(i);
-            } else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
+            } else if (arg.equals(ToolOption.DOCLETPATH.primaryName)) {
                 checkOneArg(argv, i++);
                 if (userDocletPath == null) {
                     userDocletPath = argv.get(i);
@@ -599,8 +728,12 @@
                 handleDocletOptions(i, args, true);
 
                 if (o.hasArg) {
-                    checkOneArg(args, i++);
-                    o.process(this, args.get(i));
+                    if (arg.startsWith("--") && arg.contains("=")) {
+                        o.process(this, arg.substring(arg.indexOf('=') + 1));
+                    } else {
+                        checkOneArg(args, i++);
+                        o.process(this, args.get(i));
+                    }
                 } else if (o.hasSuffix) {
                     o.process(this, arg);
                 } else {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Mon Oct 10 13:31:48 2016 -0700
@@ -35,9 +35,12 @@
 import javax.lang.model.element.ElementKind;
 
 import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.Option.OptionKind;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.util.Options;
 
+import static com.sun.tools.javac.main.Option.OptionKind.*;
+
 /**
  * javadoc tool options.
  *
@@ -50,197 +53,169 @@
 
     // ----- options for underlying compiler -----
 
-    BOOTCLASSPATH("-bootclasspath", true) {
+    BOOTCLASSPATH("-bootclasspath", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.BOOT_CLASS_PATH, arg);
         }
     },
 
-    CLASSPATH("-classpath", true) {
+    CLASS_PATH("--class-path -classpath -cp", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.CLASS_PATH, arg);
         }
     },
 
-    CP("-cp", true) {
-        @Override
-        public void process(Helper helper, String arg) {
-            helper.setFileManagerOpt(Option.CLASS_PATH, arg);
-        }
-    },
-
-    CLASS_PATH("--class-path", true) {
-        @Override
-        public void process(Helper helper, String arg) {
-            helper.setFileManagerOpt(Option.CLASS_PATH, arg);
-        }
-    },
-
-    EXTDIRS("-extdirs", true) {
+    EXTDIRS("-extdirs", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.EXTDIRS, arg);
         }
     },
 
-    SOURCEPATH("-sourcepath", true) {
+    SOURCE_PATH("--source-path -sourcepath", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.SOURCE_PATH, arg);
         }
     },
 
-    SOURCE_PATH("--source-path", true) {
-        @Override
-        public void process(Helper helper, String arg) {
-            helper.setFileManagerOpt(Option.SOURCE_PATH, arg);
-        }
-    },
-
-    SYSCLASSPATH("-sysclasspath", true) {
+    SYSCLASSPATH("-sysclasspath", HIDDEN, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.BOOT_CLASS_PATH, arg);
         }
     },
 
-    MODULE_SOURCE_PATH("--module-source-path", true) {
+    MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.MODULE_SOURCE_PATH, arg);
         }
     },
 
-    UPGRADE_MODULE_PATH("--upgrade-module-path", true) {
+    UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.UPGRADE_MODULE_PATH, arg);
         }
     },
 
-    SYSTEM("--system", true) {
+    SYSTEM("--system", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.SYSTEM, arg);
         }
     },
 
-    MODULE_PATH("--module-path", true) {
-        @Override
-        public void process(Helper helper, String arg) {
-            helper.setFileManagerOpt(Option.MODULE_PATH, arg);
-        }
-    },
-
-    P("-p", true) {
+    MODULE_PATH("--module-path -p", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
         }
     },
 
-    ADD_MODULES("--add-modules", true) {
+    ADD_MODULES("--add-modules", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
+            Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    LIMIT_MODULES("--limit-modules", true) {
+    LIMIT_MODULES("--limit-modules", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
+            Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    MODULE("--module", true) {
+    MODULE("--module", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.addToList(this, ",", arg);
         }
     },
 
-    ENCODING("-encoding", true) {
+    ENCODING("-encoding", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFileManagerOpt(Option.ENCODING, arg);
         }
     },
 
-    RELEASE("--release", true) {
+    RELEASE("--release", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.RELEASE.process(helper.getOptionHelper(), opt, arg);
+            Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    SOURCE("-source", true) {
+    SOURCE("-source", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.SOURCE.process(helper.getOptionHelper(), opt, arg);
+            Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    XMAXERRS("-Xmaxerrs", true) {
+    XMAXERRS("-Xmaxerrs", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.XMAXERRS.process(helper.getOptionHelper(), opt, arg);
+            Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    XMAXWARNS("-Xmaxwarns", true) {
+    XMAXWARNS("-Xmaxwarns", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.XMAXWARNS.process(helper.getOptionHelper(), opt, arg);
+            Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    ADD_READS("--add-reads", true) {
+    ADD_READS("--add-reads", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
+            Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    ADD_EXPORTS("--add-exports", true) {
+    ADD_EXPORTS("--add-exports", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
+            Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
-    XMODULE("-Xmodule:", false) {
+    XMODULE("-Xmodule:", EXTENDED, false) {
         @Override
         public void process(Helper helper, String arg) {
             Option.XMODULE.process(helper.getOptionHelper(), arg);
         }
     },
 
-    PATCH_MODULE("--patch-module", true) {
+    PATCH_MODULE("--patch-module", EXTENDED, true) {
         @Override
         public void process(Helper helper, String arg) {
-            Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
+            Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     // ----- doclet options -----
 
-    DOCLET("-doclet", true), // handled in setDocletInvoker
+    DOCLET("-doclet", STANDARD, true), // handled in setDocletInvoker
 
-    DOCLETPATH("-docletpath", true), // handled in setDocletInvoker
+    DOCLETPATH("-docletpath", STANDARD, true), // handled in setDocletInvoker
 
     // ----- selection options -----
 
-    SUBPACKAGES("-subpackages", true) {
+    SUBPACKAGES("-subpackages", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.addToList(this, ":", arg);
         }
     },
 
-    EXCLUDE("-exclude", true) {
+    EXCLUDE("-exclude", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.addToList(this, ":", arg);
@@ -249,72 +224,72 @@
 
     // ----- filtering options -----
 
-    PACKAGE("-package") {
+    PACKAGE("-package", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.setSimpleFilter("package");
         }
     },
 
-    PRIVATE("-private") {
+    PRIVATE("-private", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.setSimpleFilter("private");
         }
     },
 
-    PROTECTED("-protected") {
+    PROTECTED("-protected", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.setSimpleFilter("protected");
         }
     },
 
-    PUBLIC("-public") {
+    PUBLIC("-public", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.setSimpleFilter("public");
         }
     },
 
-    SHOW_MEMBERS("--show-members:") {
+    SHOW_MEMBERS("--show-members", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFilter(this, arg);
         }
     },
 
-    SHOW_TYPES("--show-types:") {
+    SHOW_TYPES("--show-types", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.setFilter(this, arg);
         }
     },
 
-    SHOW_PACKAGES("--show-packages:") {
+    SHOW_PACKAGES("--show-packages", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
+            helper.setShowPackageAccess(SHOW_PACKAGES, arg);
         }
     },
 
-    SHOW_MODULE_CONTENTS("--show-module-contents:") {
+    SHOW_MODULE_CONTENTS("--show-module-contents", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
+            helper.setShowModuleContents(SHOW_MODULE_CONTENTS, arg);
         }
     },
 
-    EXPAND_REQUIRES("--expand-requires:") {
+    EXPAND_REQUIRES("--expand-requires", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
+            helper.setExpandRequires(EXPAND_REQUIRES, arg);
         }
     },
 
     // ----- output control options -----
 
-    PROMPT("-prompt") {
+    PROMPT("-prompt", HIDDEN) {
         @Override
         public void process(Helper helper) {
             helper.compOpts.put("-prompt", "-prompt");
@@ -322,21 +297,21 @@
         }
     },
 
-    QUIET("-quiet") {
+    QUIET("-quiet", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.jdtoolOpts.put(QUIET, true);
         }
     },
 
-    VERBOSE("-verbose") {
+    VERBOSE("-verbose", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.compOpts.put("-verbose", "");
         }
     },
 
-    XWERROR("-Xwerror") {
+    XWERROR("-Xwerror", HIDDEN) {
         @Override
         public void process(Helper helper) {
             helper.rejectWarnings = true;
@@ -346,21 +321,21 @@
 
     // ----- other options -----
 
-    BREAKITERATOR("-breakiterator") {
+    BREAKITERATOR("-breakiterator", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.breakiterator = true;
         }
     },
 
-    LOCALE("-locale", true) {
+    LOCALE("-locale", STANDARD, true) {
         @Override
         public void process(Helper helper, String arg) {
             helper.docLocale = arg;
         }
     },
 
-    XCLASSES("-Xclasses") {
+    XCLASSES("-Xclasses", HIDDEN) {
         @Override
         public void process(Helper helper) {
             helper.jdtoolOpts.put(XCLASSES, true);
@@ -369,32 +344,54 @@
 
     // ----- help options -----
 
-    HELP("-help") {
+    HELP("--help -help", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.usage();
         }
     },
 
-    X("-X") {
+    X("-X", STANDARD) {
         @Override
         public void process(Helper helper) {
             helper.Xusage();
         }
+    },
+
+    // This option exists only for the purpose of documenting itself.
+    // It's actually implemented by the launcher.
+    J("-J", STANDARD, true) {
+        @Override
+        public void process(Helper helper) {
+            throw new AssertionError("the -J flag should be caught by the launcher.");
+        }
+    },
+
+    // This option exists only for the purpose of documenting itself.
+    // It's actually implemented ahead of the normal option decoding loop.
+    Xold("-Xold", EXTENDED) {
+        @Override
+        public void process(Helper helper) {
+            throw new AssertionError("the -Xold flag should be handled earlier.");
+        }
     };
 
-    public final String opt;
+    public final String primaryName;
+    public final List<String> names;
+    public final OptionKind kind;
     public final boolean hasArg;
     public final boolean hasSuffix; // ex: foo:bar or -foo=bar
 
-    ToolOption(String opt) {
-        this(opt, false);
+    ToolOption(String opt, OptionKind kind) {
+        this(opt, kind, false);
     }
 
-    ToolOption(String opt, boolean hasArg) {
-        this.opt = opt;
+    ToolOption(String names, OptionKind kind, boolean hasArg) {
+        this.names = Arrays.asList(names.split("\\s+"));
+        this.primaryName = this.names.get(0);
+        this.kind = kind;
         this.hasArg = hasArg;
-        char lastChar = opt.charAt(opt.length() - 1);
+        char lastChar = names.charAt(names.length() - 1);
         this.hasSuffix = lastChar == ':' || lastChar == '=';
     }
 
@@ -402,16 +399,42 @@
 
     void process(Helper helper) { }
 
+    List<String> getNames() {
+        return names;
+    }
+
+    String getParameters(Messager messager) {
+        return (hasArg || primaryName.endsWith(":"))
+                ? messager.getText(getKey(primaryName, ".arg"))
+                : null;
+    }
+
+    String getDescription(Messager messager) {
+        return messager.getText(getKey(primaryName, ".desc"));
+    }
+
+    private String getKey(String optionName, String suffix) {
+        return "main.opt."
+                + optionName
+                .replaceAll("^-*", "")              // remove leading '-'
+                .replaceAll("[^A-Za-z0-9]+$", "")   // remove trailing non-alphanumeric
+                .replaceAll("[^A-Za-z0-9]", ".")    // replace internal non-alphanumeric
+                + suffix;
+    }
+
+
     static ToolOption get(String name) {
         String oname = name;
         if (name.contains(":")) {
             oname = name.substring(0, name.indexOf(':') + 1);
         } else if (name.contains("=")) {
-            oname = name.substring(0, name.indexOf('=') + 1);
+            oname = name.substring(0, name.indexOf('='));
         }
         for (ToolOption o : values()) {
-            if (oname.equals(o.opt)) {
-                return o;
+            for (String n : o.names) {
+                if (oname.equals(n)) {
+                    return o;
+                }
             }
         }
         return null;
@@ -457,11 +480,6 @@
             jdtoolOpts.put(opt, list);
         }
 
-        String getOptionArgumentValue(String in) {
-            String[] values = in.trim().split(":");
-            return values[1];
-        }
-
         void setExpandRequires(ToolOption opt, String arg) {
             switch (arg) {
                 case "public":
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Mon Oct 10 13:31:48 2016 -0700
@@ -28,112 +28,234 @@
 main.warnings={0} warnings
 main.warning={0} warning
 
-main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
-\  -overview <file>                 Read overview documentation from HTML file\n\
-\  -public                          Show only public classes and members\n\
-\  -protected                       Show protected/public classes and \n\
-\                                   members (default)\n\
-\  -package                         Show package/protected/public classes\n\
-\                                   and members\n\
-\  -private                         Show all classes and members\n\
-\  --show-members:value             Specifies which members (fields, methods\n\
-\                                   etc.) will be documented, where value can\n\
-\                                   be one of "public", "protected", "package"\n\
-\                                   or "private".\n\
-\                                   Default is protected, will show public and\n\
-\                                   protected members, "public" will show only\n\
-\                                   public members, "package" will show public,\n\
-\                                   protected and package members and \n\
-\                                   "private" will show all  members\n\
-\  --show-types:value               Specifies which types (classes, interfaces\n\
-\                                   etc.) will be documented, where value can be\n\
-\                                   one of "public", "protected", "package" or\n\
-\                                   "private".\n\
-\                                   Default is "protected", show public and\n\
-\                                   protected types, "package" will show public,\n\
-\                                   protected and package types and "private"\n\
-\                                   will show all types\n\
-\  --show-packages:value            Specifies which module's packages will be\n\
-\                                   documented. Possible values are "exported"\n\
-\                                   or "all" packages\n\
-\  --show-module-contents:value     Specifies the documentation granularity of\n\
-\                                   module declarations.\n\
-\                                   Possible values are "api" or "all".\n\
-\  --expand-requires:value          Instructs the tool to expand the "requires"\n\
-\                                   module dependencies "public" expands all the\n\
-\                                   "requires public" edges of the module graph.\n\
-\                                   "all" expands all the "requires" edges of\n\
-\                                   the module graph by default only the\n\
-\                                   specified modules will be considered.\n\
-\  -help                            Display command line options and exit\n\
-\  --module m1, m2..                Document the specified module(s)\n\
-\  -doclet <class>                  Generate output via alternate doclet\n\
-\  -docletpath <path>               Specify where to find doclet class files\n\
-\  --module-source-path <path>      Specify where to find input source files\n\
-\                                   for multiple modules\n\
-\  --upgrade-module-path <path>     Override location of upgradeable modules\n\
-\  --module-path <path>, -p <path>  Specify where to find application modules\n\
-\  --add-modules <module>(,<module>)*\n\
-\                                   Root modules to resolve in addition to the\n\
-\                                   initial modules,\n\
-\                                   or all modules on the module path if\n\
-\                                   <module> is ALL-MODULE-PATH.\n\
-\  --limit-modules <module>(,<module>)*\n\
-\                                   Limit the universe of observable modules\n\
-\  --source-path <path>             Specify where to find source files\n\
-\  -sourcepath <path>               Specify where to find source files\n\
-\  --class-path <path>              Specify where to find user class files\n\
-\  -classpath <path>                Specify where to find user class files\n\
-\  -cp <path>                       Specify where to find user class files\n\
-\  -exclude <pkglist>               Specify a list of packages to exclude\n\
-\  -subpackages <subpkglist>        Specify subpackages to recursively load\n\
-\  -breakiterator                   Compute first sentence with BreakIterator\n\
-\  -bootclasspath <path>            Override location of platform class files\n\
-\                                   used for non-modular releases\n\
-\  --system <jdk>                   Override location of system modules used\n\
-\                                   for modular releases.\n\
-\  --release <release>              Provide source compatibility with\n\
-\                                   specified release\n\
-\  -source <release>                Provide source compatibility with\n\
-\                                   specified release\n\
-\  -extdirs <dirlist>               Override location of installed extensions\n\
-\  -verbose                         Output messages about what Javadoc is doing\n\
-\  -locale <name>                   Locale to be used, e.g. en_US or en_US_WIN\n\
-\  -encoding <name>                 Source file encoding name\n\
-\  -quiet                           Do not display status messages\n\
-\  -J<flag>                         Pass <flag> directly to the runtime system\n\
-\  -X                               Print a synopsis of nonstandard\n\
-\                                   options and exit\n
+main.usage=Usage:\n\
+\    javadoc [options] [packagenames] [sourcefiles] [@files]\n\
+where options include:
+
+main.opt.public.desc=\
+    Show only public classes and members
+
+main.opt.protected.desc=\
+    Show protected/public classes and members (default)
+
+main.opt.package.desc=\
+    Show package/protected/public classes and members
+
+main.opt.private.desc=\
+    Show all classes and members
+
+main.opt.show.members.arg=\
+    <value>
+main.opt.show.members.desc=\
+    Specifies which members (fields, methods, etc.) will be\n\
+    documented, where value can be one of "public", "protected",\n\
+    "package" or "private". The default is "protected", which will\n\
+    show public and protected members, "public" will show only\n\
+    public members, "package" will show public, protected and\n\
+    package members and "private" will show all members.
+
+main.opt.show.types.arg=\
+    <value>
+main.opt.show.types.desc=\
+    Specifies which types (classes, interfaces, etc.) will be\n\
+    documented, where value can be one of "public", "protected",\n\
+    "package" or "private". The default is "protected", which will\n\
+    show public and protected types, "public" will show only\n\
+    public types, "package" will show public, protected and\n\
+    package types and "private" will show all types.
+
+main.opt.show.packages.arg=\
+    <value>
+main.opt.show.packages.desc=\
+    Specifies which module's packages will be documented. Possible\n\
+    values are "exported" or "all" packages.
+
+main.opt.show.module.contents.arg=\
+    <value>
+main.opt.show.module.contents.desc=\
+    Specifies the documentation granularity of module\n\
+    declarations. Possible values are "api" or "all".
+
+main.opt.expand.requires.arg=\
+    <value>
+main.opt.expand.requires.desc=\
+    Instructs the tool to expand the set of modules to be\n\
+    documented. By default, only the modules given explicitly on\n\
+    the command line will be documented. A value of "public" will\n\
+    additionally include all "requires public" dependencies of\n\
+    those modules. A value of "all" will include all dependencies\n\
+    of those modules.
+
+main.opt.help.desc=\
+    Display command line options and exit
+
+main.opt.module.arg=\
+    <module>(,<module>)*
+main.opt.module.desc=\
+    Document the specified module(s)
+
+main.opt.doclet.arg=\
+    <class>
+main.opt.doclet.desc=\
+    Generate output via alternate doclet
+
+main.opt.docletpath.arg=\
+    <path>
+main.opt.docletpath.desc=\
+    Specify where to find doclet class files
+
+main.opt.module.source.path.arg=\
+    <path>
+main.opt.module.source.path.desc=\
+    Specify where to find input source files for multiple modules
+
+main.opt.upgrade.module.path.arg=\
+    <path>
+main.opt.upgrade.module.path.desc=\
+    Override location of upgradeable modules
+
+main.opt.module.path.arg=\
+    <path>
+main.opt.module.path.desc=\
+    Specify where to find application modules
+
+main.opt.add.modules.arg=\
+    <module>(,<module>)*
+main.opt.add.modules.desc=\
+    Root modules to resolve in addition to the initial modules,\n\
+    or all modules on the module path if <module> is\n\
+    ALL-MODULE-PATH.
+
+main.opt.limit.modules.arg=\
+    <module>(,<module>)*
+main.opt.limit.modules.desc=\
+    Limit the universe of observable modules
+
+main.opt.source.path.arg=\
+    <path>
+main.opt.source.path.desc=\
+    Specify where to find source files
+
+main.opt.class.path.arg=\
+    <path>
+main.opt.class.path.desc=\
+    Specify where to find user class files
+
+main.opt.exclude.arg=\
+    <pkglist>
+main.opt.exclude.desc=\
+    Specify a list of packages to exclude
+
+main.opt.subpackages.arg=\
+    <subpkglist>
+main.opt.subpackages.desc=\
+    Specify subpackages to recursively load
+
+main.opt.breakiterator.desc=\
+    Compute first sentence with BreakIterator
+
+main.opt.bootclasspath.arg=\
+    <path>
+main.opt.bootclasspath.desc=\
+    Override location of platform class files used for non-modular\n\
+    releases
+
+main.opt.system.arg=\
+    <jdk>
+main.opt.system.desc=\
+    Override location of system modules used for modular releases
+
+main.opt.release.arg=\
+    <release>
+main.opt.release.desc=\
+    Provide source compatibility with specified release
+
+main.opt.source.arg=\
+    <release>
+main.opt.source.desc=\
+    Provide source compatibility with specified release
+
+main.opt.extdirs.arg=\
+    <dirlist>
+main.opt.extdirs.desc=\
+    Override location of installed extensions
+
+main.opt.verbose.desc=\
+    Output messages about what Javadoc is doing
+
+main.opt.locale.arg=\
+    <name>
+main.opt.locale.desc=\
+    Locale to be used, e.g. en_US or en_US_WIN
+
+main.opt.encoding.arg=\
+    <name>
+main.opt.encoding.desc=\
+    Source file encoding name
+
+main.opt.quiet.desc=\
+    Do not display status messages
+
+main.opt.J.arg=\
+    <flag>
+main.opt.J.desc=\
+    Pass <flag> directly to the runtime system
+
+main.opt.X.desc=\
+    Print a synopsis of nonstandard options and exit
 
 main.usage.foot=\n\
 GNU-style options may use '=' instead of whitespace to separate the name of an\n\
 option from its value.\n
 
-main.Xusage=\
-\  -Xmaxerrs <number>               Set the maximum number of errors to print\n\
-\  -Xmaxwarns <number>              Set the maximum number of warnings to print\n\
-\  --add-exports <module>/<package>=<other-module>(,<other-module>)*\n\
-\                                   Specify a package to be considered as exported\n\
-\                                   from its defining module to additional modules,\n\
-\                                   or to all unnamed modules if <other-module> is\n\
-\                                   ALL-UNNAMED.\n\
-\  --add-reads <module>=<other-module>(,<other-module>)*\n\
-\                                   Specify additional modules to be considered as\n\
-\                                   required by a given module. <other-module> may be\n\
-\                                   ALL-UNNAMED to require the unnamed module.\n\
-\  -Xmodule:<module-name>           Specify a module to which the classes being\n\
-\                                   compiled belong.\n\
-\  --patch-module <module>=<file>(:<file>)*\n\
-\                                   Override or augment a module with classes\n\
-\                                   and resources in JAR files or directories\n\
-\  -Xold                            Invoke the legacy javadoc tool\n
+main.Xusage=
+
+main.opt.Xmaxerrs.arg=\
+    <number>
+main.opt.Xmaxerrs.desc=\
+    Set the maximum number of errors to print
+
+main.opt.Xmaxwarns.arg=\
+    <number>
+main.opt.Xmaxwarns.desc=\
+    Set the maximum number of warnings to print
+
+main.opt.add.exports.arg=\
+    <module>/<package>=<other-module>(,<other-module>)*
+main.opt.add.exports.desc=\
+    Specify a package to be considered as exported from its\n\
+    defining module to additional modules, or to all unnamed\n\
+    modules if <other-module> is ALL-UNNAMED
 
-main.Xusage.foot=\
+main.opt.add.reads.arg=\
+    <module>=<other-module>(,<other-module>)*
+main.opt.add.reads.desc=\
+    Specify additional modules to be considered as required by a\n\
+    given module. <other-module> may be ALL-UNNAMED to require\n\
+    the unnamed module.
+
+main.opt.Xmodule.arg=\
+    <module-name>
+main.opt.Xmodule.desc=\
+    Specify a module to which the classes being compiled belong
+
+main.opt.patch.module.arg=\
+    <module>=<file>(:<file>)*
+main.opt.patch.module.desc=\
+    Override or augment a module with classes and resources in\n\
+    JAR files or directories
+
+main.opt.Xold.desc=\
+    Invoke the legacy javadoc tool
+
+main.Xusage.foot=\n\
 These options are non-standard and subject to change without notice.
 
-main.doclet.usage.header=Provided by the {0} doclet:
+main.doclet.usage.header=\nProvided by the {0} doclet:
 
 main.requires_argument=option {0} requires an argument.
+main.unnecessary_arg_provided=option {0} does not require an argument
+main.only_one_argument_with_equals=cannot use ''='' syntax for options that require multiple arguments
 main.invalid_flag=invalid flag: {0}
 main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
 main.module_not_found=module {0} not found.\n
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Mon Oct 10 13:31:48 2016 -0700
@@ -150,7 +150,7 @@
                 task.options.help = true;
             }
         },
-        new Option(true, "-dotoutput") {
+        new Option(true, "-dotoutput", "--dot-output") {
             void process(JdepsTask task, String opt, String arg) throws BadArgs {
                 Path p = Paths.get(arg);
                 if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
@@ -191,7 +191,7 @@
                 }
             }
         },
-        new Option(false, "-apionly") {
+        new Option(false, "-apionly", "--api-only") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.apiOnly = true;
             }
@@ -203,7 +203,7 @@
                 task.options.addmods.addAll(mods);
             }
         },
-        new Option(true, "--gen-module-info") {
+        new Option(true, "--generate-module-info") {
             void process(JdepsTask task, String opt, String arg) throws BadArgs {
                 Path p = Paths.get(arg);
                 if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
@@ -212,7 +212,7 @@
                 task.options.genModuleInfo = Paths.get(arg);
             }
         },
-        new Option(false, "-jdkinternals") {
+        new Option(false, "-jdkinternals", "--jdk-internals") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.findJDKInternals = true;
                 task.options.verbose = CLASS;
@@ -263,19 +263,36 @@
                 task.options.addmods.add(arg);
             }
         },
+        new Option(true, "--multi-release") {
+            void process(JdepsTask task, String opt, String arg) throws BadArgs {
+                if (arg.equalsIgnoreCase("base")) {
+                    task.options.multiRelease = JarFile.baseVersion();
+                } else {
+                    try {
+                        int v = Integer.parseInt(arg);
+                        if (v < 9) {
+                            throw new BadArgs("err.invalid.arg.for.option", arg);
+                        }
+                    } catch (NumberFormatException x) {
+                        throw new BadArgs("err.invalid.arg.for.option", arg);
+                    }
+                    task.options.multiRelease = Runtime.Version.parse(arg);
+                }
+            }
+        },
 
         // ---- Target filtering options ----
-        new Option(true, "-p", "-package") {
+        new Option(true, "-p", "-package", "--package") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.packageNames.add(arg);
             }
         },
-        new Option(true, "-e", "-regex") {
+        new Option(true, "-e", "-regex", "--regex") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.regex = Pattern.compile(arg);
             }
         },
-        new Option(true, "-requires") {
+        new Option(true, "--require") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.requires.add(arg);
             }
@@ -336,7 +353,7 @@
             }
         },
 
-        new Option(false, "-I", "-inverse") {
+        new Option(false, "-I", "--inverse") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.inverse = true;
                 // equivalent to the inverse of compile-time view analysis
@@ -361,7 +378,7 @@
             }
         },
 
-        new Option(false, "-version") {
+        new Option(false, "-version", "--version") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.version = true;
             }
@@ -390,23 +407,6 @@
                 }
             }
         },
-        new Option(true, "--multi-release") {
-            void process(JdepsTask task, String opt, String arg) throws BadArgs {
-                if (arg.equalsIgnoreCase("base")) {
-                    task.options.multiRelease = JarFile.baseVersion();
-                } else {
-                    try {
-                        int v = Integer.parseInt(arg);
-                        if (v < 9) {
-                            throw new BadArgs("err.invalid.arg.for.option", arg);
-                        }
-                    } catch (NumberFormatException x) {
-                        throw new BadArgs("err.invalid.arg.for.option", arg);
-                    }
-                    task.options.multiRelease = Runtime.Version.parse(arg);
-                }
-            }
-        },
     };
 
     private static final String PROGNAME = "jdeps";
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Mon Oct 10 13:31:48 2016 -0700
@@ -13,162 +13,168 @@
 
 main.opt.h=\
 \  -h -? -help\n\
-\  --help                            Print this usage message
+\  --help                        Print this usage message
 
 main.opt.version=\
-\  -version                          Version information
+\  -version --version            Version information
 
 main.opt.v=\
-\  -v           -verbose             Print all class level dependencies\n\
-\                                    Equivalent to -verbose:class -filter:none.\n\
-\  -verbose:package                  Print package-level dependencies excluding\n\
-\                                    dependencies within the same package by default\n\
-\  -verbose:class                    Print class-level dependencies excluding\n\
-\                                    dependencies within the same package by default
+\  -v       -verbose             Print all class level dependences\n\
+\                                Equivalent to -verbose:class -filter:none.\n\
+\  -verbose:package              Print package-level dependences excluding\n\
+\                                dependences within the same package by default\n\
+\  -verbose:class                Print class-level dependences excluding\n\
+\                                dependences within the same package by default
 
 main.opt.s=\
-\  -s           -summary             Print dependency summary only.
+\  -s       -summary             Print dependency summary only.
 
 main.opt.f=\
-\  -f <regex>  -filter <regex>       Filter dependences matching the given\n\
-\                                    pattern. If given multiple times, the last\n\
-\                                    one will be used.\n\
-\  -filter:package                   Filter dependences within the same package.\n\
-\                                    This is the default.\n\
-\  -filter:archive                   Filter dependences within the same archive.\n\
-\  -filter:module                    Filter dependences within the same module.\n\
-\  -filter:none                      No -filter:package and -filter:archive\n\
-\                                    filtering.  Filtering specified via the\n\
-\                                    -filter option still applies.\n\
+\  -f <regex> -filter <regex>    Filter dependences matching the given\n\
+\                                pattern. If given multiple times, the last\n\
+\                                one will be used.\n\
+\  -filter:package               Filter dependences within the same package.\n\
+\                                This is the default.\n\
+\  -filter:archive               Filter dependences within the same archive.\n\
+\  -filter:module                Filter dependences within the same module.\n\
+\  -filter:none                  No -filter:package and -filter:archive\n\
+\                                filtering.  Filtering specified via the\n\
+\                                -filter option still applies.\n\
 
 main.opt.p=\n\
-\Options to filter dependencies:\n\
-\  -p <pkgname> -package <pkgname>   Finds dependences matching the given package\n\
-\                                    name (may be given multiple times).
+\Options to filter dependences:\n\
+\  -p <pkg>\n\
+\  -package <pkg>\n\
+\  --package <pkg>               Finds dependences matching the given package\n\
+\                                name (may be given multiple times).
 
 main.opt.e=\
-\  -e <regex> -regex <regex>         Finds dependences matching the given pattern.
+\  -e <regex>\n\
+\  -regex <regex>\n\
+\  --regex <regex>               Finds dependences matching the given pattern.
 
-main.opt.requires=\
-\  -requires <module-name>           Finds dependences matching the given module\n\
-\                                    name (may be given multiple times).\n\
-\                                    -package, -regex, -requires are mutual exclusive.
+main.opt.require=\
+\  --require <module-name>       Finds dependences matching the given module\n\
+\                                name (may be given multiple times). --package,\n\
+\                                --regex, --require are mutual exclusive.
 
 main.opt.include=\n\
  \Options to filter classes to be analyzed:\n\
-\  -include <regex>                  Restrict analysis to classes matching pattern\n\
-\                                    This option filters the list of classes to\n\
-\                                    be analyzed.  It can be used together with\n\
-\                                    -p and -e which apply pattern to the dependences
+\  -include <regex>              Restrict analysis to classes matching pattern\n\
+\                                This option filters the list of classes to\n\
+\                                be analyzed.  It can be used together with\n\
+\                                -p and -e which apply pattern to the dependences
 
 main.opt.P=\
-\  -P           -profile             Show profile containing a package
+\  -P       -profile             Show profile containing a package
 
 main.opt.cp=\
 \  -cp <path>\n\
 \  -classpath <path>\n\
-\  --class-path <path>               Specify where to find class files
+\  --class-path <path>           Specify where to find class files
 
 main.opt.module-path=\
-\  --module-path <module path>...    Specify module path
+\  --module-path <module path>   Specify module path
 
 main.opt.upgrade-module-path=\
-\  --upgrade-module-path <module path>...  Specify upgrade module path
+\  --upgrade-module-path <module path>  Specify upgrade module path
 
 main.opt.system=\
-\  --system <java-home>              Specify an alternate system module path
+\  --system <java-home>          Specify an alternate system module path
 
 main.opt.add-modules=\
 \  --add-modules <module-name>[,<module-name>...]\n\
-\                                    Adds modules to the root set for analysis
+\                                Adds modules to the root set for analysis
 
 main.opt.m=\
 \  -m <module-name>\n\
-\  --module <module-name>            Specify the root module for analysis
+\  --module <module-name>        Specify the root module for analysis
 
 main.opt.R=\
-\  -R           -recursive           Recursively traverse all run-time dependencies.\n\
-\                                    The -R option implies -filter:none.  If -p,\n\
-\                                    -e, -foption is specified, only the matching\n\
-\                                    dependences are analyzed.
+\  -R       -recursive           Recursively traverse all run-time dependences.\n\
+\                                The -R option implies -filter:none.  If -p,\n\
+\                                -e, -foption is specified, only the matching\n\
+\                                dependences are analyzed.
 
 main.opt.I=\
-\  -I           -inverse             Analyzes the dependences per other given options\n\
-\                                    and then find all artifacts that directly\n\
-\                                    and indirectly depend on the matching nodes.\n\
-\                                    This is equivalent to the inverse of\n\
-\                                    compile-time view analysis and print\n\
-\                                    dependency summary.  This option must use\n\
-\                                    with -requires, -package or -regex option.
+\  -I       --inverse            Analyzes the dependences per other given options\n\
+\                                and then find all artifacts that directly\n\
+\                                and indirectly depend on the matching nodes.\n\
+\                                This is equivalent to the inverse of\n\
+\                                compile-time view analysis and print\n\
+\                                dependency summary.  This option must use\n\
+\                                with --require, --package or --regex option.
 
 main.opt.compile-time=\
-\  --compile-time                    Compile-time view of transitive dependencies\n\
-\                                    i.e. compile-time view of -R option.\n\
-\                                    Analyzes the dependences per other given options\n\
-\                                    If a dependence is found from a directory,\n\
-\                                    a JAR file or a module, all classes in that \n\
-\                                    containing archive are analyzed.
+\  --compile-time                Compile-time view of transitive dependences\n\
+\                                i.e. compile-time view of -R option.\n\
+\                                Analyzes the dependences per other given options\n\
+\                                If a dependence is found from a directory,\n\
+\                                a JAR file or a module, all classes in that \n\
+\                                containing archive are analyzed.
 
 main.opt.apionly=\
-\  -apionly                          Restrict analysis to APIs i.e. dependences\n\
-\                                    from the signature of public and protected\n\
-\                                    members of public classes including field\n\
-\                                    type, method parameter types, returned type,\n\
-\                                    checked exception types etc.
+\  -apionly\n\
+\  --api-only                    Restrict analysis to APIs i.e. dependences\n\
+\                                from the signature of public and protected\n\
+\                                members of public classes including field\n\
+\                                type, method parameter types, returned type,\n\
+\                                checked exception types etc.
 
-main.opt.gen-module-info=\
-\  --gen-module-info <dir>           Generate module-info.java under the specified\n\
-\                                    directory. The specified JAR files will be\n\
-\                                    analyzed. This option cannot be used with\n\
-\                                    -dotoutput or -cp.
+main.opt.generate-module-info=\
+\  --generate-module-info <dir>  Generate module-info.java under the specified\n\
+\                                directory. The specified JAR files will be\n\
+\                                analyzed. This option cannot be used with\n\
+\                                --dot-output or --class-path.
 
 main.opt.check=\
 \  --check <module-name>[,<module-name>...\n\
-\                                    Analyze the dependence of the specified modules\n\
-\                                    It prints the module descriptor, the resulting\n\
-\                                    module dependences after analysis and the\n\
-\                                    graph after transition reduction.  It also\n\
-\                                    identifies any unused qualified exports.
+\                                Analyze the dependence of the specified modules\n\
+\                                It prints the module descriptor, the resulting\n\
+\                                module dependences after analysis and the\n\
+\                                graph after transition reduction.  It also\n\
+\                                identifies any unused qualified exports.
 
 
 main.opt.dotoutput=\
-\  -dotoutput <dir>                  Destination directory for DOT file output
+\  -dotoutput <dir>\n\
+\  --dot-output <dir>            Destination directory for DOT file output
 
 main.opt.jdkinternals=\
-\  -jdkinternals                     Finds class-level dependences on JDK internal\n\
-\                                    APIs. By default, it analyzes all classes\n\
-\                                    on -classpath and input files unless -include\n\
-\                                    option is specified. This option cannot be\n\
-\                                    used with -p, -e and -s options.\n\
-\                                    WARNING: JDK internal APIs are inaccessible.
+\  -jdkinternals\n\
+\  --jdk-internals               Finds class-level dependences on JDK internal\n\
+\                                APIs. By default, it analyzes all classes\n\
+\                                on --class-path and input files unless -include\n\
+\                                option is specified. This option cannot be\n\
+\                                used with -p, -e and -s options.\n\
+\                                WARNING: JDK internal APIs are inaccessible.
 
 main.opt.depth=\
-\  -depth=<depth>                    Specify the depth of the transitive\n\
-\                                    dependency analysis
+\  -depth=<depth>                Specify the depth of the transitive\n\
+\                                dependency analysis
 
 main.opt.q=\
-\  -q           -quiet               Do not show missing dependencies from \n\
-\                                    -genmoduleinfo output.
+\  -q       -quiet               Do not show missing dependences from \n\
+\                                --generate-module-info output.
 
 main.opt.multi-release=\
-\  --multi-release <version>         Specifies the version when processing\n\
-\                                    multi-release jar files.  <version> should\n\
-\                                    be integer >= 9 or base.
+\  --multi-release <version>     Specifies the version when processing\n\
+\                                multi-release jar files.  <version> should\n\
+\                                be integer >= 9 or base.
 
 err.unknown.option=unknown option: {0}
 err.missing.arg=no value given for {0}
 err.invalid.arg.for.option=invalid argument for option: {0}
 err.option.after.class=option must be specified before classes: {0}
-err.genmoduleinfo.not.jarfile={0} not valid for --gen-module-info option (must be non-modular JAR file)
+err.genmoduleinfo.not.jarfile={0} not valid for --generate-module-info option (must be non-modular JAR file)
 err.profiles.msg=No profile information
 err.exception.message={0}
 err.invalid.path=invalid path: {0}
 err.invalid.module.option=Cannot set {0} with {1} option.
-err.invalid.filters=Only one of -package (-p), -regex (-e), -requires option can be set
+err.invalid.filters=Only one of --package (-p), --regex (-e), --require option can be set
 err.module.not.found=module not found: {0}
 err.root.module.not.set=root module set empty
-err.invalid.inverse.option={0} cannot be used with -inverse option
-err.inverse.filter.not.set={0} cannot be used with -inverse option
+err.invalid.inverse.option={0} cannot be used with --inverse option
 err.multirelease.option.exists={0} is not a multi-release jar file, but the --multi-release option is set
 err.multirelease.option.notfound={0} is a multi-release jar file, but the --multi-release option is not set
 err.multirelease.version.associated=class {0} already associated with version {1}, trying to add version {2}
@@ -178,7 +184,7 @@
 warn.replace.useJDKInternals=\
 JDK internal APIs are unsupported and private to JDK implementation that are\n\
 subject to be removed or changed incompatibly and could break your application.\n\
-Please modify your code to eliminate dependency on any JDK internal APIs.\n\
+Please modify your code to eliminate dependence on any JDK internal APIs.\n\
 For the most recent update on JDK internal API replacements, please check:\n\
 {0}
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Oct 10 13:31:48 2016 -0700
@@ -199,6 +199,7 @@
     private boolean feedbackInitialized = false;
     private String commandLineFeedbackMode = null;
     private List<String> remoteVMOptions = new ArrayList<>();
+    private List<String> compilerOptions = new ArrayList<>();
 
     SourceCodeAnalysis analysis;
     JShell state = null;
@@ -558,9 +559,14 @@
         parser.accepts("s");
         parser.accepts("v");
         OptionSpec<String> r = parser.accepts("R").withRequiredArg();
+        OptionSpec<String> c = parser.accepts("C").withRequiredArg();
         parser.acceptsAll(asList("h", "help"));
         parser.accepts("version");
         parser.accepts("full-version");
+
+        parser.accepts("X");
+        OptionSpec<String> addExports = parser.accepts("add-exports").withRequiredArg();
+
         NonOptionArgumentSpec<String> loadFileSpec = parser.nonOptions();
 
         OptionSet options;
@@ -585,6 +591,10 @@
             printUsage();
             return null;
         }
+        if (options.has("X")) {
+            printUsageX();
+            return null;
+        }
         if (options.has("version")) {
             cmdout.printf("jshell %s\n", version());
             return null;
@@ -630,7 +640,19 @@
             commandLineFeedbackMode = "verbose";
         }
         if (options.has(r)) {
-            remoteVMOptions = options.valuesOf(r);
+            remoteVMOptions.addAll(options.valuesOf(r));
+        }
+        if (options.has(c)) {
+            compilerOptions.addAll(options.valuesOf(c));
+        }
+
+        if (options.has(addExports)) {
+            List<String> exports = options.valuesOf(addExports).stream()
+                    .map(mp -> mp + "=ALL-UNNAMED")
+                    .flatMap(mp -> Stream.of("--add-exports", mp))
+                    .collect(toList());
+            remoteVMOptions.addAll(exports);
+            compilerOptions.addAll(exports);
         }
 
         return options.valuesOf(loadFileSpec);
@@ -640,6 +662,10 @@
         cmdout.print(getResourceString("help.usage"));
     }
 
+    private void printUsageX() {
+        cmdout.print(getResourceString("help.usage.x"));
+    }
+
     /**
      * Message handler to use during initial start-up.
      */
@@ -683,7 +709,8 @@
                 .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive())
                         ? currentNameSpace.tid(sn)
                         : errorNamespace.tid(sn))
-                .remoteVMOptions(remoteVMOptions.toArray(new String[remoteVMOptions.size()]))
+                .remoteVMOptions(remoteVMOptions.stream().toArray(String[]::new))
+                .compilerOptions(compilerOptions.stream().toArray(String[]::new))
                 .build();
         shutdownSubscription = state.onShutdown((JShell deadState) -> {
             if (deadState == state) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Oct 10 13:31:48 2016 -0700
@@ -164,8 +164,15 @@
 \                            Use one -J for each runtime flag or flag argument\n\
 \    -R<flag>              Pass <flag> to the remote runtime system.\n\
 \                            Use one -R for each remote flag or flag argument\n\
+\    -C<flag>              Pass <flag> to the compiler.\n\
+\                            Use one -C for each compiler flag or flag argument\n\
 \    --help                Print this synopsis of standard options\n\
-\    --version             Version information\n
+\    --version             Version information\n\
+\    -X                    Print help on non-standard options\n
+help.usage.x = \
+\    --add-exports <module>/<package>   Export specified module-private package to snippets\n\
+\    \n\
+\These options are non-standard and subject to change without notice.\n
 
 help.list.summary = list the source you have typed
 help.list.args = [<name or id>|-all|-start]
--- a/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/doclet/lib/JavadocTester.java	Mon Oct 10 13:31:48 2016 -0700
@@ -41,6 +41,7 @@
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.List;
@@ -410,6 +411,23 @@
     }
 
     /**
+     * Get the content of the one of the output streams written by
+     * javadoc.
+     */
+    public String getOutput(Output output) {
+        return outputMap.get(output);
+    }
+
+    /**
+     * Get the content of the one of the output streams written by
+     * javadoc.
+     */
+    public List<String> getOutputLines(Output output) {
+        String text = outputMap.get(output);
+        return (text == null) ? Collections.emptyList() : Arrays.asList(text.split(NL));
+    }
+
+    /**
      * Check for files in (or not in) the generated output.
      * @param expectedFound true if all of the files are expected
      *  to be found, or false if all of the files are expected to be
--- a/langtools/test/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Mon Oct 10 13:31:48 2016 -0700
@@ -32,6 +32,9 @@
  * @run main TestHelpOption
  */
 
+import java.util.*;
+import java.util.stream.*;
+
 public class TestHelpOption extends JavadocTester {
 
     public static void main(String... args) throws Exception {
@@ -40,6 +43,26 @@
     }
 
     @Test
+    void testLineLengths() {
+        javadoc("-d", "out1",
+                "-sourcepath", testSrc,
+                "-X",
+                testSrc("TestXOption.java"));
+        checkExit(Exit.OK);
+        List<String> longLines = getOutputLines(Output.OUT).stream()
+                .filter(s -> s.length() > 80)
+                .collect(Collectors.toList());
+        checking("line lengths");
+        if (longLines.isEmpty()) {
+            passed("all lines OK");
+        } else {
+            out.println("long lines:");
+            longLines.stream().forEach(s -> out.println(">>>" + s + "<<<"));
+            failed(longLines.size() + " long lines");
+        }
+    }
+
+    @Test
     void testWithOption() {
         javadoc("-d", "out1",
                 "-sourcepath", testSrc,
@@ -107,7 +130,7 @@
                 "-use ",
                 "-version ",
                 "-author ",
-                "-docfilessubdirs ",
+                "-docfilessubdirs\n",
                 "-splitindex ",
                 "-windowtitle ",
                 "-doctitle ",
@@ -119,11 +142,11 @@
                 "-excludedocfilessubdir ",
                 "-group ",
                 "-nocomment ",
-                "-nodeprecated ",
+                "-nodeprecated\n",
                 "-noqualifier ",
                 "-nosince ",
                 "-notimestamp ",
-                "-nodeprecatedlist ",
+                "-nodeprecatedlist\n",
                 "-notree ",
                 "-noindex ",
                 "-nohelp ",
--- a/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java	Mon Oct 10 13:31:48 2016 -0700
@@ -31,6 +31,9 @@
  * @run main TestXOption
  */
 
+import java.util.*;
+import java.util.stream.*;
+
 public class TestXOption extends JavadocTester {
 
     public static void main(String... args) throws Exception {
@@ -39,6 +42,26 @@
     }
 
     @Test
+    void testLineLengths() {
+        javadoc("-d", "out1",
+                "-sourcepath", testSrc,
+                "-X",
+                testSrc("TestXOption.java"));
+        checkExit(Exit.OK);
+        List<String> longLines = getOutputLines(Output.OUT).stream()
+                .filter(s -> s.length() > 80)
+                .collect(Collectors.toList());
+        checking("line lengths");
+        if (longLines.isEmpty()) {
+            passed("all lines OK");
+        } else {
+            out.println("long lines:");
+            longLines.stream().forEach(s -> out.println(">>>" + s + "<<<"));
+            failed(longLines.size() + " long lines");
+        }
+    }
+
+    @Test
     void testWithOption() {
         javadoc("-d", "out1",
                 "-sourcepath", testSrc,
@@ -58,14 +81,9 @@
     }
 
     private void checkOutput(boolean expectFound) {
-        // TODO: It's an ugly hidden side-effect of the current doclet API
-        // that the -X output from the tool and the -X output from the doclet
-        // come out on different streams!
-        // When we clean up the doclet API, this should be rationalized.
         checkOutput(Output.OUT, expectFound,
                 "-Xmaxerrs ",
-                "-Xmaxwarns ");
-        checkOutput(Output.OUT, expectFound,
+                "-Xmaxwarns ",
                 "-Xdocrootparent ",
                 "-Xdoclint ",
                 "-Xdoclint:");
--- a/langtools/test/jdk/javadoc/tool/CheckResourceKeys.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/CheckResourceKeys.java	Mon Oct 10 13:31:48 2016 -0700
@@ -145,6 +145,9 @@
             // ignore these synthesized keys, tested by usageTests
             if (rk.startsWith("doclet.usage.") || rk.startsWith("doclet.xusage"))
                 continue;
+            // ignore these synthesized keys, tested by usageTests
+            if (rk.matches("main\\.opt\\..*\\.(arg|desc)"))
+                continue;
             if (codeKeys.contains(rk))
                 continue;
 
@@ -161,6 +164,9 @@
             // ignore these synthesized keys, tested by usageTests
             if (ck.startsWith("doclet.usage.") || ck.startsWith("doclet.xusage."))
                 continue;
+            // ignore this partial key, tested by usageTests
+            if (ck.equals("main.opt."))
+                continue;
             if (resourceKeys.contains(ck))
                 continue;
             error("No resource for \"" + ck + "\"");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/OptionSyntaxTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+
+/*
+ * @test
+ * @bug 8166144
+ * @summary support new-style options
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.JavadocTask toolbox.ModuleBuilder toolbox.TestRunner toolbox.ToolBox
+ * @run main OptionSyntaxTest
+ */
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+
+public class OptionSyntaxTest extends TestRunner {
+    public static class TestDoclet implements Doclet {
+        @Override
+        public boolean run(DocletEnvironment root) {
+            System.out.println("TestDoclet.run");
+            return true;
+        }
+
+        @Override
+        public String getName() {
+            return "Test";
+        }
+
+        @Override
+        public Set<Option> getSupportedOptions() {
+            return options;
+        }
+
+        @Override
+        public SourceVersion getSupportedSourceVersion() {
+            return SourceVersion.latest();
+        }
+
+        @Override
+        public void init(Locale locale, Reporter reporter) {
+        }
+
+        private final Set<Doclet.Option> options = new HashSet<>(Arrays.asList(
+                new DOption("-old", 0),
+                new DOption("-oldWithArg", 1),
+                new DOption("-oldWithArgs", 2),
+                new DOption("--new", 0),
+                new DOption("--newWithArg", 1),
+                new DOption("--newWithArgs", 2)
+        ));
+
+    }
+
+    static class DOption implements Doclet.Option {
+        private final String name;
+        private final int argCount;
+
+        DOption(String name, int argCount) {
+            this.name = name;
+            this.argCount = argCount;
+        }
+
+        @Override
+        public int getArgumentCount() {
+            return argCount;
+        }
+
+        @Override
+        public String getDescription() {
+            return "description[" + name + "]";
+        }
+
+        @Override
+        public Kind getKind() {
+            return Doclet.Option.Kind.STANDARD;
+        }
+
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public String getParameters() {
+            return argCount > 0 ? "parameters[" + name + "," + argCount + "]" : null;
+        }
+
+        @Override
+        public boolean matches(String option) {
+            return option.equals(name);
+        }
+
+        @Override
+        public boolean process(String option, ListIterator<String> arguments) {
+            List<String> args = new ArrayList<>();
+            for (int i = 0; i < argCount && arguments.hasNext(); i++) {
+                args.add(arguments.next());
+            }
+            System.out.println("process " + option + " " + args);
+            return args.stream().filter(s -> s.startsWith("arg")).count() == argCount;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        OptionSyntaxTest t = new OptionSyntaxTest();
+        t.runTests();
+    }
+
+    private final ToolBox tb = new ToolBox();
+    private final Path src = Paths.get("src");
+    private final Path modules = Paths.get("modules");
+
+    OptionSyntaxTest() throws IOException {
+        super(System.err);
+        initModules();
+    }
+
+    void initModules() throws IOException {
+        new ModuleBuilder(tb, "m1")
+                .exports("p1")
+                .classes("package p1; public class C1 { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "m2")
+                .exports("p2")
+                .classes("package p2; public class C2 { }")
+                .build(modules);
+
+    }
+
+    @Test
+    public void testBasic() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testNewSourcePath() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "--source-path", "src/m1",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testNewSourcePathEquals() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "--source-path=src/m1",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testOldDocletArgs() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "-old",
+                       "-oldWithArg", "arg",
+                       "-oldWithArgs", "arg1", "arg2",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testNewDocletArgs() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "--new",
+                       "--newWithArg", "arg",
+                       "--newWithArgs", "arg1", "arg2",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testNewDocletArgsEquals() {
+        new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "--new", "--newWithArg=arg",
+                       "p1")
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testNewDocletArgsMissingArgs() throws Exception {
+        String log = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "--newWithArg")
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.contains("option --newWithArg requires an argument"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testNewDocletArgsExtraArgs() throws Exception {
+        String log = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "--new=arg",
+                       "p1")
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.contains("option --new does not require an argument"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testNewDocletArgsExtraArgs2() throws Exception {
+        String log = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-docletpath", System.getProperty("test.classes"),
+                       "-doclet", TestDoclet.class.getName(),
+                       "-sourcepath", "src/m1",
+                       "--newWithArgs=arg1 arg2",
+                       "p1")
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.contains("cannot use '=' syntax for options that require multiple arguments"))
+            throw new Exception("expected output not found");
+    }
+
+}
--- a/langtools/test/jdk/javadoc/tool/api/basic/IsSupportedOptionTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/api/basic/IsSupportedOptionTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -35,7 +35,7 @@
 import javax.tools.ToolProvider;
 
 /**
- * Tests for DocumentationTool.usSupportedOption method.
+ * Tests for DocumentationTool.isSupportedOption method.
  */
 public class IsSupportedOptionTest extends APITest {
     public static void main(String... args) throws Exception {
--- a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java	Mon Oct 10 13:31:48 2016 -0700
@@ -70,7 +70,7 @@
     @Test
     public void testModuleModeApi(Path base) throws Exception {
         execTask("--module-source-path", src,
-                "--module", "m1", "--show-module-contents:api");
+                "--module", "m1", "--show-module-contents", "api");
 
         checkModuleMode("API");
     }
@@ -78,7 +78,7 @@
     @Test
     public void testModuleModeAll(Path base) throws Exception {
         execTask("--module-source-path", src,
-                "--module", "m1", "--show-module-contents:all");
+                "--module", "m1", "--show-module-contents", "all");
 
         checkModuleMode("ALL");
     }
@@ -87,7 +87,7 @@
     public void testShowPackagesExported(Path base)  throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-packages:exported"); // default
+                "--show-packages", "exported"); // default
 
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
@@ -99,7 +99,7 @@
     public void testShowPackagesAll(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-packages:all");
+                "--show-packages", "all");
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
         checkPackagesIncluded("pub", "pro");
@@ -112,7 +112,7 @@
     public void testShowTypesPrivate(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-types:private");
+                "--show-types", "private");
 
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
@@ -129,7 +129,7 @@
     public void testShowTypesPackage(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-types:package");
+                "--show-types", "package");
 
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
@@ -145,7 +145,7 @@
     public void testShowTypesProtected(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-types:protected");
+                "--show-types", "protected");
 
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
@@ -162,7 +162,7 @@
     public void testShowTypesPublic(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-types:public");
+                "--show-types", "public");
 
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
@@ -179,7 +179,7 @@
     public void testShowMembersPrivate(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-members:private");
+                "--show-members", "private");
 
         checkMembers(Visibility.PRIVATE);
     }
@@ -188,7 +188,7 @@
     public void testShowMembersPackage(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-members:package");
+                "--show-members", "package");
 
         checkMembers(Visibility.PACKAGE);
     }
@@ -197,7 +197,7 @@
     public void testShowMembersProtected(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-members:protected");
+                "--show-members", "protected");
 
         checkMembers(Visibility.PROTECTED);
     }
@@ -206,7 +206,7 @@
     public void testShowMembersPublic(Path base) throws Exception {
         execTask("--module-source-path", src,
                 "--module", "m1",
-                "--show-members:public");
+                "--show-members", "public");
 
         checkMembers(Visibility.PUBLIC);
     }
--- a/langtools/test/jdk/javadoc/tool/modules/Modules.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java	Mon Oct 10 13:31:48 2016 -0700
@@ -440,7 +440,7 @@
 
         execTask("--module-source-path", src.toString(),
                 "--module", "M",
-                "--expand-requires:public");
+                "--expand-requires", "public");
 
         checkModulesSpecified("M", "N", "O");
         checkModulesIncluded("M", "N", "O");
@@ -465,7 +465,7 @@
 
         execTask("--module-source-path", src.toString(),
                 "--module", "M",
-                "--expand-requires:all");
+                "--expand-requires", "all");
 
         checkModulesSpecified("M", "java.base", "N", "L", "O");
         checkModulesIncluded("M", "java.base", "N", "L", "O");
@@ -493,7 +493,7 @@
 
         execNegativeTask("--module-source-path", src.toString(),
                 "--module", "MIA",
-                "--expand-requires:all");
+                "--expand-requires", "all");
 
         assertErrorPresent("javadoc: error - module MIA not found.");
     }
@@ -515,7 +515,7 @@
 
         execNegativeTask("--module-source-path", src.toString(),
                 "--module", "M,N,L,MIA,O,P",
-                "--expand-requires:all");
+                "--expand-requires", "all");
 
         assertErrorPresent("javadoc: error - module MIA not found");
     }
--- a/langtools/test/jdk/jshell/HistoryTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/jshell/HistoryTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8166744
  * @summary Test Completion
  * @modules jdk.internal.le/jdk.internal.jline.extra
  *          jdk.jshell/jdk.internal.jshell.tool
@@ -75,6 +76,44 @@
              });
     }
 
+    public void test8166744() {
+        test(
+             a -> {if (!a) setCommandInput("class C {\n");},
+             a -> {if (!a) setCommandInput("void f() {\n");},
+             a -> {if (!a) setCommandInput("}\n");},
+             a -> {assertCommand(a, "}", "|  created class C");},
+             a -> {
+                 if (!a) {
+                     try {
+                         previousAndAssert(getHistory(), "}");
+                         previousAndAssert(getHistory(), "}");
+                         previousAndAssert(getHistory(), "void f() {");
+                         previousAndAssert(getHistory(), "class C {");
+                         getHistory().add("class C{");
+                     } catch (Exception ex) {
+                         throw new IllegalStateException(ex);
+                     }
+                 }
+                 assertCommand(a, "int dummy;", "dummy ==> 0");
+             });
+        test(
+             a -> {if (!a) setCommandInput("class C {\n");},
+             a -> {if (!a) setCommandInput("void f() {\n");},
+             a -> {if (!a) setCommandInput("}\n");},
+             a -> {assertCommand(a, "}", "|  created class C");},
+             a -> {
+                 if (!a) {
+                     try {
+                         previousSnippetAndAssert(getHistory(), "class C {");
+                         getHistory().add("class C{");
+                     } catch (Exception ex) {
+                         throw new IllegalStateException(ex);
+                     }
+                 }
+                 assertCommand(a, "int dummy;", "dummy ==> 0");
+             });
+    }
+
     private EditingHistory getHistory() throws Exception {
         Field input = repl.getClass().getDeclaredField("input");
         input.setAccessible(true);
--- a/langtools/test/jdk/jshell/ToolBasicTest.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347
+ * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714
  * @summary Tests for Basic tests for REPL tool
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -574,4 +574,20 @@
         }
     }
 
+    public void testAddExports() {
+        test(false, new String[]{"--no-startup"},
+                a -> assertCommandOutputStartsWith(a, "import jdk.internal.misc.VM;", "|  Error:")
+        );
+        test(false, new String[]{"--no-startup",
+            "-R--add-exports", "-Rjava.base/jdk.internal.misc=ALL-UNNAMED",
+            "-C--add-exports", "-Cjava.base/jdk.internal.misc=ALL-UNNAMED"},
+                a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"),
+                a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n")
+        );
+        test(false, new String[]{"--no-startup", "--add-exports", "java.base/jdk.internal.misc"},
+                a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"),
+                a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n")
+        );
+    }
+
 }
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Mon Oct 10 13:31:48 2016 -0700
@@ -66,6 +66,7 @@
 compiler.misc.kindname.type.variable.bound
 compiler.misc.kindname.value
 compiler.misc.incompatible.eq.lower.bounds              # cannot happen?
+compiler.misc.module.name.mismatch
 compiler.misc.no.unique.minimal.instance.exists
 compiler.misc.no.unique.maximal.instance.exists         # cannot happen?
 compiler.misc.resume.abort                              # prompt for a response
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/bridges/ReorderedBoundsTest.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8166363
+ * @summary Method with reordered type parameter bounds compiles with Override annotation but does not actually override superclass method.
+ * @run main ReorderedBoundsTest
+ */
+
+import java.io.Serializable;
+
+public class ReorderedBoundsTest {
+  public static class Parent {
+    public <T extends Appendable & Serializable> String printClassName(T t) {
+      return "Parent";
+    }
+  }
+
+  public static class OrderedChild extends Parent {
+    @Override
+    public <T extends Appendable & Serializable> String printClassName(T t) {
+      return "OrderedChild";
+    }
+  }
+
+  public static class ReorderedChild extends Parent {
+    @Override
+    public <T extends Serializable & Appendable> String printClassName(T t) {
+      return "ReorderedChild";
+    }
+  }
+
+  public static void main(String[] args) {
+
+    String s;
+    Parent p = new OrderedChild();
+    if (!(s = p.printClassName(new StringBuilder())).equals("OrderedChild"))
+        throw new AssertionError("Bad output: " + s);
+
+    p = new ReorderedChild();
+    if (!(s = p.printClassName(new StringBuilder())).equals("ReorderedChild"))
+        throw new AssertionError("Bad output: " + s);
+  }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/modules/EdgeCases.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/javac/modules/EdgeCases.java	Mon Oct 10 13:31:48 2016 -0700
@@ -58,6 +58,8 @@
 import toolbox.JarTask;
 import toolbox.JavacTask;
 import toolbox.Task;
+import toolbox.Task.Expect;
+import toolbox.Task.OutputKind;
 
 public class EdgeCases extends ModuleTestBase {
 
@@ -304,4 +306,147 @@
         }
     }
 
+    @Test
+    public void testImplicitJavaBase(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_java_base = src.resolve("java.base");
+        Files.createDirectories(src_java_base);
+        tb.writeJavaFiles(src_java_base, "module java.base { exports java.lang; }");
+        tb.writeJavaFiles(src_java_base,
+                          "package java.lang; public class Object {}");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        //module-info from source:
+        new JavacTask(tb)
+            .options("-sourcepath", src_java_base.toString())
+            .outdir(classes)
+            .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
+            .run()
+            .writeAll();
+
+        //module-info from class:
+        if (!Files.exists(classes.resolve("module-info.class"))) {
+            throw new AssertionError("module-info.class not created!");
+        }
+
+        new JavacTask(tb)
+            .outdir(classes)
+            .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
+            .run()
+            .writeAll();
+
+        //broken module-info.class:
+        Files.newOutputStream(classes.resolve("module-info.class")).close();
+
+        List<String> log = new JavacTask(tb)
+            .options("-XDrawDiagnostics")
+            .outdir(classes)
+            .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
+            .run(Expect.FAIL)
+            .writeAll()
+            .getOutputLines(OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "- compiler.err.cant.access: <error>.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.illegal.start.of.class.file))",
+                "1 error");
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+
+        //broken module-info.java:
+        Files.delete(classes.resolve("module-info.class"));
+
+        try (Writer out = Files.newBufferedWriter(src_java_base.resolve("module-info.java"))) {
+            out.write("class Broken {}");
+        }
+
+        log = new JavacTask(tb)
+            .options("-sourcepath", src_java_base.toString(),
+                                "-XDrawDiagnostics")
+            .outdir(classes)
+            .files(findJavaFiles(src_java_base.resolve("java").resolve("lang").resolve("Object.java")))
+            .run(Expect.FAIL)
+            .writeAll()
+            .getOutputLines(OutputKind.DIRECT);
+
+        expected = Arrays.asList("X");
+
+        if (expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    @Test
+    public void testModuleInfoNameMismatchSource(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path m1 = src.resolve("m1");
+        Files.createDirectories(m1);
+        tb.writeJavaFiles(m1, "module other { }",
+                              "package test; public class Test {}");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+            .options("--module-source-path", src.toString(),
+                     "-XDrawDiagnostics")
+            .outdir(classes)
+            .files(findJavaFiles(m1.resolve("test").resolve("Test.java")))
+            .run(Expect.FAIL)
+            .writeAll()
+            .getOutputLines(OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "module-info.java:1:1: compiler.err.module.name.mismatch: other, m1",
+                "- compiler.err.cant.access: m1.module-info, (compiler.misc.cant.resolve.modules)",
+                "2 errors");
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    @Test
+    public void testModuleInfoNameMismatchClass(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Files.createDirectories(src);
+        tb.writeJavaFiles(src, "module other { }",
+                               "package test; public class Test {}");
+        Path classes = base.resolve("classes");
+        Path m1Classes = classes.resolve("m1");
+        tb.createDirectories(m1Classes);
+
+        new JavacTask(tb)
+            .outdir(m1Classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll()
+            .getOutputLines(OutputKind.DIRECT);
+
+        Path src2 = base.resolve("src2");
+        Files.createDirectories(src2);
+        tb.writeJavaFiles(src2, "module use { requires m1; }");
+
+        Path classes2 = base.resolve("classes2");
+        tb.createDirectories(classes2);
+
+        List<String> log = new JavacTask(tb)
+            .options("--module-path", classes.toString(),
+                     "-XDrawDiagnostics")
+            .outdir(classes2)
+            .files(findJavaFiles(src2))
+            .run(Expect.FAIL)
+            .writeAll()
+            .getOutputLines(OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "- compiler.err.cant.access: m1.module-info, (compiler.misc.bad.class.file.header: module-info.class, (compiler.misc.module.name.mismatch: other, m1))",
+                "1 error");
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/StopAfterError/StopAfterError.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8073844
+ * @summary If an error is produced by an annotation processor, the code should not be Attred, \
+ *          unless requested
+ * @modules jdk.compiler
+ * @compile StopAfterError.java
+ * @compile/fail/ref=StopAfterError.out -XDrawDiagnostics -processor StopAfterError StopAfterErrorAux.java
+ * @compile/fail/ref=StopAfterError.out -XDshould-stop.ifError=PROCESS -XDrawDiagnostics -processor StopAfterError StopAfterErrorAux.java
+ * @compile/fail/ref=StopAfterErrorContinue.out -XDshould-stop.ifError=ATTR -XDrawDiagnostics -processor StopAfterError StopAfterErrorAux.java
+ */
+
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
+
+@SupportedAnnotationTypes("*")
+public class StopAfterError extends AbstractProcessor {
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Stop!");
+        }
+        return false;
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latestSupported();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/StopAfterError/StopAfterError.out	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,2 @@
+- compiler.err.proc.messager: Stop!
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/StopAfterError/StopAfterErrorAux.java	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,6 @@
+/* /nodynamiccopyright/ */
+class StopAfterErrorAux {
+    public void test() {
+        should not; get here;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/StopAfterError/StopAfterErrorContinue.out	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,4 @@
+- compiler.err.proc.messager: Stop!
+StopAfterErrorAux.java:4:9: compiler.err.cant.resolve.location: kindname.class, should, , , (compiler.misc.location: kindname.class, StopAfterErrorAux, null)
+StopAfterErrorAux.java:4:21: compiler.err.cant.resolve.location: kindname.class, get, , , (compiler.misc.location: kindname.class, StopAfterErrorAux, null)
+3 errors
--- a/langtools/test/tools/jdeps/APIDeps.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/jdeps/APIDeps.java	Mon Oct 10 13:31:48 2016 -0700
@@ -135,7 +135,7 @@
                            "java.util.Set",
                            "c.C", "d.D", "c.I", "e.E", "m.Bar"},
              new String[] {"compact1", testDirBasename, mDir.getName()},
-             new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "-apionly"});
+             new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "--api-only"});
         return errors;
     }
 
--- a/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/jdeps/jdkinternals/ShowReplacement.java	Mon Oct 10 13:31:48 2016 -0700
@@ -116,7 +116,7 @@
     @Test
     public void removedPackage() {
         Path file = Paths.get("q", "RemovedPackage.class");
-        String[] output = JdepsUtil.jdeps("-jdkinternals", CLASSES_DIR.resolve(file).toString());
+        String[] output = JdepsUtil.jdeps("--jdk-internals", CLASSES_DIR.resolve(file).toString());
         int i = 0;
         // expect no replacement
         while (i < output.length && !output[i].contains("Suggested Replacement")) {
--- a/langtools/test/tools/jdeps/modules/GenModuleInfo.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/jdeps/modules/GenModuleInfo.java	Mon Oct 10 13:31:48 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @summary Tests jdeps --gen-module-info option
+ * @summary Tests jdeps --generate-module-info option
  * @library ../lib
  * @build CompilerUtils JdepsUtil
  * @modules jdk.jdeps/com.sun.tools.jdeps
@@ -106,7 +106,7 @@
                 .map(mn -> LIBS_DIR.resolve(mn + ".jar"))
                 .map(Path::toString);
 
-        JdepsUtil.jdeps(Stream.concat(Stream.of("--gen-module-info", DEST_DIR.toString()),
+        JdepsUtil.jdeps(Stream.concat(Stream.of("--generate-module-info", DEST_DIR.toString()),
                                       files).toArray(String[]::new));
 
         // check file exists
--- a/langtools/test/tools/jdeps/modules/InverseDeps.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/jdeps/modules/InverseDeps.java	Mon Oct 10 13:31:48 2016 -0700
@@ -91,7 +91,7 @@
     @DataProvider(name = "testrequires")
     public Object[][] expected1() {
         return new Object[][] {
-            // -requires and result
+            // --require and result
             { "java.sql", new String[][] {
                     new String[] { "java.sql", "m5" },
                 }
@@ -117,7 +117,7 @@
 
     @Test(dataProvider = "testrequires")
     public void testrequires(String name, String[][] expected) throws Exception {
-        String cmd1 = String.format("jdeps -inverse --module-path %s -requires %s --add-modules %s%n",
+        String cmd1 = String.format("jdeps --inverse --module-path %s --require %s --add-modules %s%n",
                 MODS_DIR, name, modules.stream().collect(Collectors.joining(",")));
 
         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd1)) {
@@ -128,7 +128,7 @@
             runJdeps(jdeps, expected);
         }
 
-        String cmd2 = String.format("jdeps -inverse --module-path %s -requires %s" +
+        String cmd2 = String.format("jdeps --inverse --module-path %s --require %s" +
             " --add-modules ALL-MODULE-PATH%n", LIBS_DIR, name);
 
             // automatic module
@@ -164,7 +164,7 @@
 
     @Test(dataProvider = "testpackage")
     public void testpackage(String name, String[][] expected) throws Exception {
-        String cmd = String.format("jdeps -inverse --module-path %s -package %s --add-modules %s%n",
+        String cmd = String.format("jdeps --inverse --module-path %s -package %s --add-modules %s%n",
             MODS_DIR, name, modules.stream().collect(Collectors.joining(",")));
         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) {
             jdeps.appModulePath(MODS_DIR.toString())
@@ -195,7 +195,7 @@
 
     @Test(dataProvider = "testregex")
     public void testregex(String name, String[][] expected) throws Exception {
-        String cmd = String.format("jdeps -inverse --module-path %s -regex %s --add-modules %s%n",
+        String cmd = String.format("jdeps --inverse --module-path %s -regex %s --add-modules %s%n",
                 MODS_DIR, name, modules.stream().collect(Collectors.joining(",")));
 
         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd)) {
@@ -240,7 +240,7 @@
 
         Path jarfile = LIBS_DIR.resolve("m7.jar");
 
-        String cmd1 = String.format("jdeps -inverse -classpath %s -regex %s %s%n",
+        String cmd1 = String.format("jdeps --inverse -classpath %s -regex %s %s%n",
             cpath, name, jarfile);
         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd1)) {
             jdeps.verbose("-verbose:class")
@@ -253,7 +253,7 @@
         Set<Path> paths = modules.stream()
                                  .map(mn -> LIBS_DIR.resolve(mn + ".jar"))
                                  .collect(Collectors.toSet());
-        String cmd2 = String.format("jdeps -inverse -regex %s %s%n", name, paths);
+        String cmd2 = String.format("jdeps --inverse -regex %s %s%n", name, paths);
         try (JdepsUtil.Command jdeps = JdepsUtil.newCommand(cmd2)) {
             jdeps.verbose("-verbose:class").regex(name);
             paths.forEach(jdeps::addRoot);
--- a/langtools/test/tools/jdeps/modules/src/m3/module-info.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/langtools/test/tools/jdeps/modules/src/m3/module-info.java	Mon Oct 10 13:31:48 2016 -0700
@@ -24,7 +24,7 @@
 module m3 {
     requires public java.sql;
     requires public m2;
-    requires java.logging;   // TODO: --gen-module-info to do transitive reduction
+    requires java.logging;   // TODO: --generate-module-info to do transitive reduction
     requires public m1;
     exports p3;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/ExplodedImageOptimize.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  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.
+#
+
+# Runs a tool on the exploded image to improve performance
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include $(JDK_TOPDIR)/make/ModuleTools.gmk
+
+################################################################################
+
+PACKAGES_ATTRIBUTE_TARGET := $(JDK_OUTPUTDIR)/_packages_attribute.done
+ALL_MODULEINFO_CLASSES := $(wildcard $(JDK_OUTPUTDIR)/modules/*/module_info.class)
+
+$(PACKAGES_ATTRIBUTE_TARGET): $(ALL_MODULEINFO_CLASSES) $(BUILD_JIGSAW_CLASSES)
+	$(call LogInfo, Optimizing the exploded image)
+	$(TOOL_ADD_PACKAGES_ATTRIBUTE) $(JDK_OUTPUTDIR)
+
+TARGETS := $(PACKAGES_ATTRIBUTE_TARGET)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all default
--- a/make/Javadoc.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/make/Javadoc.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -1575,7 +1575,7 @@
 $(JACCESSAPI_INDEX_HTML): $(JACCESSAPI_OPTIONS_FILE) $(JACCESSAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
 	$(prep-javadoc)
 	$(call JavadocSummary,$(JACCESSAPI_OPTIONS_FILE),$(JACCESSAPI_PACKAGES_FILE))
-	$(JAVADOC_CMD) -d $(@D) \
+	$(JAVADOC_CMD_SMALL) -d $(@D) \
 	    @$(JACCESSAPI_OPTIONS_FILE) @$(JACCESSAPI_PACKAGES_FILE)
 
 # Create file with javadoc options in it
--- a/make/Main.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/make/Main.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -82,10 +82,13 @@
 
   buildtools-jdk:
 	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileTools.gmk)
+
+  buildtools-modules:
+	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CompileModuleTools.gmk)
 endif
 
 ALL_TARGETS += buildtools-langtools interim-langtools \
-    interim-rmic interim-cldrconverter buildtools-jdk
+    interim-rmic interim-cldrconverter buildtools-jdk buildtools-modules
 
 ################################################################################
 # Special targets for certain modules
@@ -340,8 +343,12 @@
 mac-bundles-jdk:
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk)
 
+exploded-image-optimize:
+	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f ExplodedImageOptimize.gmk)
+
 ALL_TARGETS += source-tips create-hgtip-files bootcycle-images zip-security \
-     zip-source jrtfs-jar jimages profiles mac-bundles-jdk
+    zip-source jrtfs-jar jimages profiles mac-bundles-jdk \
+    exploded-image-optimize
 
 ################################################################################
 # Docs targets
@@ -521,6 +528,8 @@
 
   buildtools-jdk: interim-langtools interim-cldrconverter
 
+  buildtools-modules: exploded-image-base
+
   $(CORBA_GENSRC_TARGETS): interim-langtools
 
   $(HOTSPOT_GENSRC_TARGETS): interim-langtools
@@ -646,6 +655,7 @@
     # Avoid calling create-buildjdk from within a create-buildjdk call
     ifneq ($(CREATING_BUILDJDK), true)
       $(JMOD_TARGETS): create-buildjdk
+      buildtools-modules: create-buildjdk
     endif
   endif
 
@@ -677,6 +687,8 @@
 
   mac-bundles-jdk: jimages
 
+  exploded-image-optimize: exploded-image-base buildtools-modules
+
   bootcycle-images: jimages
 
   docs-javadoc: $(GENSRC_TARGETS) rmic
@@ -728,7 +740,7 @@
 
   docs-bundles: docs-image
 
-  generate-summary: jmods
+  generate-summary: jmods buildtools-modules
 
 endif
 
@@ -774,7 +786,8 @@
 samples: samples-jdk
 
 # The "exploded image" is a locally runnable JDK in $(BUILD_OUTPUT)/jdk.
-exploded-image: $(ALL_MODULES)
+exploded-image-base: $(ALL_MODULES)
+exploded-image: exploded-image-base exploded-image-optimize
 
 create-buildjdk: create-buildjdk-copy create-buildjdk-interim-image
 
@@ -815,7 +828,8 @@
 all-bundles: product-bundles test-bundles docs-bundles
 
 ALL_TARGETS += buildtools gensrc gendata copy java rmic libs launchers jmods \
-    jdk.jdwp.agent-gensrc $(ALL_MODULES) demos samples exploded-image \
+    jdk.jdwp.agent-gensrc $(ALL_MODULES) demos samples \
+    exploded-image-base exploded-image \
     create-buildjdk mac-bundles product-images docs-image test-image all-images \
     all-bundles
 
--- a/make/MainSupport.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/make/MainSupport.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -137,7 +137,6 @@
 define DeclareRecipeForModuleMakefile
   ifeq ($$($1_MULTIPLE_MAKEFILES), true)
     $2-$$($1_TARGET_SUFFIX): $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
-    $1 += $2-$$($1_TARGET_SUFFIX)-$$(notdir $3)
 
     $2-$$($1_TARGET_SUFFIX)-$$(notdir $3):
   else
@@ -173,6 +172,12 @@
 
   # Only declare recipes if there are makefiles to call
   ifneq ($$($1_$2_TOPDIRS), )
+    # Add the top dir specific target to target list regardless of if recipe
+    # generation is disabled.
+    ifeq ($$($1_MULTIPLE_MAKEFILES), true)
+      $$(foreach d, $$($1_$2_TOPDIRS), \
+        $$(eval $1 += $2-$$($1_TARGET_SUFFIX)-$$(notdir $$d)))
+    endif
     ifeq ($(NO_RECIPES),)
       $$(foreach d, $$($1_$2_TOPDIRS), \
           $$(eval $$(call DeclareRecipeForModuleMakefile,$1,$2,$$d)))
--- a/make/common/SetupJavaCompilers.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/make/common/SetupJavaCompilers.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -38,7 +38,10 @@
 # and the interim javac, to be run by the boot jdk.
 $(eval $(call SetupJavaCompiler,BOOT_JAVAC, \
     JAVAC := $(JAVAC), \
-    FLAGS := $(BOOT_JDK_SOURCETARGET) -XDignore.symbol.file=true -g \
+    FLAGS := \
+        $(JAVA_TOOL_FLAGS_SMALL) \
+        $(BOOT_JDK_SOURCETARGET) \
+        -XDignore.symbol.file=true -g \
         -Xlint:all$(COMMA)-deprecation$(COMMA)-options -Werror, \
     DISABLE_SJAVAC := true, \
 ))
--- a/nashorn/.hgtags	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/.hgtags	Mon Oct 10 13:31:48 2016 -0700
@@ -371,3 +371,4 @@
 cb00d5ef023a18a66fcb4311ed4474d4145c66e9 jdk-9+135
 f11b8f5c4ccbf9c87d283815abac6c0117fba3c0 jdk-9+136
 17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137
+4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138
--- a/nashorn/make/BuildNashorn.gmk	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/make/BuildNashorn.gmk	Mon Oct 10 13:31:48 2016 -0700
@@ -26,7 +26,7 @@
 # This must be the first rule
 default: all
 
--include $(SPEC)
+include $(SPEC)
 include MakeBase.gmk
 include JarArchive.gmk
 include JavaCompilation.gmk
@@ -42,7 +42,7 @@
 
 # Need to use source and target 8 for nasgen to work.
 $(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG, \
-    JVM := $(JAVA), \
+    JVM := $(JAVA_JAVAC), \
     JAVAC := $(NEW_JAVAC), \
     FLAGS := -g -source 9 -target 9 --upgrade-module-path "$(JDK_OUTPUTDIR)/modules/" \
          --system none --module-source-path "$(MODULESOURCEPATH)", \
@@ -91,7 +91,7 @@
 	$(MKDIR) -p $(@D)
 	$(RM) -rf $(@D)/jdk $(@D)/netscape
 	$(CP) -R -p $(SUPPORT_OUTPUTDIR)/special_classes/jdk.scripting.nashorn/* $(@D)/
-	$(JAVA) $(NASGEN_OPTIONS) \
+	$(JAVA_SMALL) $(NASGEN_OPTIONS) \
 	    jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
 	$(TOUCH) $@
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Oct 10 13:31:48 2016 -0700
@@ -2486,11 +2486,6 @@
                     }
 
                     @Override
-                    public boolean enterObjectNode(final ObjectNode objectNode) {
-                        return false;
-                    }
-
-                    @Override
                     public boolean enterDefault(final Node node) {
                         if (contains) {
                             return false;
@@ -2562,7 +2557,8 @@
             oc = new FieldObjectCreator<Expression>(this, tuples) {
                 @Override
                 protected void loadValue(final Expression node, final Type type) {
-                    loadExpressionAsType(node, type);
+                    // Use generic type in order to avoid conversion between object types
+                    loadExpressionAsType(node, Type.generic(type));
                 }};
         }
 
@@ -2578,10 +2574,7 @@
         //handler
         if (restOfProperty) {
             final ContinuationInfo ci = getContinuationInfo();
-            // Can be set at most once for a single rest-of method
-            assert ci.getObjectLiteralMap() == null;
-            ci.setObjectLiteralMap(oc.getMap());
-            ci.setObjectLiteralStackDepth(method.getStackSize());
+            ci.setObjectLiteralMap(method.getStackSize(), oc.getMap());
         }
 
         method.dup();
@@ -5309,10 +5302,8 @@
         private Type[] stackTypes;
         // If non-null, this node should perform the requisite type conversion
         private Type returnValueType;
-        // If we are in the middle of an object literal initialization, we need to update the map
-        private PropertyMap objectLiteralMap;
-        // Object literal stack depth for object literal - not necessarily top if property is a tree
-        private int objectLiteralStackDepth = -1;
+        // If we are in the middle of an object literal initialization, we need to update the property maps
+        private Map<Integer, PropertyMap> objectLiteralMaps;
         // The line number at the continuation point
         private int lineNumber;
         // The active catch label, in case the continuation point is in a try/catch block
@@ -5364,20 +5355,15 @@
             this.returnValueType = returnValueType;
         }
 
-        int getObjectLiteralStackDepth() {
-            return objectLiteralStackDepth;
-        }
-
-        void setObjectLiteralStackDepth(final int objectLiteralStackDepth) {
-            this.objectLiteralStackDepth = objectLiteralStackDepth;
-        }
-
-        PropertyMap getObjectLiteralMap() {
-            return objectLiteralMap;
-        }
-
-        void setObjectLiteralMap(final PropertyMap objectLiteralMap) {
-            this.objectLiteralMap = objectLiteralMap;
+        void setObjectLiteralMap(final int objectLiteralStackDepth, final PropertyMap objectLiteralMap) {
+            if (objectLiteralMaps == null) {
+                objectLiteralMaps = new HashMap<>();
+            }
+            objectLiteralMaps.put(objectLiteralStackDepth, objectLiteralMap);
+        }
+
+        PropertyMap getObjectLiteralMap(final int stackDepth) {
+            return objectLiteralMaps == null ? null : objectLiteralMaps.get(stackDepth);
         }
 
         @Override
@@ -5467,10 +5453,9 @@
         final int[]   stackStoreSpec = ci.getStackStoreSpec();
         final Type[]  stackTypes     = ci.getStackTypes();
         final boolean isStackEmpty   = stackStoreSpec.length == 0;
-        boolean replacedObjectLiteralMap = false;
+        int replacedObjectLiteralMaps = 0;
         if(!isStackEmpty) {
             // Load arguments on the stack
-            final int objectLiteralStackDepth = ci.getObjectLiteralStackDepth();
             for(int i = 0; i < stackStoreSpec.length; ++i) {
                 final int slot = stackStoreSpec[i];
                 method.load(lvarTypes.get(slot), slot);
@@ -5478,18 +5463,18 @@
                 // stack: s0=object literal being initialized
                 // change map of s0 so that the property we are initializing when we failed
                 // is now ci.returnValueType
-                if (i == objectLiteralStackDepth) {
+                final PropertyMap map = ci.getObjectLiteralMap(i);
+                if (map != null) {
                     method.dup();
-                    assert ci.getObjectLiteralMap() != null;
                     assert ScriptObject.class.isAssignableFrom(method.peekType().getTypeClass()) : method.peekType().getTypeClass() + " is not a script object";
-                    loadConstant(ci.getObjectLiteralMap());
+                    loadConstant(map);
                     method.invoke(ScriptObject.SET_MAP);
-                    replacedObjectLiteralMap = true;
+                    replacedObjectLiteralMaps++;
                 }
             }
         }
-        // Must have emitted the code for replacing the map of an object literal if we have a set object literal stack depth
-        assert ci.getObjectLiteralStackDepth() == -1 || replacedObjectLiteralMap;
+        // Must have emitted the code for replacing all object literal maps
+        assert ci.objectLiteralMaps == null || ci.objectLiteralMaps.size() == replacedObjectLiteralMaps;
         // Load RewriteException back.
         method.load(rewriteExceptionType, lvarCount);
         // Get rid of the stored reference
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Mon Oct 10 13:31:48 2016 -0700
@@ -189,7 +189,8 @@
 
     @Override
     protected void loadValue(final Expression expr, final Type type) {
-        codegen.loadExpressionAsType(expr, type);
+        // Use generic type in order to avoid conversion between object types
+        codegen.loadExpressionAsType(expr, Type.generic(type));
     }
 
     @Override
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Mon Oct 10 13:31:48 2016 -0700
@@ -473,22 +473,6 @@
     }
 
     @Override
-    protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) {
-        if (overrides && super.hasOwnProperty(NashornCallSiteDescriptor.getOperand(desc))) {
-            try {
-                final GuardedInvocation inv = super.findCallMethodMethod(desc, request);
-                if (inv != null) {
-                    return inv;
-                }
-            } catch (final Exception e) {
-                //ignored
-            }
-        }
-
-        return findHook(desc, __call__);
-    }
-
-    @Override
     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final StandardOperation operation) {
         final String name = NashornCallSiteDescriptor.getOperand(desc);
         if (overrides && super.hasOwnProperty(name)) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Oct 10 13:31:48 2016 -0700
@@ -80,7 +80,6 @@
 import jdk.nashorn.internal.objects.NativeArray;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
@@ -1883,8 +1882,6 @@
             return findCallMethod(desc, request);
         case NEW:
             return findNewMethod(desc, request);
-        case CALL_METHOD:
-            return findCallMethodMethod(desc, request);
         default:
         }
         return null;
@@ -1920,32 +1917,6 @@
     }
 
     /**
-     * Find an implementation for a CALL_METHOD operation. Note that Nashorn internally never uses
-     * CALL_METHOD, but instead always emits two call sites in bytecode, one for GET_METHOD, and then another
-     * one for CALL. Explicit support for CALL_METHOD is provided for the benefit of potential external
-     * callers. The implementation itself actually folds a GET_METHOD method handle into a CALL method handle.
-     *
-     * @param desc    the call site descriptor.
-     * @param request the link request
-     *
-     * @return GuardedInvocation to be invoked at call site.
-     */
-    protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) {
-        // R(P0, P1, ...)
-        final MethodType callType = desc.getMethodType();
-        // use type Object(P0) for the getter
-        final CallSiteDescriptor getterType = desc.changeMethodType(MethodType.methodType(Object.class, callType.parameterType(0)));
-        final GuardedInvocation getter = findGetMethod(getterType, request, StandardOperation.GET_METHOD);
-
-        // Object(P0) => Object(P0, P1, ...)
-        final MethodHandle argDroppingGetter = MH.dropArguments(getter.getInvocation(), 1, callType.parameterList().subList(1, callType.parameterCount()));
-        // R(Object, P0, P1, ...)
-        final MethodHandle invoker = Bootstrap.createDynamicInvoker("", NashornCallSiteDescriptor.CALL, callType.insertParameterTypes(0, argDroppingGetter.type().returnType()));
-        // Fold Object(P0, P1, ...) into R(Object, P0, P1, ...) => R(P0, P1, ...)
-        return getter.replaceMethods(MH.foldArguments(invoker, argDroppingGetter), getter.getGuard());
-    }
-
-    /**
      * Test whether this object contains in its prototype chain or is itself a with-object.
      * @return true if a with-object was found
      */
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Undefined.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Undefined.java	Mon Oct 10 13:31:48 2016 -0700
@@ -103,8 +103,6 @@
             final String name = NashornCallSiteDescriptor.getOperand(desc);
             final String msg = name != null? "not.a.function" : "cant.call.undefined";
             throw typeError(msg, name);
-        case CALL_METHOD:
-            throw lookupTypeError("cant.read.property.of.undefined", desc);
         case GET_PROPERTY:
         case GET_ELEMENT:
         case GET_METHOD:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Mon Oct 03 14:10:40 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Mon Oct 10 13:31:48 2016 -0700
@@ -86,13 +86,11 @@
     private static final MethodHandle EMPTY_ELEM_SETTER =
             MH.dropArguments(EMPTY_PROP_SETTER, 0, Object.class);
 
-    private static final MethodHandle THROW_NO_SUCH_FUNCTION;
     private static final MethodHandle THROW_STRICT_PROPERTY_SETTER;
     private static final MethodHandle THROW_OPTIMISTIC_UNDEFINED;
 
     static {
         final Lookup lookup = new Lookup(MethodHandles.lookup());
-        THROW_NO_SUCH_FUNCTION = lookup.findOwnStatic("throwNoSuchFunction", Object.class, Object.class, Object.class);
         THROW_STRICT_PROPERTY_SETTER = lookup.findOwnStatic("throwStrictPropertySetter", void.class, Object.class, Object.class);
         THROW_OPTIMISTIC_UNDEFINED = lookup.findOwnStatic("throwOptimisticUndefined", Object.class, int.class);
     }
@@ -130,8 +128,6 @@
         if (op != null) {
             final String operand = NashornCallSiteDescriptor.getOperand(desc);
             switch (op) {
-            case CALL_METHOD:
-                return adaptThrower(bindOperand(THROW_NO_SUCH_FUNCTION, operand), desc);
             case GET_METHOD:
             case GET_PROPERTY:
             case GET_ELEMENT: {
@@ -172,11 +168,6 @@
     }
 
     @SuppressWarnings("unused")
-    private static Object throwNoSuchFunction(final Object self, final Object name) {
-        throw createTypeError(self, name, "no.such.function");
-    }
-
-    @SuppressWarnings("unused")
     private static void throwStrictPropertySetter(final Object self, final Object name) {
         throw createTypeError(self, name, "cant.set.property");
     }
@@ -230,7 +221,6 @@
         case NEW:
         case CALL:
             throw typeError("not.a.function", "null");
-        case CALL_METHOD:
         case GET_METHOD:
             throw typeError("no.such.function", getArgument(linkRequest), "null");
         case GET_PROPERTY:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8166902.js	Mon Oct 10 13:31:48 2016 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8166902: Nested object literal property maps not reset in optimistic recompilation
+ *
+ * @test
+ * @run
+ */
+
+var o = {
+    a: "A",
+    b: "B"
+};
+
+var m = {
+    x: { z: o.a },
+    y: o.b
+};
+
+Assert.assertEquals(m.x.z, "A");
+Assert.assertEquals(m.y, "B");
+