Merge http-client-branch
authordfuchs
Tue, 24 Apr 2018 10:20:22 +0100
branchhttp-client-branch
changeset 56478 90df053536e0
parent 56477 46c04919ee5c (current diff)
parent 49868 d5cecd70fc0f (diff)
child 56480 97bff67fed21
Merge
src/hotspot/share/gc/shared/commandLineFlagConstraintsGC.cpp
src/hotspot/share/gc/shared/commandLineFlagConstraintsGC.hpp
src/hotspot/share/runtime/commandLineFlagConstraintList.cpp
src/hotspot/share/runtime/commandLineFlagConstraintList.hpp
src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp
src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.hpp
src/hotspot/share/runtime/commandLineFlagConstraintsRuntime.cpp
src/hotspot/share/runtime/commandLineFlagConstraintsRuntime.hpp
src/hotspot/share/runtime/commandLineFlagRangeList.cpp
src/hotspot/share/runtime/commandLineFlagRangeList.hpp
src/hotspot/share/runtime/commandLineFlagWriteableList.cpp
src/hotspot/share/runtime/commandLineFlagWriteableList.hpp
src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java
src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java
src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c
src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c
src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM942C.java
src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM943C.java
test/jdk/ProblemList.txt
test/langtools/tools/javac/6410653/T6410653.java
test/langtools/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java
test/langtools/tools/javac/options/release/ReleaseOptionClashes.java
--- a/.hgtags	Tue Apr 24 10:17:23 2018 +0100
+++ b/.hgtags	Tue Apr 24 10:20:22 2018 +0100
@@ -481,3 +481,4 @@
 755e1b55a4dff510f9639cdb5c5e82549a7e09b3 jdk-11+8
 0c3e252cea44f06aef570ef464950ab97c669970 jdk-11+9
 6fa770f9f8ab296e1ce255ec17ccf6d4e1051886 jdk-10+46
+69d7398038c54774d9395b6810e0cca335edc02c jdk-11+10
--- a/make/Init.gmk	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/Init.gmk	Tue Apr 24 10:20:22 2018 +0100
@@ -310,9 +310,13 @@
           ifneq ($(PARALLEL_TARGETS), )
 	    $(call StartGlobalTimer)
 	    $(call PrepareSmartJavac)
+            # JOBS will only be empty for a bootcycle-images recursive call
+            # or if specified via a make argument directly. In those cases
+            # treat it as NOT using jobs at all.
 	    ( cd $(TOPDIR) && \
 	        $(NICE) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
-	            -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
+                    $(if $(JOBS), -j $(JOBS)) \
+	            -f make/Main.gmk $(USER_MAKE_VARS) \
 	            $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE) $(BUILD_LOG_PIPE) || \
 	        ( exitcode=$$? && \
 	        $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" \
--- a/make/autoconf/flags.m4	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/autoconf/flags.m4	Tue Apr 24 10:20:22 2018 +0100
@@ -233,15 +233,17 @@
   # The sysroot flags are needed for configure to be able to run the compilers
   FLAGS_SETUP_SYSROOT_FLAGS
 
+  # For solstudio and xlc, the word size flag is required for correct behavior.
+  # For clang/gcc, the flag is only strictly required for reduced builds, but
+  # set it always where possible (x86, sparc and ppc).
   if test "x$TOOLCHAIN_TYPE" = xxlc; then
     MACHINE_FLAG="-q${OPENJDK_TARGET_CPU_BITS}"
-  elif test "x$TOOLCHAIN_TYPE" != xmicrosoft; then
-    if test "x$OPENJDK_TARGET_CPU" != xaarch64 &&
-       test "x$OPENJDK_TARGET_CPU" != xarm &&
-       test "x$OPENJDK_TARGET_CPU" != xmips &&
-       test "x$OPENJDK_TARGET_CPU" != xmipsel &&
-       test "x$OPENJDK_TARGET_CPU" != xmips64 &&
-       test "x$OPENJDK_TARGET_CPU" != xmips64el; then
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    MACHINE_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
+  elif test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
+    if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86 ||
+        test "x$OPENJDK_TARGET_CPU_ARCH" = xsparc ||
+        test "x$OPENJDK_TARGET_CPU_ARCH" = xppc; then
       MACHINE_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
     fi
   fi
--- a/make/data/charsetmapping/charsets	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/data/charsetmapping/charsets	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -326,6 +326,8 @@
     ascii   true
     alias   cp1252			# JDK historical
     alias   cp5348			# Euro IBM CCSID
+    alias   ibm-1252
+    alias   ibm1252
 
 charset windows-1253 MS1253
     package sun.nio.cs
@@ -933,11 +935,16 @@
 
 charset x-IBM942C IBM942C
     package sun.nio.cs.ext
-    type    source
+    type    template
     alias   cp942C               # JDK historical
     alias   ibm942C
     alias   ibm-942C
     alias   942C
+    alias   cp932
+    alias   ibm932
+    alias   ibm-932
+    alias   932
+    alias   x-ibm932
 
 charset x-IBM943 IBM943
     package sun.nio.cs.ext
@@ -952,7 +959,7 @@
 
 charset x-IBM943C IBM943C
     package sun.nio.cs.ext
-    type    source
+    type    template
     alias   cp943C               # JDK historical
     alias   ibm943C
     alias   ibm-943C
@@ -1519,6 +1526,9 @@
     alias   ibm1383
     alias   ibm-1383
     alias   1383
+    alias   ibmeuccn
+    alias   ibm-euccn
+    alias   cpeuccn
 
 charset x-IBM970 IBM970
     package sun.nio.cs.ext
--- a/make/data/charsetmapping/stdcs-aix	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/data/charsetmapping/stdcs-aix	Tue Apr 24 10:20:22 2018 +0100
@@ -1,6 +1,26 @@
 #
 #   generate these charsets into sun.nio.cs
 #
+Big5
+Big5_Solaris
+Big5_HKSCS
 EUC_CN
 EUC_KR
 GBK
+GB18030
+IBM856
+IBM921
+IBM922
+IBM942
+IBM942C
+IBM943
+IBM943C
+IBM950
+IBM970
+IBM1046
+IBM1124
+IBM1383
+ISO_8859_6
+ISO_8859_8
+MS1252
+TIS_620
--- a/make/jdk/src/classes/build/tools/charsetmapping/SPI.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/jdk/src/classes/build/tools/charsetmapping/SPI.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -129,7 +129,7 @@
                      } else if (line.indexOf("_INCLUDE_ALIASES_MAP_") != -1) {
                          Hasher.genClass(out, aliasKeys, aliasValues,
                                          null, "Aliases", "String",
-                                         11, 3, true, false, false);
+                                         12, 3, true, false, false);
                      } else if (line.indexOf("_INCLUDE_CLASSES_MAP_") != -1) {
                          Hasher.genClass(out, clzKeys, clzValues,
                                          null, "Classes", "String",
--- a/make/langtools/tools/propertiesparser/parser/MessageType.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/langtools/tools/propertiesparser/parser/MessageType.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,13 +86,17 @@
         NAME("name", "Name", "com.sun.tools.javac.util"),
         NUMBER("number", "int", null),
         OPTION_NAME("option name", "Option", "com.sun.tools.javac.main"),
+        PROFILE("profile", "Profile", "com.sun.tools.javac.jvm"),
+        SOURCE("source", "Source", "com.sun.tools.javac.code"),
         SOURCE_VERSION("source version", "SourceVersion", "javax.lang.model"),
         STRING("string", "String", null),
         SYMBOL("symbol", "Symbol", "com.sun.tools.javac.code"),
         SYMBOL_KIND("symbol kind", "Kind", "com.sun.tools.javac.code.Kinds"),
         KIND_NAME("kind name", "KindName", "com.sun.tools.javac.code.Kinds"),
+        TARGET("target", "Target", "com.sun.tools.javac.jvm"),
         TOKEN("token", "TokenKind", "com.sun.tools.javac.parser.Tokens"),
         TYPE("type", "Type", "com.sun.tools.javac.code"),
+        URL("url", "URL", "java.net"),
         SET("set", "Set", "java.util"),
         LIST("list", "List", "java.util"),
         OBJECT("object", "Object", null),
--- a/make/launcher/Launcher-jdk.pack.gmk	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/launcher/Launcher-jdk.pack.gmk	Tue Apr 24 10:20:22 2018 +0100
@@ -88,7 +88,6 @@
     CFLAGS_solaris := -KPIC, \
     CFLAGS_macosx := -fPIC, \
     DISABLED_WARNINGS_gcc := unused-result implicit-fallthrough, \
-    DISABLED_WARNINGS_microsoft := 4005, \
     LDFLAGS := $(UNPACKEXE_ZIPOBJS) \
         $(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
         $(call SET_SHARED_LIBRARY_ORIGIN), \
--- a/make/lib/Awt2dLibraries.gmk	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/lib/Awt2dLibraries.gmk	Tue Apr 24 10:20:22 2018 +0100
@@ -224,7 +224,7 @@
         format-nonliteral parentheses, \
     DISABLED_WARNINGS_clang := logical-op-parentheses extern-initializer, \
     DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE, \
-    DISABLED_WARNINGS_microsoft := 4297 4244 4267 4996, \
+    DISABLED_WARNINGS_microsoft := 4297 4244 4267 4291 4302 4311 4996, \
     ASFLAGS := $(LIBAWT_ASFLAGS), \
     LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_macosx := -L$(INSTALL_LIBRARIES_HERE), \
--- a/make/lib/Lib-jdk.pack.gmk	Tue Apr 24 10:17:23 2018 +0100
+++ b/make/lib/Lib-jdk.pack.gmk	Tue Apr 24 10:20:22 2018 +0100
@@ -40,7 +40,6 @@
         $(LIBJAVA_HEADER_FLAGS), \
     CFLAGS_release := -DPRODUCT, \
     DISABLED_WARNINGS_gcc := implicit-fallthrough, \
-    DISABLED_WARNINGS_microsoft := 4005, \
     LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
         $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_windows := -map:$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpack.map -debug, \
--- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -29,6 +29,9 @@
 #include "gc/g1/g1CardTable.hpp"
 #include "gc/g1/g1ThreadLocalData.hpp"
 #include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
 #include "interpreter/interp_masm.hpp"
 #include "runtime/sharedRuntime.hpp"
 
--- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -44,12 +44,6 @@
   }
 }
 
-
-void ModRefBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
-                                             Address dst, Register val, Register tmp1, Register tmp2) {
-  BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
-}
-
 void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                          Address dst, Register val, Register tmp1, Register tmp2) {
   if (type == T_OBJECT || type == T_ARRAY) {
--- a/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shared/modRefBarrierSetAssembler_aarch64.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -40,7 +40,7 @@
                                                 Register start, Register end, Register tmp, RegSet saved_regs) {}
 
   virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
-                            Address dst, Register val, Register tmp1, Register tmp2);
+                            Address dst, Register val, Register tmp1, Register tmp2) = 0;
 
 public:
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -265,22 +265,21 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
+                                           Register result, Register index, Register tmp) {
   assert_different_registers(result, index);
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  lslw(tmp, tmp, LogBytesPerHeapOop);
+  lslw(index, index, LogBytesPerHeapOop);
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
   ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  add(result, result, tmp);
+  add(result, result, index);
   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), /*tmp1*/ noreg, /*tmp_thread*/ noreg);
+  bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, /*tmp_thread*/ noreg);
 }
 
 void InterpreterMacroAssembler::load_resolved_klass_at_offset(
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -122,7 +122,7 @@
   void get_method_counters(Register method, Register mcs, Label& skip);
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp = r5);
 
   // load cpool->resolved_klass_at(index);
   void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -2108,7 +2108,7 @@
 
   bind(not_weak);
   // Resolve (untagged) jobject.
-  bs->load_at(this, IN_ROOT | ON_STRONG_OOP_REF, T_OBJECT,
+  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
                     value, Address(value, 0), tmp, thread);
   verify_oop(value);
   bind(done);
@@ -3642,18 +3642,20 @@
 }
 
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
-  ldr(result, Address(result, 0));
-}
-
-void MacroAssembler::load_mirror(Register dst, Register method) {
+  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
+                    result, Address(result, 0), tmp, rthread);
+}
+
+void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   ldr(dst, Address(rmethod, Method::const_offset()));
   ldr(dst, Address(dst, ConstMethod::constants_offset()));
   ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
   ldr(dst, Address(dst, mirror_offset));
-  resolve_oop_handle(dst);
+  resolve_oop_handle(dst, tmp);
 }
 
 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -803,8 +803,8 @@
   void store_klass(Register dst, Register src);
   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register dst, Register method);
+  void resolve_oop_handle(Register result, Register tmp = r5);
+  void load_mirror(Register dst, Register method, Register tmp = r5);
 
   void load_heap_oop(Register dst, Address src);
 
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -133,9 +133,29 @@
     address addr = MacroAssembler::target_addr_for_insn(instruction_address());
     *(intptr_t*)addr = x;
   } else {
+    // Store x into the instruction stream.
     MacroAssembler::pd_patch_instruction(instruction_address(), (address)x);
     ICache::invalidate_range(instruction_address(), instruction_size);
   }
+
+  // Find and replace the oop/metadata corresponding to this
+  // instruction in oops section.
+  CodeBlob* cb = CodeCache::find_blob(instruction_address());
+  nmethod* nm = cb->as_nmethod_or_null();
+  if (nm != NULL) {
+    RelocIterator iter(nm, instruction_address(), next_instruction_address());
+    while (iter.next()) {
+      if (iter.type() == relocInfo::oop_type) {
+        oop* oop_addr = iter.oop_reloc()->oop_addr();
+        *oop_addr = cast_to_oop(x);
+        break;
+      } else if (iter.type() == relocInfo::metadata_type) {
+        Metadata** metadata_addr = iter.metadata_reloc()->metadata_addr();
+        *metadata_addr = (Metadata*)x;
+        break;
+      }
+    }
+  }
 }
 
 void NativeMovConstReg::print() {
--- a/src/hotspot/cpu/arm/methodHandles_arm.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -35,6 +35,7 @@
 #include "memory/resourceArea.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/frame.inline.hpp"
+#include "utilities/preserveException.hpp"
 
 #define __ _masm->
 
--- a/src/hotspot/cpu/arm/relocInfo_arm.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/arm/relocInfo_arm.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -29,6 +29,7 @@
 #include "nativeInst_arm.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.hpp"
+#include "runtime/orderAccess.inline.hpp"
 #include "runtime/safepoint.hpp"
 
 void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
--- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -56,12 +56,6 @@
   }
 }
 
-void ModRefBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
-                                             Register base, RegisterOrConstant ind_or_offs, Register val,
-                                             Register tmp1, Register tmp2, Register tmp3, bool needs_frame) {
-  BarrierSetAssembler::store_at(masm, decorators, type, base, ind_or_offs, val, tmp1, tmp2, tmp3, needs_frame);
-}
-
 void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                          Register base, RegisterOrConstant ind_or_offs, Register val,
                                          Register tmp1, Register tmp2, Register tmp3, bool needs_frame) {
--- a/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/ppc/gc/shared/modRefBarrierSetAssembler_ppc.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -41,7 +41,7 @@
 
   virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                             Register base, RegisterOrConstant ind_or_offs, Register val,
-                            Register tmp1, Register tmp2, Register tmp3, bool needs_frame);
+                            Register tmp1, Register tmp2, Register tmp3, bool needs_frame) = 0;
 public:
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                   Register src, Register dst, Register count, Register preserve1, Register preserve2);
--- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -24,6 +24,7 @@
  */
 
 #include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
 #include "gc/shared/barrierSetAssembler.hpp"
 #include "interpreter/interp_masm.hpp"
 
--- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -50,11 +50,6 @@
   }
 }
 
-void ModRefBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
-                                             const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
-  BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
-}
-
 void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                          const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
   if (type == T_OBJECT || type == T_ARRAY) {
--- a/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/s390/gc/shared/modRefBarrierSetAssembler_s390.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -39,7 +39,7 @@
   virtual void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
                                                 bool do_return);
   virtual void oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
-                            const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3);
+                            const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3) = 0;
 public:
   virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                   Register src, Register dst, Register count);
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -739,20 +739,19 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
-  assert_different_registers(result, index);
+                                           Register result, Register index, Register tmp) {
+  assert_different_registers(result, index, tmp);
   assert_not_delayed();
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  sll(index, LogBytesPerHeapOop, tmp);
+  sll(index, LogBytesPerHeapOop, index);
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
   ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  add(result, tmp, result);
+  add(result, index, result);
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp);
 }
 
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -183,7 +183,7 @@
   void get_cache_index_at_bcp(Register temp, Register index, int bcp_offset, size_t index_size = sizeof(u2));
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp);
 
   // load cpool->resolved_klass_at(index)
   void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -3392,18 +3392,19 @@
   bind(no_reserved_zone_enabling);
 }
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
-  ld_ptr(result, 0, result);
+  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+                 Address(result, 0), result, tmp);
 }
 
-void MacroAssembler::load_mirror(Register mirror, Register method) {
+void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   ld_ptr(method, in_bytes(Method::const_offset()), mirror);
   ld_ptr(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
   ld_ptr(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
   ld_ptr(mirror, mirror_offset, mirror);
-  resolve_oop_handle(mirror);
+  resolve_oop_handle(mirror, tmp);
 }
 
 void MacroAssembler::load_klass(Register src_oop, Register klass) {
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -968,8 +968,8 @@
   inline void ldbool(const Address& a, Register d);
   inline void movbool( bool boolconst, Register d);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register mirror, Register method);
+  void resolve_oop_handle(Register result, Register tmp);
+  void load_mirror(Register mirror, Register method, Register tmp);
 
   // klass oop manipulations if compressed
   void load_klass(Register src_oop, Register klass);
--- a/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -502,7 +502,7 @@
     __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
 
     // lock the mirror, not the Klass*
-    __ load_mirror(O0, Lmethod);
+    __ load_mirror(O0, Lmethod, Lscratch);
 
 #ifdef ASSERT
     __ tst(O0);
@@ -810,7 +810,7 @@
   __ mov( G5_method, Lmethod);                 // set Lmethod
   // Get mirror and store it in the frame as GC root for this Method*
   Register mirror = LcpoolCache;
-  __ load_mirror(mirror, Lmethod);
+  __ load_mirror(mirror, Lmethod, Lscratch);
   __ st_ptr(mirror, FP, (frame::interpreter_frame_mirror_offset * wordSize) + STACK_BIAS);
   __ get_constant_pool_cache(LcpoolCache);     // set LcpoolCache
   __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
@@ -1280,7 +1280,7 @@
     // get native function entry point(O0 is a good temp until the very end)
     __ delayed()->ld_ptr(Lmethod, in_bytes(Method::native_function_offset()), O0);
     // for static methods insert the mirror argument
-    __ load_mirror(O1, Lmethod);
+    __ load_mirror(O1, Lmethod, G3_scratch);
 #ifdef ASSERT
     if (!PrintSignatureHandlers)  // do not dirty the output with this
     { Label L;
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -326,7 +326,7 @@
   // non-null object (CallSite, etc.)
   assert_different_registers(Otos_i, G3_scratch);
   __ get_cache_index_at_bcp(Otos_i, G3_scratch, 1, index_size);  // load index => G3_scratch
-  __ load_resolved_reference_at_index(Otos_i, G3_scratch);
+  __ load_resolved_reference_at_index(Otos_i, G3_scratch, Lscratch);
   __ tst(Otos_i);
   __ br(Assembler::notEqual, false, Assembler::pt, resolved);
   __ delayed()->set((int)bytecode(), O1);
@@ -2016,7 +2016,7 @@
                                               Register Roffset,
                                               Register Rflags,
                                               bool is_static) {
-  assert_different_registers(Rcache, Rflags, Roffset);
+  assert_different_registers(Rcache, Rflags, Roffset, Lscratch);
 
   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
 
@@ -2026,7 +2026,7 @@
     __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f1_offset(), Robj);
     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     __ ld_ptr( Robj, mirror_offset, Robj);
-    __ resolve_oop_handle(Robj);
+    __ resolve_oop_handle(Robj, Lscratch);
   }
 }
 
@@ -2847,7 +2847,7 @@
     // This must be done before we get the receiver,
     // since the parameter_size includes it.
     assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
-    __ load_resolved_reference_at_index(temp, index);
+    __ load_resolved_reference_at_index(temp, index, /*tmp*/recv);
     __ verify_oop(temp);
     __ push_ptr(temp);  // push appendix (MethodType, CallSite, etc.)
     __ bind(L_no_push);
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -502,20 +502,19 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
+                                           Register result, Register index, Register tmp) {
   assert_different_registers(result, index);
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  shll(tmp, LogBytesPerHeapOop);
+  shll(index, LogBytesPerHeapOop);
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
   movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  addptr(result, tmp);
+  addptr(result, index);
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp);
 }
 
--- a/src/hotspot/cpu/x86/interp_masm_x86.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/x86/interp_masm_x86.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -122,7 +122,7 @@
                               size_t index_size = sizeof(u2));
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp = rscratch2);
 
   // load cpool->resolved_klass_at(index)
   void load_resolved_klass_at_index(Register cpool,  // the constant pool (corrupted on return)
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -6274,19 +6274,22 @@
 }
 
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
-  // OopHandle::resolve is an indirection.
-  movptr(result, Address(result, 0));
-}
-
-void MacroAssembler::load_mirror(Register mirror, Register method) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
+  // Only 64 bit platforms support GCs that require a tmp register
+  // Only IN_HEAP loads require a thread_tmp register
+  // OopHandle::resolve is an indirection like jobject.
+  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+                 result, Address(result, 0), tmp, /*tmp_thread*/noreg);
+}
+
+void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
   // get mirror
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   movptr(mirror, Address(method, Method::const_offset()));
   movptr(mirror, Address(mirror, ConstMethod::constants_offset()));
   movptr(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
   movptr(mirror, Address(mirror, mirror_offset));
-  resolve_oop_handle(mirror);
+  resolve_oop_handle(mirror, tmp);
 }
 
 void MacroAssembler::load_klass(Register dst, Register src) {
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -307,8 +307,8 @@
   void movbool(Address dst, Register src);
   void testbool(Register dst);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register mirror, Register method);
+  void resolve_oop_handle(Register result, Register tmp = rscratch2);
+  void load_mirror(Register mirror, Register method, Register tmp = rscratch2);
 
   // oop manipulations
   void load_klass(Register dst, Register src);
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -374,7 +374,7 @@
 }
 
 inline static bool checkPollingPage(address pc, address fault, address* stub) {
-  if (fault == os::get_polling_page()) {
+  if (os::is_poll_address(fault)) {
     *stub = SharedRuntime::get_poll_stub(pc);
     return true;
   }
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -445,6 +445,8 @@
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_handle_wrong_method_stub", address, SharedRuntime::get_handle_wrong_method_stub());
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_exception_handler_for_return_address", address, SharedRuntime::exception_handler_for_return_address);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_register_finalizer", address, SharedRuntime::register_finalizer);
+    SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notify", address, JVMCIRuntime::object_notify);
+    SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_object_notifyAll", address, JVMCIRuntime::object_notifyAll);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_OSR_migration_end", address, SharedRuntime::OSR_migration_end);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_dynamic_invoke", address, CompilerRuntime::resolve_dynamic_invoke);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_resolve_string_by_symbol", address, CompilerRuntime::resolve_string_by_symbol);
--- a/src/hotspot/share/aot/aotLoader.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/aot/aotLoader.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -183,28 +183,21 @@
     // Shifts are static values which initialized by 0 until java heap initialization.
     // AOT libs are loaded before heap initialized so shift values are not set.
     // It is okay since ObjectAlignmentInBytes flag which defines shifts value is set before AOT libs are loaded.
-    // Set shifts value based on first AOT library config.
+    // AOT sets shift values during heap and metaspace initialization.
+    // Check shifts value to make sure thay did not change.
     if (UseCompressedOops && AOTLib::narrow_oop_shift_initialized()) {
       int oop_shift = Universe::narrow_oop_shift();
-      if (oop_shift == 0) {
-        Universe::set_narrow_oop_shift(AOTLib::narrow_oop_shift());
-      } else {
-        FOR_ALL_AOT_LIBRARIES(lib) {
-          (*lib)->verify_flag(AOTLib::narrow_oop_shift(), oop_shift, "Universe::narrow_oop_shift");
-        }
+      FOR_ALL_AOT_LIBRARIES(lib) {
+        (*lib)->verify_flag((*lib)->config()->_narrowOopShift, oop_shift, "Universe::narrow_oop_shift");
       }
       if (UseCompressedClassPointers) { // It is set only if UseCompressedOops is set
         int klass_shift = Universe::narrow_klass_shift();
-        if (klass_shift == 0) {
-          Universe::set_narrow_klass_shift(AOTLib::narrow_klass_shift());
-        } else {
-          FOR_ALL_AOT_LIBRARIES(lib) {
-            (*lib)->verify_flag(AOTLib::narrow_klass_shift(), klass_shift, "Universe::narrow_klass_shift");
-          }
+        FOR_ALL_AOT_LIBRARIES(lib) {
+          (*lib)->verify_flag((*lib)->config()->_narrowKlassShift, klass_shift, "Universe::narrow_klass_shift");
         }
       }
     }
-    // Create heaps for all the libraries
+    // Create heaps for all valid libraries
     FOR_ALL_AOT_LIBRARIES(lib) {
       if ((*lib)->is_valid()) {
         AOTCodeHeap* heap = new AOTCodeHeap(*lib);
@@ -213,6 +206,9 @@
           add_heap(heap);
           CodeCache::add_heap(heap);
         }
+      } else {
+        // Unload invalid libraries
+        os::dll_unload((*lib)->dl_handle());
       }
     }
   }
@@ -223,20 +219,29 @@
   }
 }
 
+// Set shift value for compressed oops and classes based on first AOT library config.
+// AOTLoader::universe_init(), which is called later, will check the shift value again to make sure nobody change it.
+// This code is not executed during CDS dump because it runs in Interpreter mode and AOT is disabled in this mode.
+
+void AOTLoader::set_narrow_oop_shift() {
+  // This method is called from Universe::initialize_heap().
+  if (UseAOT && libraries_count() > 0 &&
+      UseCompressedOops && AOTLib::narrow_oop_shift_initialized()) {
+    if (Universe::narrow_oop_shift() == 0) {
+      // 0 is valid shift value for small heap but we can safely increase it
+      // at this point when nobody used it yet.
+      Universe::set_narrow_oop_shift(AOTLib::narrow_oop_shift());
+    }
+  }
+}
+
 void AOTLoader::set_narrow_klass_shift() {
-  // This method could be called from Metaspace::set_narrow_klass_base_and_shift().
-  // In case it is not called (during dump CDS, for example) the corresponding code in
-  // AOTLoader::universe_init(), which is called later, will set the shift value.
+  // This method is called from Metaspace::set_narrow_klass_base_and_shift().
   if (UseAOT && libraries_count() > 0 &&
       UseCompressedOops && AOTLib::narrow_oop_shift_initialized() &&
       UseCompressedClassPointers) {
-    int klass_shift = Universe::narrow_klass_shift();
-    if (klass_shift == 0) {
+    if (Universe::narrow_klass_shift() == 0) {
       Universe::set_narrow_klass_shift(AOTLib::narrow_klass_shift());
-    } else {
-      FOR_ALL_AOT_LIBRARIES(lib) {
-        (*lib)->verify_flag(AOTLib::narrow_klass_shift(), klass_shift, "Universe::narrow_klass_shift");
-      }
     }
   }
 }
--- a/src/hotspot/share/aot/aotLoader.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/aot/aotLoader.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -57,6 +57,7 @@
   static void initialize() NOT_AOT({ FLAG_SET_ERGO(bool, UseAOT, false); });
 
   static void universe_init() NOT_AOT_RETURN;
+  static void set_narrow_oop_shift() NOT_AOT_RETURN;
   static void set_narrow_klass_shift() NOT_AOT_RETURN;
   static bool contains(address p) NOT_AOT({ return false; });
   static void load_for_klass(InstanceKlass* ik, Thread* thread) NOT_AOT_RETURN;
--- a/src/hotspot/share/classfile/classLoader.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/classLoader.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -80,13 +80,13 @@
 
 // Entry points in zip.dll for loading zip/jar file entries
 
-typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
-typedef void (JNICALL *ZipClose_t)(jzfile *zip);
-typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
-typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
-typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
-typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
-typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
+typedef void * * (*ZipOpen_t)(const char *name, char **pmsg);
+typedef void (*ZipClose_t)(jzfile *zip);
+typedef jzentry* (*FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
+typedef jboolean (*ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
+typedef jzentry* (*GetNextEntry_t)(jzfile *zip, jint n);
+typedef jboolean (*ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
+typedef jint     (*Crc32_t)(jint crc, const jbyte *buf, jint len);
 
 static ZipOpen_t         ZipOpen            = NULL;
 static ZipClose_t        ZipClose           = NULL;
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -54,6 +54,7 @@
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
+#include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
@@ -64,6 +65,7 @@
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "oops/weakHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
@@ -101,8 +103,25 @@
   }
 }
 
+// JFR and logging support so that the name and klass are available after the
+// class_loader oop is no longer alive, during unloading.
+void ClassLoaderData::initialize_name_and_klass(Handle class_loader) {
+  _class_loader_klass = class_loader->klass();
+  oop class_loader_name = java_lang_ClassLoader::name(class_loader());
+  if (class_loader_name != NULL) {
+    Thread* THREAD = Thread::current();
+    ResourceMark rm(THREAD);
+    const char* class_loader_instance_name =
+      java_lang_String::as_utf8_string(class_loader_name);
+
+    if (class_loader_instance_name != NULL && class_loader_instance_name[0] != '\0') {
+      // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
+      _class_loader_name = SymbolTable::new_symbol(class_loader_instance_name, CATCH);
+    }
+  }
+}
+
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) :
-  _class_loader(h_class_loader()),
   _is_anonymous(is_anonymous),
   // An anonymous class loader data doesn't have anything to keep
   // it from being unloaded during parsing of the anonymous class.
@@ -113,9 +132,14 @@
   _claimed(0), _modified_oops(true), _accumulated_modified_oops(false),
   _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
   _next(NULL),
+  _class_loader_klass(NULL), _class_loader_name(NULL),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
 
+  if (!h_class_loader.is_null()) {
+    _class_loader = _handles.add(h_class_loader());
+  }
+
   if (!is_anonymous) {
     // The holder is initialized later for anonymous classes, and before calling anything
     // that call class_loader().
@@ -268,7 +292,6 @@
     clear_modified_oops();
   }
 
-  f->do_oop(&_class_loader);
   _handles.oops_do(f);
 }
 
@@ -555,7 +578,7 @@
   if (lt.is_enabled()) {
     ResourceMark rm;
     LogStream ls(lt);
-    ls.print("unload ");
+    ls.print("unload");
     print_value_on(&ls);
     ls.cr();
   }
@@ -630,7 +653,7 @@
 // Unloading support
 bool ClassLoaderData::is_alive() const {
   bool alive = keep_alive()         // null class loader and incomplete anonymous klasses.
-      || (_holder.peek() != NULL);  // not cleaned by weak reference processing
+      || (_holder.peek() != NULL);  // and not cleaned by the GC weak handle processing.
 
   return alive;
 }
@@ -886,13 +909,23 @@
 }
 
 const char* ClassLoaderData::loader_name() const {
-  // Handles null class loader
-  return SystemDictionary::loader_name(class_loader());
+  if (is_unloading()) {
+    if (_class_loader_klass == NULL) {
+      return "<bootloader>";
+    } else if (_class_loader_name != NULL) {
+      return _class_loader_name->as_C_string();
+    } else {
+      return _class_loader_klass->name()->as_C_string();
+    }
+  } else {
+    // Handles null class loader
+    return SystemDictionary::loader_name(class_loader());
+  }
 }
 
 
 void ClassLoaderData::print_value_on(outputStream* out) const {
-  if (class_loader() != NULL) {
+  if (!is_unloading() && class_loader() != NULL) {
     out->print("loader data: " INTPTR_FORMAT " for instance ", p2i(this));
     class_loader()->print_value_on(out);  // includes loader_name() and address of class loader instance
   } else {
@@ -907,7 +940,7 @@
 #ifndef PRODUCT
 void ClassLoaderData::print_on(outputStream* out) const {
   out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
-              p2i(this), p2i((void *)class_loader()), loader_name());
+              p2i(this), p2i(_class_loader.ptr_raw()), loader_name());
   if (is_anonymous()) out->print(" anonymous");
   if (claimed()) out->print(" claimed");
   if (is_unloading()) out->print(" unloading");
@@ -961,10 +994,10 @@
 
 // Add a new class loader data node to the list.  Assign the newly created
 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
-ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) {
+ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anonymous) {
   NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
                                      // ClassLoaderData in the graph since the CLD
-                                     // contains unhandled oops
+                                     // contains oops in _handles that must be walked.
 
   ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous);
 
@@ -1001,6 +1034,16 @@
   } while (true);
 }
 
+ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) {
+  ClassLoaderData* loader_data = add_to_graph(loader, is_anonymous);
+  // Initialize name and class after the loader data is added to the CLDG
+  // because adding the Symbol for the name might safepoint.
+  if (loader.not_null()) {
+    loader_data->initialize_name_and_klass(loader);
+  }
+  return loader_data;
+}
+
 void ClassLoaderDataGraph::oops_do(OopClosure* f, bool must_claim) {
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
     cld->oops_do(f, must_claim);
@@ -1236,8 +1279,7 @@
 
 // Move class loader data from main list to the unloaded list for unloading
 // and deallocation later.
-bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure,
-                                        bool clean_previous_versions) {
+bool ClassLoaderDataGraph::do_unloading(bool clean_previous_versions) {
 
   ClassLoaderData* data = _head;
   ClassLoaderData* prev = NULL;
@@ -1295,7 +1337,7 @@
       // Remove entries in the dictionary of live class loader that have
       // initiated loading classes in a dead class loader.
       if (data->dictionary() != NULL) {
-        data->dictionary()->do_unloading(is_alive_closure);
+        data->dictionary()->do_unloading();
       }
       // Walk a ModuleEntry's reads, and a PackageEntry's exports
       // lists to determine if there are modules on those lists that are now
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -28,7 +28,6 @@
 #include "memory/allocation.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/metaspace.hpp"
-#include "memory/metaspaceCounters.hpp"
 #include "oops/oopHandle.hpp"
 #include "oops/weakHandle.hpp"
 #include "runtime/mutex.hpp"
@@ -84,6 +83,7 @@
   static volatile size_t  _num_instance_classes;
   static volatile size_t  _num_array_classes;
 
+  static ClassLoaderData* add_to_graph(Handle class_loader, bool anonymous);
   static ClassLoaderData* add(Handle class_loader, bool anonymous);
   static void post_class_unload_events();
  public:
@@ -114,7 +114,7 @@
   static void packages_unloading_do(void f(PackageEntry*));
   static void loaded_classes_do(KlassClosure* klass_closure);
   static void classes_unloading_do(void f(Klass* const));
-  static bool do_unloading(BoolObjectClosure* is_alive_closure, bool clean_previous_versions);
+  static bool do_unloading(bool clean_previous_versions);
 
   // dictionary do
   // Iterate over all klasses in dictionary, but
@@ -221,7 +221,7 @@
   static ClassLoaderData * _the_null_class_loader_data;
 
   WeakHandle<vm_class_loader_data> _holder; // The oop that determines lifetime of this class loader
-  oop _class_loader;          // The instance of java/lang/ClassLoader associated with
+  OopHandle _class_loader;    // The instance of java/lang/ClassLoader associated with
                               // this ClassLoaderData
 
   ClassLoaderMetaspace * volatile _metaspace;  // Meta-space where meta-data defined by the
@@ -234,7 +234,7 @@
   bool _modified_oops;             // Card Table Equivalent (YC/CMS support)
   bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
 
-  s2 _keep_alive;          // if this CLD is kept alive without a keep_alive_object().
+  s2 _keep_alive;          // if this CLD is kept alive.
                            // Used for anonymous classes and the boot class
                            // loader. _keep_alive does not need to be volatile or
                            // atomic since there is one unique CLD per anonymous class.
@@ -265,6 +265,9 @@
   // Support for walking class loader data objects
   ClassLoaderData* _next; /// Next loader_datas created
 
+  // JFR support
+  Klass*  _class_loader_klass;
+  Symbol* _class_loader_name;
   TRACE_DEFINE_TRACE_ID_FIELD;
 
   void set_next(ClassLoaderData* next) { _next = next; }
@@ -305,6 +308,8 @@
   MetaWord* allocate(size_t size);
 
   Dictionary* create_dictionary();
+
+  void initialize_name_and_klass(Handle class_loader);
  public:
   // GC interface.
   void clear_claimed() { _claimed = 0; }
@@ -340,9 +345,7 @@
 
   // Returns true if this class loader data is for the boot class loader.
   // (Note that the class loader data may be anonymous.)
-  bool is_boot_class_loader_data() const {
-    return class_loader() == NULL;
-  }
+  inline bool is_boot_class_loader_data() const;
 
   bool is_builtin_class_loader_data() const;
   bool is_permanent_class_loader_data() const;
@@ -351,10 +354,7 @@
   // method will allocate a Metaspace if needed.
   ClassLoaderMetaspace* metaspace_non_null();
 
-  oop class_loader() const { return _class_loader; }
-
-  // The object the GC is using to keep this ClassLoaderData alive.
-  oop keep_alive_object() const;
+  inline oop class_loader() const;
 
   // Returns true if this class loader data is for a loader going away.
   bool is_unloading() const     {
@@ -363,7 +363,7 @@
   }
 
   // Used to refcount an anonymous class's CLD in order to
-  // indicate their aliveness without a keep_alive_object().
+  // indicate their aliveness.
   void inc_keep_alive();
   void dec_keep_alive();
 
@@ -407,6 +407,9 @@
   static ClassLoaderData* class_loader_data_or_null(oop loader);
   static ClassLoaderData* anonymous_class_loader_data(Handle loader);
 
+
+  Klass* class_loader_klass() const { return _class_loader_klass; }
+  Symbol* class_loader_name() const { return _class_loader_name; }
   TRACE_DEFINE_TRACE_ID_METHODS;
 };
 
--- a/src/hotspot/share/classfile/classLoaderData.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -28,6 +28,18 @@
 #include "classfile/classLoaderData.hpp"
 #include "classfile/javaClasses.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
+#include "oops/weakHandle.inline.hpp"
+
+inline oop ClassLoaderData::class_loader() const {
+  assert(!_unloading, "This oop is not available to unloading class loader data");
+  assert(_holder.is_null() || _holder.peek() != NULL , "This class loader data holder must be alive");
+  return _class_loader.resolve();
+}
+
+inline bool ClassLoaderData::is_boot_class_loader_data() const {
+    return class_loader() == NULL;
+  }
 
 inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
   if (loader == NULL) {
--- a/src/hotspot/share/classfile/classLoaderStats.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderStats.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/classLoaderStats.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/classfile/dictionary.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/dictionary.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -214,13 +214,13 @@
 
 // During class loading we may have cached a protection domain that has
 // since been unreferenced, so this entry should be cleared.
-void Dictionary::clean_cached_protection_domains(BoolObjectClosure* is_alive, DictionaryEntry* probe) {
+void Dictionary::clean_cached_protection_domains(DictionaryEntry* probe) {
   assert_locked_or_safepoint(SystemDictionary_lock);
 
   ProtectionDomainEntry* current = probe->pd_set();
   ProtectionDomainEntry* prev = NULL;
   while (current != NULL) {
-    if (!is_alive->do_object_b(current->object_no_keepalive())) {
+    if (current->object_no_keepalive() == NULL) {
       LogTarget(Debug, protectiondomain) lt;
       if (lt.is_enabled()) {
         ResourceMark rm;
@@ -228,7 +228,6 @@
         LogStream ls(lt);
         ls.print_cr("PD in set is not alive:");
         ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls);
-        ls.print(" protection domain: "); current->object_no_keepalive()->print_value_on(&ls);
         ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls);
         ls.cr();
       }
@@ -249,7 +248,7 @@
 }
 
 
-void Dictionary::do_unloading(BoolObjectClosure* is_alive) {
+void Dictionary::do_unloading() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   // The NULL class loader doesn't initiate loading classes from other class loaders
@@ -276,7 +275,7 @@
         continue;
       }
       // Clean pd_set
-      clean_cached_protection_domains(is_alive, probe);
+      clean_cached_protection_domains(probe);
       p = probe->next_addr();
     }
   }
--- a/src/hotspot/share/classfile/dictionary.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/dictionary.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -52,7 +52,7 @@
 
   DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);
 
-  void clean_cached_protection_domains(BoolObjectClosure* is_alive, DictionaryEntry* probe);
+  void clean_cached_protection_domains(DictionaryEntry* probe);
 
 protected:
   static size_t entry_size();
@@ -72,20 +72,16 @@
 
   InstanceKlass* find_shared_class(int index, unsigned int hash, Symbol* name);
 
-  // GC support
-  void oops_do(OopClosure* f);
-  void roots_oops_do(OopClosure* strong, OopClosure* weak);
-
   void classes_do(void f(InstanceKlass*));
   void classes_do(void f(InstanceKlass*, TRAPS), TRAPS);
   void all_entries_do(void f(InstanceKlass*, ClassLoaderData*));
   void classes_do(MetaspaceClosure* it);
 
-  void unlink(BoolObjectClosure* is_alive);
+  void unlink();
   void remove_classes_in_error_state();
 
   // Unload classes whose defining loaders are unloaded
-  void do_unloading(BoolObjectClosure* is_alive);
+  void do_unloading();
 
   // Protection domains
   InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
--- a/src/hotspot/share/classfile/loaderConstraints.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/loaderConstraints.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,7 +99,7 @@
       InstanceKlass* klass = probe->klass();
       // Remove klass that is no longer alive
       if (klass != NULL &&
-          klass->class_loader_data()->is_unloading()) {
+          !klass->is_loader_alive()) {
         probe->set_klass(NULL);
         if (lt.is_enabled()) {
           ResourceMark rm;
@@ -116,31 +116,31 @@
       int n = 0;
       while (n < probe->num_loaders()) {
         if (probe->loader_data(n)->is_unloading()) {
-            if (lt.is_enabled()) {
-              ResourceMark rm;
-              lt.print("purging loader %s from constraint for name %s",
-                            probe->loader_data(n)->loader_name(),
-                            probe->name()->as_C_string()
-                            );
-            }
+          if (lt.is_enabled()) {
+            ResourceMark rm;
+            lt.print("purging loader %s from constraint for name %s",
+                     probe->loader_data(n)->loader_name(),
+                     probe->name()->as_C_string()
+                     );
+          }
 
-            // Compact array
-            int num = probe->num_loaders() - 1;
-            probe->set_num_loaders(num);
+          // Compact array
+          int num = probe->num_loaders() - 1;
+          probe->set_num_loaders(num);
           probe->set_loader_data(n, probe->loader_data(num));
           probe->set_loader_data(num, NULL);
 
-            if (lt.is_enabled()) {
-              ResourceMark rm;
-              lt.print("new loader list:");
-              for (int i = 0; i < probe->num_loaders(); i++) {
-                lt.print("    [%d]: %s", i,
-                              probe->loader_data(i)->loader_name());
-              }
+          if (lt.is_enabled()) {
+            ResourceMark rm;
+            lt.print("new loader list:");
+            for (int i = 0; i < probe->num_loaders(); i++) {
+              lt.print("    [%d]: %s", i,
+                            probe->loader_data(i)->loader_name());
             }
+          }
 
-            continue;  // current element replaced, so restart without
-                       // incrementing n
+          continue;  // current element replaced, so restart without
+                     // incrementing n
           }
         n++;
       }
@@ -159,9 +159,7 @@
       } else {
 #ifdef ASSERT
         if (probe->klass() != NULL) {
-          ClassLoaderData* loader_data =
-            probe->klass()->class_loader_data();
-          assert(!loader_data->is_unloading(), "klass should be live");
+          assert(probe->klass()->is_loader_alive(), "klass should be live");
         }
 #endif
         // Go to next entry
--- a/src/hotspot/share/classfile/moduleEntry.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/moduleEntry.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,11 +24,12 @@
 
 #include "precompiled.hpp"
 #include "jni.h"
-#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/safepoint.hpp"
@@ -40,6 +41,8 @@
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
+oop ModuleEntry::module() const { return _module.resolve(); }
+
 void ModuleEntry::set_location(Symbol* location) {
   if (_location != NULL) {
     // _location symbol's refcounts are managed by ModuleEntry,
--- a/src/hotspot/share/classfile/moduleEntry.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/moduleEntry.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -90,7 +90,7 @@
   Symbol*          name() const                        { return literal(); }
   void             set_name(Symbol* n)                 { set_literal(n); }
 
-  oop              module() const                      { return _module.resolve(); }
+  oop              module() const;
   OopHandle        module_handle() const               { return _module; }
   void             set_module(OopHandle j)             { _module = j; }
 
--- a/src/hotspot/share/classfile/placeholders.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/placeholders.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/placeholders.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "oops/oop.inline.hpp"
--- a/src/hotspot/share/classfile/protectionDomainCache.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/protectionDomainCache.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -30,6 +30,7 @@
 #include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/weakHandle.inline.hpp"
 #include "utilities/hashtable.inline.hpp"
 
 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) {
@@ -42,26 +43,26 @@
 }
 
 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)
-  : Hashtable<oop, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
+  : Hashtable<ClassLoaderWeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
 {
 }
 
-void ProtectionDomainCacheTable::unlink(BoolObjectClosure* is_alive) {
+void ProtectionDomainCacheTable::unlink() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be");
   for (int i = 0; i < table_size(); ++i) {
     ProtectionDomainCacheEntry** p = bucket_addr(i);
     ProtectionDomainCacheEntry* entry = bucket(i);
     while (entry != NULL) {
-      if (is_alive->do_object_b(entry->object_no_keepalive())) {
+      oop pd = entry->object_no_keepalive();
+      if (pd != NULL) {
         p = entry->next_addr();
       } else {
         LogTarget(Debug, protectiondomain) lt;
         if (lt.is_enabled()) {
           LogStream ls(lt);
-          ls.print("protection domain unlinked: ");
-          entry->object_no_keepalive()->print_value_on(&ls);
-          ls.cr();
+          ls.print_cr("protection domain unlinked at %d", i);
         }
+        entry->literal().release();
         *p = entry->next();
         free_entry(entry);
       }
@@ -70,16 +71,6 @@
   }
 }
 
-void ProtectionDomainCacheTable::oops_do(OopClosure* f) {
-  for (int index = 0; index < table_size(); index++) {
-    for (ProtectionDomainCacheEntry* probe = bucket(index);
-                                     probe != NULL;
-                                     probe = probe->next()) {
-      probe->oops_do(f);
-    }
-  }
-}
-
 void ProtectionDomainCacheTable::print_on(outputStream* st) const {
   st->print_cr("Protection domain cache table (table_size=%d, classes=%d)",
                table_size(), number_of_entries());
@@ -97,7 +88,7 @@
 }
 
 oop ProtectionDomainCacheEntry::object() {
-  return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(literal_addr());
+  return literal().resolve();
 }
 
 oop ProtectionDomainEntry::object() {
@@ -108,7 +99,7 @@
 // keeping it alive. This is okay to do in the VM thread state if it is not
 // leaked out to become strongly reachable.
 oop ProtectionDomainCacheEntry::object_no_keepalive() {
-  return RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(literal_addr());
+  return literal().peek();
 }
 
 oop ProtectionDomainEntry::object_no_keepalive() {
@@ -116,7 +107,7 @@
 }
 
 void ProtectionDomainCacheEntry::verify() {
-  guarantee(oopDesc::is_oop(object_no_keepalive()), "must be an oop");
+  guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop");
 }
 
 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) {
@@ -127,6 +118,8 @@
   if (entry == NULL) {
     entry = add_entry(index, hash, protection_domain);
   }
+  // keep entry alive
+  (void)entry->object();
   return entry;
 }
 
@@ -145,7 +138,8 @@
   assert(index == index_for(protection_domain), "incorrect index?");
   assert(find_entry(index, protection_domain) == NULL, "no double entry");
 
-  ProtectionDomainCacheEntry* p = new_entry(hash, protection_domain);
-  Hashtable<oop, mtClass>::add_entry(index, p);
+  ClassLoaderWeakHandle w = ClassLoaderWeakHandle::create(protection_domain);
+  ProtectionDomainCacheEntry* p = new_entry(hash, w);
+  Hashtable<ClassLoaderWeakHandle, mtClass>::add_entry(index, p);
   return p;
 }
--- a/src/hotspot/share/classfile/protectionDomainCache.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/protectionDomainCache.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -26,6 +26,7 @@
 #define SHARE_VM_CLASSFILE_PROTECTIONDOMAINCACHE_HPP
 
 #include "oops/oop.hpp"
+#include "oops/weakHandle.hpp"
 #include "memory/iterator.hpp"
 #include "utilities/hashtable.hpp"
 
@@ -34,22 +35,18 @@
 // to dictionary.hpp pd_set for more information about how protection domain entries
 // are used.
 // This table is walked during GC, rather than the class loader data graph dictionaries.
-class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
+class ProtectionDomainCacheEntry : public HashtableEntry<ClassLoaderWeakHandle, mtClass> {
   friend class VMStructs;
  public:
   oop object();
   oop object_no_keepalive();
 
   ProtectionDomainCacheEntry* next() {
-    return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next();
+    return (ProtectionDomainCacheEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next();
   }
 
   ProtectionDomainCacheEntry** next_addr() {
-    return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr();
-  }
-
-  void oops_do(OopClosure* f) {
-    f->do_oop(literal_addr());
+    return (ProtectionDomainCacheEntry**)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next_addr();
   }
 
   void verify();
@@ -64,20 +61,21 @@
 // we only need to iterate over this set.
 // The amount of different protection domains used is typically magnitudes smaller
 // than the number of system dictionary entries (loaded classes).
-class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> {
+class ProtectionDomainCacheTable : public Hashtable<ClassLoaderWeakHandle, mtClass> {
   friend class VMStructs;
 private:
   ProtectionDomainCacheEntry* bucket(int i) const {
-    return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i);
+    return (ProtectionDomainCacheEntry*) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket(i);
   }
 
   // The following method is not MT-safe and must be done under lock.
   ProtectionDomainCacheEntry** bucket_addr(int i) {
-    return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
+    return (ProtectionDomainCacheEntry**) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket_addr(i);
   }
 
-  ProtectionDomainCacheEntry* new_entry(unsigned int hash, Handle protection_domain) {
-    ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain());
+  ProtectionDomainCacheEntry* new_entry(unsigned int hash, ClassLoaderWeakHandle protection_domain) {
+    ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*)
+      Hashtable<ClassLoaderWeakHandle, mtClass>::new_entry(hash, protection_domain);
     return entry;
   }
 
@@ -91,10 +89,7 @@
   ProtectionDomainCacheTable(int table_size);
   ProtectionDomainCacheEntry* get(Handle protection_domain);
 
-  void unlink(BoolObjectClosure* cl);
-
-  // GC support
-  void oops_do(OopClosure* f);
+  void unlink();
 
   void print_on(outputStream* st) const;
   void verify();
--- a/src/hotspot/share/classfile/resolutionErrors.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/resolutionErrors.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -125,9 +125,8 @@
       assert(entry->pool() != (ConstantPool*)NULL, "resolution error table is corrupt");
       ConstantPool* pool = entry->pool();
       assert(pool->pool_holder() != NULL, "Constant pool without a class?");
-      ClassLoaderData* loader_data =
-              pool->pool_holder()->class_loader_data();
-      if (!loader_data->is_unloading()) {
+
+      if (pool->pool_holder()->is_loader_alive()) {
         p = entry->next_addr();
       } else {
         *p = entry->next();
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1831,24 +1831,6 @@
 }
 
 
-#ifdef ASSERT
-class VerifySDReachableAndLiveClosure : public OopClosure {
-private:
-  BoolObjectClosure* _is_alive;
-
-  template <class T> void do_oop_work(T* p) {
-    oop obj = RawAccess<>::oop_load(p);
-    guarantee(_is_alive->do_object_b(obj), "Oop in protection domain cache table must be live");
-  }
-
-public:
-  VerifySDReachableAndLiveClosure(BoolObjectClosure* is_alive) : OopClosure(), _is_alive(is_alive) { }
-
-  virtual void do_oop(oop* p)       { do_oop_work(p); }
-  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-};
-#endif
-
 // Assumes classes in the SystemDictionary are only unloaded at a safepoint
 // Note: anonymous classes are not in the SD.
 bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive,
@@ -1865,8 +1847,7 @@
     GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer);
 
     // First, mark for unload all ClassLoaderData referencing a dead class loader.
-    unloading_occurred = ClassLoaderDataGraph::do_unloading(is_alive,
-                                                            do_cleaning);
+    unloading_occurred = ClassLoaderDataGraph::do_unloading(do_cleaning);
   }
 
   if (unloading_occurred) {
@@ -1880,17 +1861,12 @@
     // Oops referenced by the protection domain cache table may get unreachable independently
     // of the class loader (eg. cached protection domain oops). So we need to
     // explicitly unlink them here.
-    _pd_cache_table->unlink(is_alive);
-
-#ifdef ASSERT
-    VerifySDReachableAndLiveClosure cl(is_alive);
-    _pd_cache_table->oops_do(&cl);
-#endif
+    _pd_cache_table->unlink();
   }
 
   if (do_cleaning) {
     GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
-    ResolvedMethodTable::unlink(is_alive);
+    ResolvedMethodTable::unlink();
   }
 
   return unloading_occurred;
@@ -1906,21 +1882,15 @@
   if (strong == weak || !ClassUnloading) {
     // Only the protection domain oops contain references into the heap. Iterate
     // over all of them.
-    _pd_cache_table->oops_do(strong);
     vm_weak_oop_storage()->oops_do(strong);
   } else {
    if (weak != NULL) {
-     _pd_cache_table->oops_do(weak);
      vm_weak_oop_storage()->oops_do(weak);
    }
   }
 
   // Visit extra methods
   invoke_method_table()->oops_do(strong);
-
-  if (weak != NULL) {
-    ResolvedMethodTable::oops_do(weak);
-  }
 }
 
 void SystemDictionary::oops_do(OopClosure* f) {
@@ -1929,15 +1899,9 @@
   f->do_oop(&_system_loader_lock_obj);
   CDS_ONLY(SystemDictionaryShared::oops_do(f);)
 
-  // Only the protection domain oops contain references into the heap. Iterate
-  // over all of them.
-  _pd_cache_table->oops_do(f);
-
   // Visit extra methods
   invoke_method_table()->oops_do(f);
 
-  ResolvedMethodTable::oops_do(f);
-
   vm_weak_oop_storage()->oops_do(f);
 }
 
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -357,6 +357,14 @@
   return pd;
 }
 
+bool SystemDictionaryShared::is_sharing_possible(ClassLoaderData* loader_data) {
+  oop class_loader = loader_data->class_loader();
+  return (class_loader == NULL ||
+          (UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader) ||
+                         SystemDictionary::is_platform_class_loader(class_loader)))
+          );
+}
+
 // Currently AppCDS only archives classes from the run-time image, the
 // -Xbootclasspath/a path, the class path, and the module path.
 //
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -300,13 +300,7 @@
   }
 
   // Check if sharing is supported for the class loader.
-  static bool is_sharing_possible(ClassLoaderData* loader_data) {
-    oop class_loader = loader_data->class_loader();
-    return (class_loader == NULL ||
-            (UseAppCDS && (SystemDictionary::is_system_class_loader(class_loader) ||
-                           SystemDictionary::is_platform_class_loader(class_loader)))
-            );
-  }
+  static bool is_sharing_possible(ClassLoaderData* loader_data);
   static bool is_shared_class_visible_for_classloader(InstanceKlass* ik,
                                                       Handle class_loader,
                                                       const char* pkg_string,
--- a/src/hotspot/share/code/codeHeapState.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/codeHeapState.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -613,16 +613,22 @@
       //---<  some sanity checks  >---
       // Do not assert here, just check, print error message and return.
       // This is a diagnostic function. It is not supposed to tear down the VM.
-      if ((char*)h <  low_bound ) {
+      if ((char*)h <  low_bound) {
         insane = true; ast->print_cr("Sanity check: HeapBlock @%p below low bound (%p)", (char*)h, low_bound);
       }
-      if (ix_end   >= granules  ) {
+      if ((char*)h >  (low_bound + res_size)) {
+        insane = true; ast->print_cr("Sanity check: HeapBlock @%p outside reserved range (%p)", (char*)h, low_bound + res_size);
+      }
+      if ((char*)h >  (low_bound + size)) {
+        insane = true; ast->print_cr("Sanity check: HeapBlock @%p outside used range (%p)", (char*)h, low_bound + size);
+      }
+      if (ix_end   >= granules) {
         insane = true; ast->print_cr("Sanity check: end index (%d) out of bounds (" SIZE_FORMAT ")", ix_end, granules);
       }
       if (size     != heap->capacity()) {
         insane = true; ast->print_cr("Sanity check: code heap capacity has changed (" SIZE_FORMAT "K to " SIZE_FORMAT "K)", size/(size_t)K, heap->capacity()/(size_t)K);
       }
-      if (ix_beg   >  ix_end    ) {
+      if (ix_beg   >  ix_end) {
         insane = true; ast->print_cr("Sanity check: end index (%d) lower than begin index (%d)", ix_end, ix_beg);
       }
       if (insane) {
@@ -988,6 +994,11 @@
       ast->print_cr("  deadSpace      = " SIZE_FORMAT_W(8) "k, nBlocks_dead     = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", deadSpace/(size_t)K,     nBlocks_dead,     (100.0*deadSpace)/size,     (100.0*deadSpace)/res_size);
       ast->print_cr("  stubSpace      = " SIZE_FORMAT_W(8) "k, nBlocks_stub     = %6d, %10.3f%% of capacity, %10.3f%% of max_capacity", stubSpace/(size_t)K,     nBlocks_stub,     (100.0*stubSpace)/size,     (100.0*stubSpace)/res_size);
       ast->print_cr("ZombieBlocks     = %8d. These are HeapBlocks which could not be identified as CodeBlobs.", nBlocks_zomb);
+      ast->cr();
+      ast->print_cr("Segment start          = " INTPTR_FORMAT ", used space      = " SIZE_FORMAT_W(8)"k", p2i(low_bound), size/K);
+      ast->print_cr("Segment end (used)     = " INTPTR_FORMAT ", remaining space = " SIZE_FORMAT_W(8)"k", p2i(low_bound) + size, (res_size - size)/K);
+      ast->print_cr("Segment end (reserved) = " INTPTR_FORMAT ", reserved space  = " SIZE_FORMAT_W(8)"k", p2i(low_bound) + res_size, res_size/K);
+      ast->cr();
       ast->print_cr("latest allocated compilation id = %d", latest_compilation_id);
       ast->print_cr("highest observed compilation id = %d", highest_compilation_id);
       ast->print_cr("Building TopSizeList iterations = %ld", total_iterations);
@@ -1218,14 +1229,14 @@
           blob_name = this_blob->name();
           nm        = this_blob->as_nmethod_or_null();
           //---<  blob address  >---
-          ast->print("%p", this_blob);
+          ast->print(INTPTR_FORMAT, p2i(this_blob));
           ast->fill_to(19);
           //---<  blob offset from CodeHeap begin  >---
           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
           ast->fill_to(33);
         } else {
           //---<  block address  >---
-          ast->print("%p", TopSizeArray[i].start);
+          ast->print(INTPTR_FORMAT, p2i(TopSizeArray[i].start));
           ast->fill_to(19);
           //---<  block offset from CodeHeap begin  >---
           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)TopSizeArray[i].start-low_bound));
@@ -1404,7 +1415,7 @@
 
     unsigned int ix = 0;
     for (ix = 0; ix < alloc_freeBlocks-1; ix++) {
-      ast->print("%p: Len[%4d] = " HEX32_FORMAT ",", FreeArray[ix].start, ix, FreeArray[ix].len);
+      ast->print(INTPTR_FORMAT ": Len[%4d] = " HEX32_FORMAT ",", p2i(FreeArray[ix].start), ix, FreeArray[ix].len);
       ast->fill_to(38);
       ast->print("Gap[%4d..%4d]: " HEX32_FORMAT " bytes,", ix, ix+1, FreeArray[ix].gap);
       ast->fill_to(71);
@@ -1414,7 +1425,7 @@
       }
       STRINGSTREAM_FLUSH_LOCKED("\n")
     }
-    ast->print_cr("%p: Len[%4d] = " HEX32_FORMAT, FreeArray[ix].start, ix, FreeArray[ix].len);
+    ast->print_cr(INTPTR_FORMAT ": Len[%4d] = " HEX32_FORMAT, p2i(FreeArray[ix].start), ix, FreeArray[ix].len);
     STRINGSTREAM_FLUSH_LOCKED("\n\n")
   }
 
@@ -2057,7 +2068,7 @@
   CodeBlob*    last_blob          = NULL;
   bool         name_in_addr_range = true;
 
-  //---<  print at least 128K per block  >---
+  //---<  print at least 128K per block (i.e. between headers)  >---
   if (granules_per_line*granule_size < 128*K) {
     granules_per_line = (unsigned int)((128*K)/granule_size);
   }
@@ -2067,7 +2078,7 @@
                 "  Due to the living nature of the code heap and because the CodeCache_lock\n"
                 "  is not continuously held, the displayed name might be wrong or no name\n"
                 "  might be found at all. The likelihood for that to happen increases\n"
-                "  over time passed between analysis and print step.\n");
+                "  over time passed between aggregtion and print steps.\n");
   STRINGSTREAM_FLUSH_LOCKED("")
 
   for (unsigned int ix = 0; ix < alloc_granules; ix++) {
@@ -2078,9 +2089,10 @@
       }
       name_in_addr_range = false;
 
+      size_t end_ix = (ix+granules_per_line <= alloc_granules) ? ix+granules_per_line : alloc_granules;
       ast->cr();
       ast->print_cr("--------------------------------------------------------------------");
-      ast->print_cr("Address range [%p,%p), " SIZE_FORMAT "k", low_bound+ix*granule_size, low_bound+(ix+granules_per_line)*granule_size, granules_per_line*granule_size/(size_t)K);
+      ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), " SIZE_FORMAT "k", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K);
       ast->print_cr("--------------------------------------------------------------------");
       STRINGSTREAM_FLUSH_LOCKED("")
     }
@@ -2091,10 +2103,30 @@
     for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
       // heap->find_start() is safe. Only working with _segmap. Returns NULL or void*. Returned CodeBlob may be uninitialized.
       CodeBlob* this_blob = (CodeBlob *)(heap->find_start(low_bound+ix*granule_size+is));
-      bool blob_initialized = (this_blob != NULL) &&
-                              ((char*)this_blob + this_blob->header_size() == (char*)(this_blob->relocation_begin())) &&
-                              ((char*)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (char*)(this_blob->content_begin()));
-      if (blob_initialized && (this_blob != last_blob)) {
+      bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
+                              ((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
+                              ((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
+                              is_readable_pointer((address)(this_blob->relocation_begin())) &&
+                              is_readable_pointer(this_blob->content_begin());
+      // blob could have been flushed, freed, and merged.
+      // this_blob < last_blob is an indicator for that.
+      if (blob_initialized && (this_blob > last_blob)) {
+        last_blob          = this_blob;
+
+        //---<  get type and name  >---
+        blobType       cbType = noType;
+        if (segment_granules) {
+          cbType = (blobType)StatArray[ix].type;
+        } else {
+          cbType = get_cbType(this_blob);
+        }
+        // this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
+        const char* blob_name = this_blob->name();
+        if ((blob_name == NULL) || !is_readable_pointer(blob_name)) {
+          blob_name = "<unavailable>";
+        }
+
+        //---<  print table header for new print range  >---
         if (!name_in_addr_range) {
           name_in_addr_range = true;
           ast->fill_to(51);
@@ -2102,32 +2134,26 @@
           ast->fill_to(61);
           ast->print_cr("%6s", "method");
           ast->print_cr("%18s %13s %17s %9s  %5s %18s  %s", "Addr(module)      ", "offset", "size", " type lvl", " temp", "blobType          ", "Name");
+          STRINGSTREAM_FLUSH_LOCKED("")
         }
 
-        //---<  Print blobTypeName as recorded during analysis  >---
-        ast->print("%p", this_blob);
+        //---<  print line prefix (address and offset from CodeHeap start)  >---
+        ast->print(INTPTR_FORMAT, p2i(this_blob));
         ast->fill_to(19);
         ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
         ast->fill_to(33);
 
-        //---<  print size, name, and signature (for nMethods)  >---
-        // this_blob->name() could return NULL if no name is given to CTOR. Inlined, maybe not visible on stack
-        const char* blob_name = this_blob->name();
-        if (blob_name == 0) {
-          blob_name = "<unavailable>";
-        }
-        // this_blob->as_nmethod_or_null() is safe. Inlined, maybe not visible on stack.
-        nmethod*           nm = this_blob->as_nmethod_or_null();
-        blobType       cbType = noType;
-        if (segment_granules) {
-          cbType = (blobType)StatArray[ix].type;
-        } else {
-          cbType = get_cbType(this_blob);
-        }
-        if ((nm != NULL) && (nm->method() != NULL)) {
+        // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
+        nmethod*    nm     = this_blob->as_nmethod_or_null();
+        Method*     method = (nm == NULL) ? NULL : nm->method();  // may be uninitialized, i.e. != NULL, but invalid
+        if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) &&
+            is_readable_pointer(method) && is_readable_pointer(method->constants())) {
           ResourceMark rm;
+          //---<  collect all data to locals as quickly as possible  >---
+          unsigned int total_size = nm->total_size();
+          int          hotness    = nm->hotness_counter();
+          bool         get_name   = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
           //---<  nMethod size in hex  >---
-          unsigned int total_size = nm->total_size();
           ast->print(PTR32_FORMAT, total_size);
           ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
           //---<  compiler information  >---
@@ -2135,21 +2161,27 @@
           ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level);
           //---<  method temperature  >---
           ast->fill_to(62);
-          ast->print("%5d", nm->hotness_counter());
+          ast->print("%5d", hotness);
           //---<  name and signature  >---
           ast->fill_to(62+6);
           ast->print("%s", blobTypeName[cbType]);
           ast->fill_to(82+6);
-          if (nm->is_in_use()) {
-            blob_name = nm->method()->name_and_sig_as_C_string();
-          }
-          if (nm->is_not_entrant()) {
-            blob_name = nm->method()->name_and_sig_as_C_string();
-          }
-          if (nm->is_zombie()) {
+          if (cbType == nMethod_dead) {
             ast->print("%14s", " zombie method");
           }
-          ast->print("%s", blob_name);
+
+          if (get_name) {
+            Symbol* methName  = method->name();
+            const char*   methNameS = (methName == NULL) ? NULL : methName->as_C_string();
+            methNameS = (methNameS == NULL) ? "<method name unavailable>" : methNameS;
+            Symbol* methSig   = method->signature();
+            const char*   methSigS  = (methSig  == NULL) ? NULL : methSig->as_C_string();
+            methSigS  = (methSigS  == NULL) ? "<method signature unavailable>" : methSigS;
+            ast->print("%s", methNameS);
+            ast->print("%s", methSigS);
+          } else {
+            ast->print("%s", blob_name);
+          }
         } else {
           ast->fill_to(62+6);
           ast->print("%s", blobTypeName[cbType]);
@@ -2157,12 +2189,12 @@
           ast->print("%s", blob_name);
         }
         STRINGSTREAM_FLUSH_LOCKED("\n")
+      } else if (!blob_initialized && (this_blob != last_blob) && (this_blob != NULL)) {
         last_blob          = this_blob;
-      } else if (!blob_initialized && (this_blob != NULL)) {
-        last_blob          = this_blob;
+        STRINGSTREAM_FLUSH_LOCKED("\n")
       }
     }
-    }
+    } // nBlobs > 0
   }
   STRINGSTREAM_FLUSH_LOCKED("\n\n")
 }
@@ -2287,7 +2319,7 @@
     ast->cr();
     assert(out == ast, "must use the same stream!");
 
-    ast->print("%p", low_bound + ix*granule_size);
+    ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
     ast->fill_to(19);
     ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
   }
@@ -2307,14 +2339,14 @@
       ast->reset();
     }
 
-    ast->print("%p", low_bound + ix*granule_size);
+    ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
     ast->fill_to(19);
     ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
   }
 }
 
 CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
-  if (cb != NULL ) {
+  if ((cb != NULL) && is_readable_pointer(cb)) {
     if (cb->is_runtime_stub())                return runtimeStub;
     if (cb->is_deoptimization_stub())         return deoptimizationStub;
     if (cb->is_uncommon_trap_stub())          return uncommonTrapStub;
@@ -2324,15 +2356,29 @@
     if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
     if (cb->is_buffer_blob())                 return bufferBlob;
 
-    if (cb->is_nmethod() ) {
-      if (((nmethod*)cb)->is_in_use())        return nMethod_inuse;
-      if (((nmethod*)cb)->is_alive() && !(((nmethod*)cb)->is_not_entrant()))   return nMethod_notused;
-      if (((nmethod*)cb)->is_alive())         return nMethod_alive;
-      if (((nmethod*)cb)->is_unloaded())      return nMethod_unloaded;
-      if (((nmethod*)cb)->is_zombie())        return nMethod_dead;
-      tty->print_cr("unhandled nmethod state");
+    nmethod*  nm = cb->as_nmethod_or_null();
+    if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
+      if (nm->is_zombie())        return nMethod_dead;
+      if (nm->is_unloaded())      return nMethod_unloaded;
+      if (nm->is_alive() && !(nm->is_not_entrant()))   return nMethod_notused;
+      if (nm->is_alive())         return nMethod_alive;
+      if (nm->is_in_use())        return nMethod_inuse;
       return nMethod_dead;
     }
   }
   return noType;
 }
+
+// Check if pointer can be read from (4-byte read access).
+// Helps to prove validity of a not-NULL pointer.
+// Returns true in very early stages of VM life when stub is not yet generated.
+#define SAFEFETCH_DEFAULT true
+bool CodeHeapState::is_readable_pointer(const void* p) {
+  if (!CanUseSafeFetch32()) {
+    return SAFEFETCH_DEFAULT;
+  }
+  int* const aligned = (int*) align_down((intptr_t)p, 4);
+  int cafebabe = 0xcafebabe;  // tester value 1
+  int deadbeef = 0xdeadbeef;  // tester value 2
+  return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
+}
--- a/src/hotspot/share/code/codeHeapState.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/codeHeapState.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -93,6 +93,7 @@
   static void print_line_delim(outputStream* out, bufferedStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
   static void print_line_delim(outputStream* out, outputStream *sst, char* low_bound, unsigned int ix, unsigned int gpl);
   static blobType get_cbType(CodeBlob* cb);
+  static bool is_readable_pointer(const void* p);
 
  public:
   static void discard(outputStream* out, CodeHeap* heap);
--- a/src/hotspot/share/code/compiledMethod.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/compiledMethod.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -99,7 +99,7 @@
   release_set_exception_cache(new_entry);
 }
 
-void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) {
+void CompiledMethod::clean_exception_cache() {
   ExceptionCache* prev = NULL;
   ExceptionCache* curr = exception_cache();
 
@@ -107,7 +107,7 @@
     ExceptionCache* next = curr->next();
 
     Klass* ex_klass = curr->exception_type();
-    if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
+    if (ex_klass != NULL && !ex_klass->is_loader_alive()) {
       if (prev == NULL) {
         set_exception_cache(next);
       } else {
@@ -369,56 +369,42 @@
 }
 
 #ifdef ASSERT
-
-class CheckClass : AllStatic {
-  static BoolObjectClosure* _is_alive;
-
-  // Check class_loader is alive for this bit of metadata.
-  static void check_class(Metadata* md) {
-    Klass* klass = NULL;
-    if (md->is_klass()) {
-      klass = ((Klass*)md);
-    } else if (md->is_method()) {
-      klass = ((Method*)md)->method_holder();
-    } else if (md->is_methodData()) {
-      klass = ((MethodData*)md)->method()->method_holder();
-    } else {
-      md->print();
-      ShouldNotReachHere();
-    }
-    assert(klass->is_loader_alive(_is_alive), "must be alive");
-  }
- public:
-  static void do_check_class(BoolObjectClosure* is_alive, CompiledMethod* nm) {
-    assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint");
-    _is_alive = is_alive;
-    nm->metadata_do(check_class);
-  }
-};
-
-// This is called during a safepoint so can use static data
-BoolObjectClosure* CheckClass::_is_alive = NULL;
+// Check class_loader is alive for this bit of metadata.
+static void check_class(Metadata* md) {
+   Klass* klass = NULL;
+   if (md->is_klass()) {
+     klass = ((Klass*)md);
+   } else if (md->is_method()) {
+     klass = ((Method*)md)->method_holder();
+   } else if (md->is_methodData()) {
+     klass = ((MethodData*)md)->method()->method_holder();
+   } else {
+     md->print();
+     ShouldNotReachHere();
+   }
+   assert(klass->is_loader_alive(), "must be alive");
+}
 #endif // ASSERT
 
 
-void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) {
+void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) {
   if (ic->is_icholder_call()) {
     // The only exception is compiledICHolder oops which may
     // yet be marked below. (We check this further below).
     CompiledICHolder* cichk_oop = ic->cached_icholder();
 
-    if (cichk_oop->is_loader_alive(is_alive)) {
+    if (cichk_oop->is_loader_alive()) {
       return;
     }
   } else {
     Metadata* ic_oop = ic->cached_metadata();
     if (ic_oop != NULL) {
       if (ic_oop->is_klass()) {
-        if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
+        if (((Klass*)ic_oop)->is_loader_alive()) {
           return;
         }
       } else if (ic_oop->is_method()) {
-        if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
+        if (((Method*)ic_oop)->method_holder()->is_loader_alive()) {
           return;
         }
       } else {
@@ -453,7 +439,7 @@
 // all strong references alive.  Any weak references should have been
 // cleared as well.  Visit all the metadata and ensure that it's
 // really alive.
-void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) {
+void CompiledMethod::verify_metadata_loaders(address low_boundary) {
 #ifdef ASSERT
     RelocIterator iter(this, low_boundary);
     while (iter.next()) {
@@ -483,7 +469,7 @@
     }
   }
   // Check that the metadata embedded in the nmethod is alive
-  CheckClass::do_check_class(is_alive, this);
+  metadata_do(check_class);
 #endif
 }
 
@@ -518,7 +504,7 @@
   }
 
   // Exception cache
-  clean_exception_cache(is_alive);
+  clean_exception_cache();
 
   // If class unloading occurred we first iterate over all inline caches and
   // clear ICs where the cached oop is referring to an unloaded klass or method.
@@ -529,7 +515,7 @@
     while(iter.next()) {
       if (iter.type() == relocInfo::virtual_call_type) {
         CompiledIC *ic = CompiledIC_at(&iter);
-        clean_ic_if_metadata_is_dead(ic, is_alive);
+        clean_ic_if_metadata_is_dead(ic);
       }
     }
   }
@@ -545,7 +531,7 @@
 #endif
 
   // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
+  verify_metadata_loaders(low_boundary);
 }
 
 template <class CompiledICorStaticCall>
@@ -606,7 +592,7 @@
   }
 
   // Exception cache
-  clean_exception_cache(is_alive);
+  clean_exception_cache();
 
   bool postponed = false;
 
@@ -619,7 +605,7 @@
       if (unloading_occurred) {
         // If class unloading occurred we first iterate over all inline caches and
         // clear ICs where the cached oop is referring to an unloaded klass or method.
-        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive);
+        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter));
       }
 
       postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
@@ -656,7 +642,7 @@
 #endif
 
   // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
+  verify_metadata_loaders(low_boundary);
 
   return postponed;
 }
--- a/src/hotspot/share/code/compiledMethod.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/compiledMethod.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -295,7 +295,7 @@
   void release_set_exception_cache(ExceptionCache *ec);
   address handler_for_exception_and_pc(Handle exception, address pc);
   void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
-  void clean_exception_cache(BoolObjectClosure* is_alive);
+  void clean_exception_cache();
 
   void add_exception_cache_entry(ExceptionCache* new_entry);
   ExceptionCache* exception_cache_entry_for_exception(Handle exception);
@@ -364,10 +364,10 @@
   void set_unloading_next(CompiledMethod* next) { _unloading_next = next; }
   CompiledMethod* unloading_next()              { return _unloading_next; }
 
-  void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive);
+  void static clean_ic_if_metadata_is_dead(CompiledIC *ic);
 
   // Check that all metadata is still alive
-  void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
+  void verify_metadata_loaders(address low_boundary);
 
   virtual void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
   //  The parallel versions are used by G1.
--- a/src/hotspot/share/code/compiledMethod.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/compiledMethod.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -28,6 +28,7 @@
 #include "code/compiledMethod.hpp"
 #include "code/nativeInst.hpp"
 #include "runtime/frame.hpp"
+#include "runtime/orderAccess.hpp"
 
 inline bool CompiledMethod::is_deopt_pc(address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
 
--- a/src/hotspot/share/code/nmethod.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/code/nmethod.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1365,7 +1365,7 @@
         }
         // During GC the is_alive closure is non-NULL, and is used to
         // determine liveness of dependees that need to be updated.
-        if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
+        if (is_alive == NULL || klass->is_loader_alive()) {
           // The GC defers deletion of this entry, since there might be multiple threads
           // iterating over the _dependencies graph. Other call paths are single-threaded
           // and may delete it immediately.
--- a/src/hotspot/share/compiler/compileBroker.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -50,6 +50,7 @@
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
+#include "runtime/jniHandles.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/safepointVerifiers.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -117,6 +118,17 @@
 // The installed compiler(s)
 AbstractCompiler* CompileBroker::_compilers[2];
 
+// The maximum numbers of compiler threads to be determined during startup.
+int CompileBroker::_c1_count = 0;
+int CompileBroker::_c2_count = 0;
+
+// An array of compiler names as Java String objects
+jobject* CompileBroker::_compiler1_objects = NULL;
+jobject* CompileBroker::_compiler2_objects = NULL;
+
+CompileLog** CompileBroker::_compiler1_logs = NULL;
+CompileLog** CompileBroker::_compiler2_logs = NULL;
+
 // These counters are used to assign an unique ID to each compilation.
 volatile jint CompileBroker::_compilation_id     = 0;
 volatile jint CompileBroker::_osr_compilation_id = 0;
@@ -287,6 +299,36 @@
 }
 
 /**
+ * Check if a CompilerThread can be removed and update count if requested.
+ */
+static bool can_remove(CompilerThread *ct, bool do_it) {
+  assert(UseDynamicNumberOfCompilerThreads, "or shouldn't be here");
+  if (!ReduceNumberOfCompilerThreads) return false;
+
+  AbstractCompiler *compiler = ct->compiler();
+  int compiler_count = compiler->num_compiler_threads();
+  bool c1 = compiler->is_c1();
+
+  // Keep at least 1 compiler thread of each type.
+  if (compiler_count < 2) return false;
+
+  // Keep thread alive for at least some time.
+  if (ct->idle_time_millis() < (c1 ? 500 : 100)) return false;
+
+  // We only allow the last compiler thread of each type to get removed.
+  jobject last_compiler = c1 ? CompileBroker::compiler1_object(compiler_count - 1)
+                             : CompileBroker::compiler2_object(compiler_count - 1);
+  if (oopDesc::equals(ct->threadObj(), JNIHandles::resolve_non_null(last_compiler))) {
+    if (do_it) {
+      assert_locked_or_safepoint(CompileThread_lock); // Update must be consistent.
+      compiler->set_num_compiler_threads(compiler_count - 1);
+    }
+    return true;
+  }
+  return false;
+}
+
+/**
  * Add a CompileTask to a CompileQueue.
  */
 void CompileQueue::add(CompileTask* task) {
@@ -383,6 +425,11 @@
     // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
     // is not critical and we do not want idle compiler threads to wake up too often.
     MethodCompileQueue_lock->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
+
+    if (UseDynamicNumberOfCompilerThreads && _first == NULL) {
+      // Still nothing to compile. Give caller a chance to stop this thread.
+      if (can_remove(CompilerThread::current(), false)) return NULL;
+    }
   }
 
   if (CompileBroker::is_compilation_disabled_forever()) {
@@ -532,8 +579,8 @@
     return;
   }
   // Set the interface to the current compiler(s).
-  int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
-  int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
+  _c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
+  _c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
 
 #if INCLUDE_JVMCI
   if (EnableJVMCI) {
@@ -545,35 +592,35 @@
       if (FLAG_IS_DEFAULT(JVMCIThreads)) {
         if (BootstrapJVMCI) {
           // JVMCI will bootstrap so give it more threads
-          c2_count = MIN2(32, os::active_processor_count());
+          _c2_count = MIN2(32, os::active_processor_count());
         }
       } else {
-        c2_count = JVMCIThreads;
+        _c2_count = JVMCIThreads;
       }
       if (FLAG_IS_DEFAULT(JVMCIHostThreads)) {
       } else {
-        c1_count = JVMCIHostThreads;
+        _c1_count = JVMCIHostThreads;
       }
     }
   }
 #endif // INCLUDE_JVMCI
 
 #ifdef COMPILER1
-  if (c1_count > 0) {
+  if (_c1_count > 0) {
     _compilers[0] = new Compiler();
   }
 #endif // COMPILER1
 
 #ifdef COMPILER2
   if (true JVMCI_ONLY( && !UseJVMCICompiler)) {
-    if (c2_count > 0) {
+    if (_c2_count > 0) {
       _compilers[1] = new C2Compiler();
     }
   }
 #endif // COMPILER2
 
   // Start the compiler thread(s) and the sweeper thread
-  init_compiler_sweeper_threads(c1_count, c2_count);
+  init_compiler_sweeper_threads();
   // totalTime performance counter is always created as it is required
   // by the implementation of java.lang.management.CompilationMBean.
   {
@@ -679,29 +726,38 @@
   _initialized = true;
 }
 
-JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
-                                       AbstractCompiler* comp, bool compiler_thread, TRAPS) {
-  JavaThread* thread = NULL;
-  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0);
+Handle CompileBroker::create_thread_oop(const char* name, TRAPS) {
+  Klass* k = SystemDictionary::find(vmSymbols::java_lang_Thread(), Handle(), Handle(), CHECK_NH);
+  assert(k != NULL, "must be initialized");
   InstanceKlass* klass = InstanceKlass::cast(k);
-  instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
-  Handle string = java_lang_String::create_from_str(name, CHECK_0);
+  instanceHandle thread_handle = klass->allocate_instance_handle(CHECK_NH);
+  Handle string = java_lang_String::create_from_str(name, CHECK_NH);
 
   // Initialize thread_oop to put it into the system threadGroup
-  Handle thread_group (THREAD,  Universe::system_thread_group());
+  Handle thread_group(THREAD, Universe::system_thread_group());
   JavaValue result(T_VOID);
-  JavaCalls::call_special(&result, thread_oop,
+  JavaCalls::call_special(&result, thread_handle,
                        klass,
                        vmSymbols::object_initializer_name(),
                        vmSymbols::threadgroup_string_void_signature(),
                        thread_group,
                        string,
-                       CHECK_0);
+                       CHECK_NH);
+
+  return thread_handle;
+}
 
+
+JavaThread* CompileBroker::make_thread(jobject thread_handle, CompileQueue* queue,
+                                       AbstractCompiler* comp, bool compiler_thread, TRAPS) {
+  JavaThread* thread = NULL;
   {
     MutexLocker mu(Threads_lock, THREAD);
     if (compiler_thread) {
-      thread = new CompilerThread(queue, counters);
+      if (!InjectCompilerCreationFailure || comp->num_compiler_threads() == 0) {
+        CompilerCounters* counters = new CompilerCounters();
+        thread = new CompilerThread(queue, counters);
+      }
     } else {
       thread = new CodeCacheSweeperThread();
     }
@@ -720,13 +776,13 @@
 
     if (thread != NULL && thread->osthread() != NULL) {
 
-      java_lang_Thread::set_thread(thread_oop(), thread);
+      java_lang_Thread::set_thread(JNIHandles::resolve_non_null(thread_handle), thread);
 
       // Note that this only sets the JavaThread _priority field, which by
       // definition is limited to Java priorities and not OS priorities.
       // The os-priority is set in the CompilerThread startup code itself
 
-      java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
+      java_lang_Thread::set_priority(JNIHandles::resolve_non_null(thread_handle), NearMaxPriority);
 
       // Note that we cannot call os::set_priority because it expects Java
       // priorities and we are *explicitly* using OS priorities so that it's
@@ -743,9 +799,9 @@
       }
       os::set_native_priority(thread, native_prio);
 
-      java_lang_Thread::set_daemon(thread_oop());
+      java_lang_Thread::set_daemon(JNIHandles::resolve_non_null(thread_handle));
 
-      thread->set_threadObj(thread_oop());
+      thread->set_threadObj(JNIHandles::resolve_non_null(thread_handle));
       if (compiler_thread) {
         thread->as_CompilerThread()->set_compiler(comp);
       }
@@ -756,6 +812,12 @@
 
   // First release lock before aborting VM.
   if (thread == NULL || thread->osthread() == NULL) {
+    if (UseDynamicNumberOfCompilerThreads && comp->num_compiler_threads() > 0) {
+      if (thread != NULL) {
+        thread->smr_delete();
+      }
+      return NULL;
+    }
     vm_exit_during_initialization("java.lang.OutOfMemoryError",
                                   os::native_thread_creation_failed_msg());
   }
@@ -767,51 +829,123 @@
 }
 
 
-void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
+void CompileBroker::init_compiler_sweeper_threads() {
   EXCEPTION_MARK;
 #if !defined(ZERO)
-  assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
+  assert(_c2_count > 0 || _c1_count > 0, "No compilers?");
 #endif // !ZERO
   // Initialize the compilation queue
-  if (c2_compiler_count > 0) {
+  if (_c2_count > 0) {
     const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue";
     _c2_compile_queue  = new CompileQueue(name);
-    _compilers[1]->set_num_compiler_threads(c2_compiler_count);
+    _compiler2_objects = NEW_C_HEAP_ARRAY(jobject, _c2_count, mtCompiler);
+    _compiler2_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c2_count, mtCompiler);
   }
-  if (c1_compiler_count > 0) {
+  if (_c1_count > 0) {
     _c1_compile_queue  = new CompileQueue("C1 compile queue");
-    _compilers[0]->set_num_compiler_threads(c1_compiler_count);
+    _compiler1_objects = NEW_C_HEAP_ARRAY(jobject, _c1_count, mtCompiler);
+    _compiler1_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c1_count, mtCompiler);
   }
 
-  int compiler_count = c1_compiler_count + c2_compiler_count;
+  char name_buffer[256];
 
-  char name_buffer[256];
-  const bool compiler_thread = true;
-  for (int i = 0; i < c2_compiler_count; i++) {
+  for (int i = 0; i < _c2_count; i++) {
     // Create a name for our thread.
     sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
-    CompilerCounters* counters = new CompilerCounters();
-    make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
+    jobject thread_handle = JNIHandles::make_global(create_thread_oop(name_buffer, THREAD));
+    _compiler2_objects[i] = thread_handle;
+    _compiler2_logs[i] = NULL;
+
+    if (!UseDynamicNumberOfCompilerThreads || i == 0) {
+      JavaThread *ct = make_thread(thread_handle, _c2_compile_queue, _compilers[1], /* compiler_thread */ true, CHECK);
+      assert(ct != NULL, "should have been handled for initial thread");
+      _compilers[1]->set_num_compiler_threads(i + 1);
+      if (TraceCompilerThreads) {
+        ResourceMark rm;
+        MutexLocker mu(Threads_lock);
+        tty->print_cr("Added initial compiler thread %s", ct->get_thread_name());
+      }
+    }
   }
 
-  for (int i = c2_compiler_count; i < compiler_count; i++) {
+  for (int i = 0; i < _c1_count; i++) {
     // Create a name for our thread.
     sprintf(name_buffer, "C1 CompilerThread%d", i);
-    CompilerCounters* counters = new CompilerCounters();
-    // C1
-    make_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], compiler_thread, CHECK);
+    jobject thread_handle = JNIHandles::make_global(create_thread_oop(name_buffer, THREAD));
+    _compiler1_objects[i] = thread_handle;
+    _compiler1_logs[i] = NULL;
+
+    if (!UseDynamicNumberOfCompilerThreads || i == 0) {
+      JavaThread *ct = make_thread(thread_handle, _c1_compile_queue, _compilers[0], /* compiler_thread */ true, CHECK);
+      assert(ct != NULL, "should have been handled for initial thread");
+      _compilers[0]->set_num_compiler_threads(i + 1);
+      if (TraceCompilerThreads) {
+        ResourceMark rm;
+        MutexLocker mu(Threads_lock);
+        tty->print_cr("Added initial compiler thread %s", ct->get_thread_name());
+      }
+    }
   }
 
   if (UsePerfData) {
-    PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK);
+    PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, _c1_count + _c2_count, CHECK);
   }
 
   if (MethodFlushing) {
     // Initialize the sweeper thread
-    make_thread("Sweeper thread", NULL, NULL, NULL, false, CHECK);
+    jobject thread_handle = JNIHandles::make_local(THREAD, create_thread_oop("Sweeper thread", THREAD)());
+    make_thread(thread_handle, NULL, NULL, /* compiler_thread */ false, CHECK);
   }
 }
 
+void CompileBroker::possibly_add_compiler_threads() {
+  EXCEPTION_MARK;
+
+  julong available_memory = os::available_memory();
+  // Only do attempt to start additional threads if the lock is free.
+  if (!CompileThread_lock->try_lock()) return;
+
+  if (_c2_compile_queue != NULL) {
+    int old_c2_count = _compilers[1]->num_compiler_threads();
+    int new_c2_count = MIN3(_c2_count,
+        _c2_compile_queue->size() / 2,
+        (int)(available_memory / 200*M));
+
+    for (int i = old_c2_count; i < new_c2_count; i++) {
+      JavaThread *ct = make_thread(compiler2_object(i), _c2_compile_queue, _compilers[1], true, CHECK);
+      if (ct == NULL) break;
+      _compilers[1]->set_num_compiler_threads(i + 1);
+      if (TraceCompilerThreads) {
+        ResourceMark rm;
+        MutexLocker mu(Threads_lock);
+        tty->print_cr("Added compiler thread %s (available memory: %dMB)",
+                      ct->get_thread_name(), (int)(available_memory/M));
+      }
+    }
+  }
+
+  if (_c1_compile_queue != NULL) {
+    int old_c1_count = _compilers[0]->num_compiler_threads();
+    int new_c1_count = MIN3(_c1_count,
+        _c1_compile_queue->size() / 4,
+        (int)(available_memory / 100*M));
+
+    for (int i = old_c1_count; i < new_c1_count; i++) {
+      JavaThread *ct = make_thread(compiler1_object(i), _c1_compile_queue, _compilers[0], true, CHECK);
+      if (ct == NULL) break;
+      _compilers[0]->set_num_compiler_threads(i + 1);
+      if (TraceCompilerThreads) {
+        ResourceMark rm;
+        MutexLocker mu(Threads_lock);
+        tty->print_cr("Added compiler thread %s (available memory: %dMB)",
+                      ct->get_thread_name(), (int)(available_memory/M));
+      }
+    }
+  }
+
+  CompileThread_lock->unlock();
+}
+
 
 /**
  * Set the methods on the stack as on_stack so that redefine classes doesn't
@@ -1546,6 +1680,49 @@
   }
 }
 
+/**
+ * Helper function to create new or reuse old CompileLog.
+ */
+CompileLog* CompileBroker::get_log(CompilerThread* ct) {
+  if (!LogCompilation) return NULL;
+
+  AbstractCompiler *compiler = ct->compiler();
+  bool c1 = compiler->is_c1();
+  jobject* compiler_objects = c1 ? _compiler1_objects : _compiler2_objects;
+  assert(compiler_objects != NULL, "must be initialized at this point");
+  CompileLog** logs = c1 ? _compiler1_logs : _compiler2_logs;
+  assert(logs != NULL, "must be initialized at this point");
+  int count = c1 ? _c1_count : _c2_count;
+
+  // Find Compiler number by its threadObj.
+  oop compiler_obj = ct->threadObj();
+  int compiler_number = 0;
+  bool found = false;
+  for (; compiler_number < count; compiler_number++) {
+    if (oopDesc::equals(JNIHandles::resolve_non_null(compiler_objects[compiler_number]), compiler_obj)) {
+      found = true;
+      break;
+    }
+  }
+  assert(found, "Compiler must exist at this point");
+
+  // Determine pointer for this thread's log.
+  CompileLog** log_ptr = &logs[compiler_number];
+
+  // Return old one if it exists.
+  CompileLog* log = *log_ptr;
+  if (log != NULL) {
+    ct->init_log(log);
+    return log;
+  }
+
+  // Create a new one and remember it.
+  init_compiler_thread_log();
+  log = ct->log();
+  *log_ptr = log;
+  return log;
+}
+
 // ------------------------------------------------------------------
 // CompileBroker::compiler_thread_loop
 //
@@ -1568,10 +1745,7 @@
   }
 
   // Open a log.
-  if (LogCompilation) {
-    init_compiler_thread_log();
-  }
-  CompileLog* log = thread->log();
+  CompileLog* log = get_log(thread);
   if (log != NULL) {
     log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'",
                     thread->name(),
@@ -1586,6 +1760,8 @@
     return;
   }
 
+  thread->start_idle_timer();
+
   // Poll for new compilation tasks as long as the JVM runs. Compilation
   // should only be disabled if something went wrong while initializing the
   // compiler runtimes. This, in turn, should not happen. The only known case
@@ -1597,9 +1773,24 @@
 
     CompileTask* task = queue->get();
     if (task == NULL) {
+      if (UseDynamicNumberOfCompilerThreads) {
+        // Access compiler_count under lock to enforce consistency.
+        MutexLocker only_one(CompileThread_lock);
+        if (can_remove(thread, true)) {
+          if (TraceCompilerThreads) {
+            tty->print_cr("Removing compiler thread %s after " JLONG_FORMAT " ms idle time",
+                          thread->name(), thread->idle_time_millis());
+          }
+          return; // Stop this thread.
+        }
+      }
       continue;
     }
 
+    if (UseDynamicNumberOfCompilerThreads) {
+      possibly_add_compiler_threads();
+    }
+
     // Give compiler threads an extra quanta.  They tend to be bursty and
     // this helps the compiler to finish up the job.
     if (CompilerThreadHintNoPreempt) {
@@ -1618,6 +1809,7 @@
       // Compile the method.
       if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
         invoke_compiler_on_method(task);
+        thread->start_idle_timer();
       } else {
         // After compilation is disabled, remove remaining methods from queue
         method->clear_queued_for_compilation();
--- a/src/hotspot/share/compiler/compileBroker.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/compiler/compileBroker.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -161,6 +161,15 @@
   // The installed compiler(s)
   static AbstractCompiler* _compilers[2];
 
+  // The maximum numbers of compiler threads to be determined during startup.
+  static int _c1_count, _c2_count;
+
+  // An array of compiler thread Java objects
+  static jobject *_compiler1_objects, *_compiler2_objects;
+
+  // An array of compiler logs
+  static CompileLog **_compiler1_logs, **_compiler2_logs;
+
   // These counters are used for assigning id's to each compilation
   static volatile jint _compilation_id;
   static volatile jint _osr_compilation_id;
@@ -219,8 +228,11 @@
 
   static volatile int _print_compilation_warning;
 
-  static JavaThread* make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, bool compiler_thread, TRAPS);
-  static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count);
+  static Handle create_thread_oop(const char* name, TRAPS);
+  static JavaThread* make_thread(jobject thread_oop, CompileQueue* queue,
+                                 AbstractCompiler* comp, bool compiler_thread, TRAPS);
+  static void init_compiler_sweeper_threads();
+  static void possibly_add_compiler_threads();
   static bool compilation_is_complete  (const methodHandle& method, int osr_bci, int comp_level);
   static bool compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level, bool excluded);
   static void preload_classes          (const methodHandle& method, TRAPS);
@@ -367,6 +379,21 @@
   // compiler name for debugging
   static const char* compiler_name(int comp_level);
 
+  // Provide access to compiler thread Java objects
+  static jobject compiler1_object(int idx) {
+    assert(_compiler1_objects != NULL, "must be initialized");
+    assert(idx < _c1_count, "oob");
+    return _compiler1_objects[idx];
+  }
+
+  static jobject compiler2_object(int idx) {
+    assert(_compiler2_objects != NULL, "must be initialized");
+    assert(idx < _c2_count, "oob");
+    return _compiler2_objects[idx];
+  }
+
+  static CompileLog* get_log(CompilerThread* ct);
+
   static int get_total_compile_count() {          return _total_compile_count; }
   static int get_total_bailout_count() {          return _total_bailout_count; }
   static int get_total_invalidated_count() {      return _total_invalidated_count; }
--- a/src/hotspot/share/gc/cms/cmsOopClosures.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsOopClosures.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,7 @@
  public:
   PushAndMarkClosure(CMSCollector* collector,
                      MemRegion span,
-                     ReferenceProcessor* rp,
+                     ReferenceDiscoverer* rd,
                      CMSBitMap* bit_map,
                      CMSBitMap* mod_union_table,
                      CMSMarkStack* mark_stack,
@@ -141,7 +141,7 @@
  public:
   ParPushAndMarkClosure(CMSCollector* collector,
                         MemRegion span,
-                        ReferenceProcessor* rp,
+                        ReferenceDiscoverer* rd,
                         CMSBitMap* bit_map,
                         OopTaskQueue* work_queue);
   virtual void do_oop(oop* p);
@@ -166,7 +166,7 @@
   DO_OOP_WORK_DEFN
  public:
   MarkRefsIntoAndScanClosure(MemRegion span,
-                             ReferenceProcessor* rp,
+                             ReferenceDiscoverer* rd,
                              CMSBitMap* bit_map,
                              CMSBitMap* mod_union_table,
                              CMSMarkStack* mark_stack,
@@ -204,7 +204,7 @@
  public:
   ParMarkRefsIntoAndScanClosure(CMSCollector* collector,
                                  MemRegion span,
-                                 ReferenceProcessor* rp,
+                                 ReferenceDiscoverer* rd,
                                  CMSBitMap* bit_map,
                                  OopTaskQueue* work_queue);
   virtual void do_oop(oop* p);
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -5244,7 +5244,7 @@
       CodeCache::do_unloading(&_is_alive_closure, purged_class);
 
       // Prune dead klasses from subklass/sibling/implementor lists.
-      Klass::clean_weak_klass_links(&_is_alive_closure);
+      Klass::clean_weak_klass_links();
     }
 
     {
@@ -5825,7 +5825,7 @@
     _span(span),
     _bitMap(bitMap)
 {
-  assert(ref_processor() == NULL, "deliberately left NULL");
+  assert(ref_discoverer() == NULL, "deliberately left NULL");
   assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
 }
 
@@ -5847,7 +5847,7 @@
     _span(span),
     _bitMap(bitMap)
 {
-  assert(ref_processor() == NULL, "deliberately left NULL");
+  assert(ref_discoverer() == NULL, "deliberately left NULL");
   assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
 }
 
@@ -5871,7 +5871,7 @@
     _verification_bm(verification_bm),
     _cms_bm(cms_bm)
 {
-  assert(ref_processor() == NULL, "deliberately left NULL");
+  assert(ref_discoverer() == NULL, "deliberately left NULL");
   assert(_verification_bm->covers(_span), "_verification_bm/_span mismatch");
 }
 
@@ -5900,7 +5900,7 @@
 //////////////////////////////////////////////////
 
 MarkRefsIntoAndScanClosure::MarkRefsIntoAndScanClosure(MemRegion span,
-                                                       ReferenceProcessor* rp,
+                                                       ReferenceDiscoverer* rd,
                                                        CMSBitMap* bit_map,
                                                        CMSBitMap* mod_union_table,
                                                        CMSMarkStack*  mark_stack,
@@ -5911,15 +5911,15 @@
   _span(span),
   _bit_map(bit_map),
   _mark_stack(mark_stack),
-  _pushAndMarkClosure(collector, span, rp, bit_map, mod_union_table,
+  _pushAndMarkClosure(collector, span, rd, bit_map, mod_union_table,
                       mark_stack, concurrent_precleaning),
   _yield(should_yield),
   _concurrent_precleaning(concurrent_precleaning),
   _freelistLock(NULL)
 {
   // FIXME: Should initialize in base class constructor.
-  assert(rp != NULL, "ref_processor shouldn't be NULL");
-  set_ref_processor_internal(rp);
+  assert(rd != NULL, "ref_discoverer shouldn't be NULL");
+  set_ref_discoverer_internal(rd);
 }
 
 // This closure is used to mark refs into the CMS generation at the
@@ -6004,18 +6004,18 @@
 //                                MarkRefsIntoAndScanClosure
 ///////////////////////////////////////////////////////////
 ParMarkRefsIntoAndScanClosure::ParMarkRefsIntoAndScanClosure(
-  CMSCollector* collector, MemRegion span, ReferenceProcessor* rp,
+  CMSCollector* collector, MemRegion span, ReferenceDiscoverer* rd,
   CMSBitMap* bit_map, OopTaskQueue* work_queue):
   _span(span),
   _bit_map(bit_map),
   _work_queue(work_queue),
   _low_water_mark(MIN2((work_queue->max_elems()/4),
                        ((uint)CMSWorkQueueDrainThreshold * ParallelGCThreads))),
-  _parPushAndMarkClosure(collector, span, rp, bit_map, work_queue)
+  _parPushAndMarkClosure(collector, span, rd, bit_map, work_queue)
 {
   // FIXME: Should initialize in base class constructor.
-  assert(rp != NULL, "ref_processor shouldn't be NULL");
-  set_ref_processor_internal(rp);
+  assert(rd != NULL, "ref_discoverer shouldn't be NULL");
+  set_ref_discoverer_internal(rd);
 }
 
 // This closure is used to mark refs into the CMS generation at the
@@ -6842,12 +6842,12 @@
 
 PushAndMarkClosure::PushAndMarkClosure(CMSCollector* collector,
                                        MemRegion span,
-                                       ReferenceProcessor* rp,
+                                       ReferenceDiscoverer* rd,
                                        CMSBitMap* bit_map,
                                        CMSBitMap* mod_union_table,
                                        CMSMarkStack*  mark_stack,
                                        bool           concurrent_precleaning):
-  MetadataAwareOopClosure(rp),
+  MetadataAwareOopClosure(rd),
   _collector(collector),
   _span(span),
   _bit_map(bit_map),
@@ -6855,7 +6855,7 @@
   _mark_stack(mark_stack),
   _concurrent_precleaning(concurrent_precleaning)
 {
-  assert(ref_processor() != NULL, "ref_processor shouldn't be NULL");
+  assert(ref_discoverer() != NULL, "ref_discoverer shouldn't be NULL");
 }
 
 // Grey object rescan during pre-cleaning and second checkpoint phases --
@@ -6916,16 +6916,16 @@
 
 ParPushAndMarkClosure::ParPushAndMarkClosure(CMSCollector* collector,
                                              MemRegion span,
-                                             ReferenceProcessor* rp,
+                                             ReferenceDiscoverer* rd,
                                              CMSBitMap* bit_map,
                                              OopTaskQueue* work_queue):
-  MetadataAwareOopClosure(rp),
+  MetadataAwareOopClosure(rd),
   _collector(collector),
   _span(span),
   _bit_map(bit_map),
   _work_queue(work_queue)
 {
-  assert(ref_processor() != NULL, "ref_processor shouldn't be NULL");
+  assert(ref_discoverer() != NULL, "ref_discoverer shouldn't be NULL");
 }
 
 void PushAndMarkClosure::do_oop(oop* p)       { PushAndMarkClosure::do_oop_work(p); }
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -3125,7 +3125,7 @@
       ReferenceProcessor*             rp = _g1h->ref_processor_stw();
 
       G1ParScanThreadState*           pss = _pss->state_for_worker(worker_id);
-      pss->set_ref_processor(rp);
+      pss->set_ref_discoverer(rp);
 
       double start_strong_roots_sec = os::elapsedTime();
 
@@ -3457,13 +3457,11 @@
 Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never);
 
 class G1KlassCleaningTask : public StackObj {
-  BoolObjectClosure*                      _is_alive;
   volatile int                            _clean_klass_tree_claimed;
   ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
 
  public:
-  G1KlassCleaningTask(BoolObjectClosure* is_alive) :
-      _is_alive(is_alive),
+  G1KlassCleaningTask() :
       _clean_klass_tree_claimed(0),
       _klass_iterator() {
   }
@@ -3490,7 +3488,7 @@
 public:
 
   void clean_klass(InstanceKlass* ik) {
-    ik->clean_weak_instanceklass_links(_is_alive);
+    ik->clean_weak_instanceklass_links();
   }
 
   void work() {
@@ -3498,7 +3496,7 @@
 
     // One worker will clean the subklass/sibling klass tree.
     if (claim_clean_klass_tree_task()) {
-      Klass::clean_subklass_tree(_is_alive);
+      Klass::clean_subklass_tree();
     }
 
     // All workers will help cleaning the classes,
@@ -3510,11 +3508,10 @@
 };
 
 class G1ResolvedMethodCleaningTask : public StackObj {
-  BoolObjectClosure* _is_alive;
   volatile int       _resolved_method_task_claimed;
 public:
-  G1ResolvedMethodCleaningTask(BoolObjectClosure* is_alive) :
-      _is_alive(is_alive), _resolved_method_task_claimed(0) {}
+  G1ResolvedMethodCleaningTask() :
+      _resolved_method_task_claimed(0) {}
 
   bool claim_resolved_method_task() {
     if (_resolved_method_task_claimed) {
@@ -3526,7 +3523,7 @@
   // These aren't big, one thread can do it all.
   void work() {
     if (claim_resolved_method_task()) {
-      ResolvedMethodTable::unlink(_is_alive);
+      ResolvedMethodTable::unlink();
     }
   }
 };
@@ -3546,8 +3543,8 @@
       AbstractGangTask("Parallel Cleaning"),
       _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()),
       _code_cache_task(num_workers, is_alive, unloading_occurred),
-      _klass_cleaning_task(is_alive),
-      _resolved_method_cleaning_task(is_alive) {
+      _klass_cleaning_task(),
+      _resolved_method_cleaning_task() {
   }
 
   // The parallel work done by all worker threads.
@@ -3823,7 +3820,7 @@
     G1STWIsAliveClosure is_alive(_g1h);
 
     G1ParScanThreadState*          pss = _pss->state_for_worker(worker_id);
-    pss->set_ref_processor(NULL);
+    pss->set_ref_discoverer(NULL);
 
     // Keep alive closure.
     G1CopyingKeepAliveClosure keep_alive(_g1h, pss->closures()->raw_strong_oops(), pss);
@@ -3915,7 +3912,7 @@
     HandleMark   hm;
 
     G1ParScanThreadState*          pss = _pss->state_for_worker(worker_id);
-    pss->set_ref_processor(NULL);
+    pss->set_ref_discoverer(NULL);
     assert(pss->queue_is_empty(), "both queue and overflow should be empty");
 
     // Is alive closure
@@ -4021,7 +4018,7 @@
 
   // Use only a single queue for this PSS.
   G1ParScanThreadState*          pss = per_thread_states->state_for_worker(0);
-  pss->set_ref_processor(NULL);
+  pss->set_ref_discoverer(NULL);
   assert(pss->queue_is_empty(), "pre-condition");
 
   // Keep alive closure.
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1413,14 +1413,13 @@
 class G1CMKeepAliveAndDrainClosure : public OopClosure {
   G1ConcurrentMark* _cm;
   G1CMTask*         _task;
-  int               _ref_counter_limit;
-  int               _ref_counter;
+  uint              _ref_counter_limit;
+  uint              _ref_counter;
   bool              _is_serial;
 public:
   G1CMKeepAliveAndDrainClosure(G1ConcurrentMark* cm, G1CMTask* task, bool is_serial) :
     _cm(cm), _task(task), _is_serial(is_serial),
     _ref_counter_limit(G1RefProcDrainInterval) {
-    assert(_ref_counter_limit > 0, "sanity");
     assert(!_is_serial || _task->worker_id() == 0, "only task 0 for serial code");
     _ref_counter = _ref_counter_limit;
   }
@@ -1696,14 +1695,6 @@
     assert(!rp->discovery_enabled(), "Post condition");
   }
 
-  assert(has_overflown() || _global_mark_stack.is_empty(),
-         "Mark stack should be empty (unless it has overflown)");
-
-  {
-    GCTraceTime(Debug, gc, phases) debug("Weak Processing", _gc_timer_cm);
-    WeakProcessor::weak_oops_do(&g1_is_alive, &do_nothing_cl);
-  }
-
   if (has_overflown()) {
     // We can not trust g1_is_alive if the marking stack overflowed
     return;
@@ -1711,6 +1702,11 @@
 
   assert(_global_mark_stack.is_empty(), "Marking should have completed");
 
+  {
+    GCTraceTime(Debug, gc, phases) debug("Weak Processing", _gc_timer_cm);
+    WeakProcessor::weak_oops_do(&g1_is_alive, &do_nothing_cl);
+  }
+
   // Unload Klasses, String, Symbols, Code Cache, etc.
   if (ClassUnloadingWithConcurrentMark) {
     GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm);
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 #include "gc/g1/g1OopClosures.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1StringDedup.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/referenceProcessor.hpp"
@@ -72,10 +73,40 @@
   return _heap->ref_processor_stw();
 }
 
+uint G1FullCollector::calc_active_workers() {
+  G1CollectedHeap* heap = G1CollectedHeap::heap();
+  uint max_worker_count = heap->workers()->total_workers();
+  // Only calculate number of workers if UseDynamicNumberOfGCThreads
+  // is enabled, otherwise use max.
+  if (!UseDynamicNumberOfGCThreads) {
+    return max_worker_count;
+  }
+
+  // Consider G1HeapWastePercent to decide max number of workers. Each worker
+  // will in average cause half a region waste.
+  uint max_wasted_regions_allowed = ((heap->num_regions() * G1HeapWastePercent) / 100);
+  uint waste_worker_count = MAX2((max_wasted_regions_allowed * 2) , 1u);
+  uint heap_waste_worker_limit = MIN2(waste_worker_count, max_worker_count);
+
+  // Also consider HeapSizePerGCThread by calling AdaptiveSizePolicy to calculate
+  // the number of workers.
+  uint current_active_workers = heap->workers()->active_workers();
+  uint adaptive_worker_limit = AdaptiveSizePolicy::calc_active_workers(max_worker_count, current_active_workers, 0);
+
+  // Update active workers to the lower of the limits.
+  uint worker_count = MIN2(heap_waste_worker_limit, adaptive_worker_limit);
+  log_debug(gc, task)("Requesting %u active workers for full compaction (waste limited workers: %u, adaptive workers: %u)",
+                      worker_count, heap_waste_worker_limit, adaptive_worker_limit);
+  worker_count = heap->workers()->update_active_workers(worker_count);
+  log_info(gc, task)("Using %u workers of %u for full compaction", worker_count, max_worker_count);
+
+  return worker_count;
+}
+
 G1FullCollector::G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs) :
     _heap(heap),
     _scope(memory_manager, explicit_gc, clear_soft_refs),
-    _num_workers(heap->workers()->active_workers()),
+    _num_workers(calc_active_workers()),
     _oop_queue_set(_num_workers),
     _array_queue_set(_num_workers),
     _preserved_marks_set(true),
--- a/src/hotspot/share/gc/g1/g1FullCollector.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -56,6 +56,8 @@
   G1IsAliveClosure          _is_alive;
   ReferenceProcessorIsAliveMutator _is_alive_mutator;
 
+  static uint calc_active_workers();
+
 public:
   G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs);
   ~G1FullCollector();
--- a/src/hotspot/share/gc/g1/g1FullGCOopClosures.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -60,7 +60,7 @@
   uint _worker_id;
 
 public:
-  G1MarkAndPushClosure(uint worker, G1FullGCMarker* marker, ReferenceProcessor* ref) :
+  G1MarkAndPushClosure(uint worker, G1FullGCMarker* marker, ReferenceDiscoverer* ref) :
     _marker(marker),
     _worker_id(worker),
     ExtendedOopClosure(ref) { }
--- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -27,6 +27,7 @@
 #include "gc/g1/g1MonitoringSupport.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/shared/hSpaceCounters.hpp"
+#include "memory/metaspaceCounters.hpp"
 
 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
                                            const char* name,
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -96,8 +96,8 @@
   virtual void do_oop(oop* p)          { do_oop_nv(p); }
   virtual void do_oop(narrowOop* p)    { do_oop_nv(p); }
 
-  void set_ref_processor(ReferenceProcessor* rp) {
-    set_ref_processor_internal(rp);
+  void set_ref_discoverer(ReferenceDiscoverer* rd) {
+    set_ref_discoverer_internal(rd);
   }
 };
 
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -87,7 +87,7 @@
   G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, size_t young_cset_length);
   virtual ~G1ParScanThreadState();
 
-  void set_ref_processor(ReferenceProcessor* rp) { _scanner.set_ref_processor(rp); }
+  void set_ref_discoverer(ReferenceDiscoverer* rd) { _scanner.set_ref_discoverer(rd); }
 
 #ifdef ASSERT
   bool queue_is_empty() const { return _refs->is_empty(); }
--- a/src/hotspot/share/gc/g1/g1_globals.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1_globals.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -74,7 +74,7 @@
           "in milliseconds.")                                               \
           range(1.0, DBL_MAX)                                               \
                                                                             \
-  product(int, G1RefProcDrainInterval, 10,                                  \
+  product(uint, G1RefProcDrainInterval, 1000,                               \
           "The number of discovered reference objects to process before "   \
           "draining concurrent marking work queues.")                       \
           range(1, INT_MAX)                                                 \
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -41,6 +41,7 @@
 #include "gc/shared/gcLocker.hpp"
 #include "gc/shared/gcWhen.hpp"
 #include "logging/log.hpp"
+#include "memory/metaspaceCounters.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -562,7 +562,7 @@
     CodeCache::do_unloading(is_alive_closure(), purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(is_alive_closure());
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -2139,7 +2139,7 @@
     CodeCache::do_unloading(is_alive_closure(), purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(is_alive_closure());
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,7 +234,7 @@
     CodeCache::do_unloading(&is_alive, purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(&is_alive);
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/gc/serial/markSweep.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/serial/markSweep.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -211,7 +211,7 @@
 
 void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {
   _ref_processor = rp;
-  mark_and_push_closure.set_ref_processor(_ref_processor);
+  mark_and_push_closure.set_ref_discoverer(_ref_processor);
 }
 
 AdjustPointerClosure MarkSweep::adjust_pointer_closure;
--- a/src/hotspot/share/gc/serial/markSweep.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/serial/markSweep.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -184,8 +184,8 @@
   virtual void do_cld(ClassLoaderData* cld);
   void do_cld_nv(ClassLoaderData* cld);
 
-  void set_ref_processor(ReferenceProcessor* rp) {
-    set_ref_processor_internal(rp);
+  void set_ref_discoverer(ReferenceDiscoverer* rd) {
+    set_ref_discoverer_internal(rd);
   }
 };
 
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -355,6 +355,7 @@
   //   For ParNew collections
   //   For PS scavenge and ParOld collections
   //   For G1 evacuation pauses (subject to update)
+  //   For G1 Full GCs (subject to update)
   // Other collection phases inherit the number of
   // GC workers from the calls above.  For example,
   // a CMS parallel remark uses the same number of GC
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -172,6 +172,22 @@
   return false;
 }
 
+bool CollectedHeap::is_oop(oop object) const {
+  if (!check_obj_alignment(object)) {
+    return false;
+  }
+
+  if (!is_in_reserved(object)) {
+    return false;
+  }
+
+  if (is_in_reserved(object->klass_or_null())) {
+    return false;
+  }
+
+  return true;
+}
+
 // Memory state functions.
 
 
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -591,6 +591,8 @@
   virtual oop pin_object(JavaThread* thread, oop obj);
   virtual void unpin_object(JavaThread* thread, oop obj);
 
+  virtual bool is_oop(oop object) const;
+
   // Non product verification and debugging.
 #ifndef PRODUCT
   // Support for PromotionFailureALot.  Return true if it's time to cause a
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -49,6 +49,7 @@
 #include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "memory/filemap.hpp"
+#include "memory/metaspaceCounters.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/biasedLocking.hpp"
--- a/src/hotspot/share/gc/shared/genOopClosures.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/genOopClosures.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -151,7 +151,7 @@
   template <class T> inline void do_oop_work(T* p);
  public:
   FilteringClosure(HeapWord* boundary, ExtendedOopClosure* cl) :
-    ExtendedOopClosure(cl->ref_processor()), _boundary(boundary),
+    ExtendedOopClosure(cl->ref_discoverer()), _boundary(boundary),
     _cl(cl) {}
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/referenceDiscoverer.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_REFERENCEDISCOVERER_HPP
+#define SHARE_GC_SHARED_REFERENCEDISCOVERER_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/referenceType.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+class ReferenceDiscoverer : public CHeapObj<mtGC> {
+public:
+  virtual bool discover_reference(oop obj, ReferenceType type) = 0;
+};
+
+#endif // SHARE_GC_SHARED_REFERENCEDISCOVERER_HPP
--- a/src/hotspot/share/gc/shared/referenceProcessor.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/referenceProcessor.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_HPP
 #define SHARE_VM_GC_SHARED_REFERENCEPROCESSOR_HPP
 
+#include "gc/shared/referenceDiscoverer.hpp"
 #include "gc/shared/referencePolicy.hpp"
 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
 #include "gc/shared/referenceProcessorStats.hpp"
@@ -166,7 +167,7 @@
   }
 };
 
-class ReferenceProcessor : public CHeapObj<mtGC> {
+class ReferenceProcessor : public ReferenceDiscoverer {
 
  private:
   size_t total_count(DiscoveredList lists[]) const;
@@ -405,7 +406,7 @@
   void verify_list(DiscoveredList& ref_list);
 
   // Discover a Reference object, using appropriate discovery criteria
-  bool discover_reference(oop obj, ReferenceType rt);
+  virtual bool discover_reference(oop obj, ReferenceType rt);
 
   // Has discovered references that need handling
   bool has_discovered_references();
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -164,6 +164,13 @@
 
   static size_t refill_waste_limit_increment()   { return TLABWasteIncrement; }
 
+  template <typename T> void addresses_do(T f) {
+    f(&_start);
+    f(&_top);
+    f(&_pf_top);
+    f(&_end);
+  }
+
   // Code generation support
   static ByteSize start_offset()                 { return byte_offset_of(ThreadLocalAllocBuffer, _start); }
   static ByteSize end_offset()                   { return byte_offset_of(ThreadLocalAllocBuffer, _end  ); }
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -415,6 +415,34 @@
   }
 JRT_END
 
+// Object.notify() fast path, caller does slow path
+JRT_LEAF(jboolean, JVMCIRuntime::object_notify(JavaThread *thread, oopDesc* obj))
+
+  // Very few notify/notifyAll operations find any threads on the waitset, so
+  // the dominant fast-path is to simply return.
+  // Relatedly, it's critical that notify/notifyAll be fast in order to
+  // reduce lock hold times.
+  if (!SafepointSynchronize::is_synchronizing()) {
+    if (ObjectSynchronizer::quick_notify(obj, thread, false)) {
+      return true;
+    }
+  }
+  return false; // caller must perform slow path
+
+JRT_END
+
+// Object.notifyAll() fast path, caller does slow path
+JRT_LEAF(jboolean, JVMCIRuntime::object_notifyAll(JavaThread *thread, oopDesc* obj))
+
+  if (!SafepointSynchronize::is_synchronizing() ) {
+    if (ObjectSynchronizer::quick_notify(obj, thread, true)) {
+      return true;
+    }
+  }
+  return false; // caller must perform slow path
+
+JRT_END
+
 JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message))
   TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
   SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, message);
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -139,6 +139,8 @@
   static address exception_handler_for_pc(JavaThread* thread);
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static jboolean object_notify(JavaThread* thread, oopDesc* obj);
+  static jboolean object_notifyAll(JavaThread* thread, oopDesc* obj);
   static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value);
   static oopDesc* load_and_clear_exception(JavaThread* thread);
   static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3);
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -625,6 +625,8 @@
   declare_function(JVMCIRuntime::exception_handler_for_pc) \
   declare_function(JVMCIRuntime::monitorenter) \
   declare_function(JVMCIRuntime::monitorexit) \
+  declare_function(JVMCIRuntime::object_notify) \
+  declare_function(JVMCIRuntime::object_notifyAll) \
   declare_function(JVMCIRuntime::throw_and_post_jvmti_exception) \
   declare_function(JVMCIRuntime::throw_klass_external_name_exception) \
   declare_function(JVMCIRuntime::throw_class_cast_exception) \
--- a/src/hotspot/share/memory/heapInspection.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/memory/heapInspection.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/collectedHeap.hpp"
--- a/src/hotspot/share/memory/iterator.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/memory/iterator.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -31,7 +31,7 @@
 
 class CodeBlob;
 class nmethod;
-class ReferenceProcessor;
+class ReferenceDiscoverer;
 class DataLayout;
 class KlassClosure;
 class ClassLoaderData;
@@ -60,17 +60,17 @@
 // pollute the OopClosure interface.
 class ExtendedOopClosure : public OopClosure {
  private:
-  ReferenceProcessor* _ref_processor;
+  ReferenceDiscoverer* _ref_discoverer;
 
  protected:
-  ExtendedOopClosure(ReferenceProcessor* rp) : _ref_processor(rp) { }
-  ExtendedOopClosure() : _ref_processor(NULL) { }
+  ExtendedOopClosure(ReferenceDiscoverer* rd) : _ref_discoverer(rd) { }
+  ExtendedOopClosure() : _ref_discoverer(NULL) { }
   ~ExtendedOopClosure() { }
 
-  void set_ref_processor_internal(ReferenceProcessor* rp) { _ref_processor = rp; }
+  void set_ref_discoverer_internal(ReferenceDiscoverer* rd) { _ref_discoverer = rd; }
 
  public:
-  ReferenceProcessor* ref_processor() const { return _ref_processor; }
+  ReferenceDiscoverer* ref_discoverer() const { return _ref_discoverer; }
 
   // Iteration of InstanceRefKlasses differ depending on the closure,
   // the below enum describes the different alternatives.
@@ -165,7 +165,7 @@
 
  public:
   MetadataAwareOopClosure() : ExtendedOopClosure() { }
-  MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) { }
+  MetadataAwareOopClosure(ReferenceDiscoverer* rd) : ExtendedOopClosure(rd) { }
 
   bool do_metadata_nv()      { return true; }
   virtual bool do_metadata() { return do_metadata_nv(); }
--- a/src/hotspot/share/memory/metaspace.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -3378,6 +3378,7 @@
 }
 
 MetaWord* SpaceManager::grow_and_allocate(size_t word_size) {
+  assert_lock_strong(_lock);
   assert(vs_list()->current_virtual_space() != NULL,
          "Should have been set");
   assert(current_chunk() == NULL ||
@@ -3553,6 +3554,7 @@
 // Adds a chunk to the list of chunks in use.
 void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
 
+  assert_lock_strong(_lock);
   assert(new_chunk != NULL, "Should not be NULL");
   assert(new_chunk->next() == NULL, "Should not be on a list");
 
--- a/src/hotspot/share/memory/universe.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/memory/universe.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -46,6 +46,7 @@
 #include "memory/filemap.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceCounters.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -785,6 +786,7 @@
       // Did reserve heap below 32Gb. Can use base == 0;
       Universe::set_narrow_oop_base(0);
     }
+    AOTLoader::set_narrow_oop_shift();
 
     Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
 
--- a/src/hotspot/share/oops/compiledICHolder.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/compiledICHolder.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -74,12 +74,12 @@
   CompiledICHolder* next()     { return _next; }
   void set_next(CompiledICHolder* n) { _next = n; }
 
-  inline bool is_loader_alive(BoolObjectClosure* is_alive) {
+  inline bool is_loader_alive() {
     Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata;
-    if (!k->is_loader_alive(is_alive)) {
+    if (!k->is_loader_alive()) {
       return false;
     }
-    if (!_holder_klass->is_loader_alive(is_alive)) {
+    if (!_holder_klass->is_loader_alive()) {
       return false;
     }
     return true;
--- a/src/hotspot/share/oops/constantPool.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_CONSTANTPOOL_INLINE_HPP
 
 #include "oops/constantPool.hpp"
+#include "oops/cpCache.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 inline CPSlot ConstantPool::slot_at(int which) const {
--- a/src/hotspot/share/oops/cpCache.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/cpCache.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -453,7 +453,7 @@
   oop  archived_references() NOT_CDS_JAVA_HEAP_RETURN_(NULL);
   void set_archived_references(oop o) NOT_CDS_JAVA_HEAP_RETURN;
 
-  oop resolved_references()                 { return _resolved_references.resolve(); }
+  inline oop resolved_references();
   void set_resolved_references(OopHandle s) { _resolved_references = s; }
   Array<u2>* reference_map() const        { return _reference_map; }
   void set_reference_map(Array<u2>* o)    { _reference_map = o; }
--- a/src/hotspot/share/oops/cpCache.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/cpCache.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
 
 #include "oops/cpCache.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 inline int ConstantPoolCacheEntry::indices_ord() const { return OrderAccess::load_acquire(&_indices); }
@@ -96,4 +97,6 @@
   }
 }
 
+inline oop ConstantPoolCache::resolved_references() { return _resolved_references.resolve(); }
+
 #endif // SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
--- a/src/hotspot/share/oops/instanceKlass.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -28,6 +28,7 @@
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -1891,22 +1892,22 @@
 }
 #endif //PRODUCT
 
-void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
-  clean_implementors_list(is_alive);
-  clean_method_data(is_alive);
+void InstanceKlass::clean_weak_instanceklass_links() {
+  clean_implementors_list();
+  clean_method_data();
 
   // Since GC iterates InstanceKlasses sequentially, it is safe to remove stale entries here.
   DependencyContext dep_context(&_dep_context);
   dep_context.expunge_stale_entries();
 }
 
-void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
-  assert(class_loader_data()->is_alive(), "this klass should be live");
+void InstanceKlass::clean_implementors_list() {
+  assert(is_loader_alive(), "this klass should be live");
   if (is_interface()) {
     if (ClassUnloading) {
       Klass* impl = implementor();
       if (impl != NULL) {
-        if (!impl->is_loader_alive(is_alive)) {
+        if (!impl->is_loader_alive()) {
           // remove this guy
           Klass** klass = adr_implementor();
           assert(klass != NULL, "null klass");
@@ -1919,11 +1920,11 @@
   }
 }
 
-void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) {
+void InstanceKlass::clean_method_data() {
   for (int m = 0; m < methods()->length(); m++) {
     MethodData* mdo = methods()->at(m)->method_data();
     if (mdo != NULL) {
-      mdo->clean_method_data(is_alive);
+      mdo->clean_method_data(/*always_clean*/false);
     }
   }
 }
--- a/src/hotspot/share/oops/instanceKlass.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1148,9 +1148,9 @@
   void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
-  void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
-  void clean_implementors_list(BoolObjectClosure* is_alive);
-  void clean_method_data(BoolObjectClosure* is_alive);
+  void clean_weak_instanceklass_links();
+  void clean_implementors_list();
+  void clean_method_data();
 
   // Explicit metaspace deallocation of fields
   // For RedefineClasses and class file parsing errors, we need to deallocate
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -63,14 +63,14 @@
 
 template <typename T, class OopClosureType>
 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
-  ReferenceProcessor* rp = closure->ref_processor();
-  if (rp != NULL) {
+  ReferenceDiscoverer* rd = closure->ref_discoverer();
+  if (rd != NULL) {
     T referent_oop = RawAccess<>::oop_load((T*)java_lang_ref_Reference::referent_addr_raw(obj));
     if (!CompressedOops::is_null(referent_oop)) {
       oop referent = CompressedOops::decode_not_null(referent_oop);
       if (!referent->is_gc_marked()) {
         // Only try to discover if not yet marked.
-        return rp->discover_reference(obj, type);
+        return rd->discover_reference(obj, type);
       }
     }
   }
--- a/src/hotspot/share/oops/klass.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/klass.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/dictionary.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -39,6 +40,7 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
@@ -380,22 +382,7 @@
   debug_only(verify();)
 }
 
-bool Klass::is_loader_alive(BoolObjectClosure* is_alive) {
-#ifdef ASSERT
-  // The class is alive iff the class loader is alive.
-  oop loader = class_loader();
-  bool loader_alive = (loader == NULL) || is_alive->do_object_b(loader);
-#endif // ASSERT
-
-  // The class is alive if it's mirror is alive (which should be marked if the
-  // loader is alive) unless it's an anoymous class.
-  bool mirror_alive = is_alive->do_object_b(java_mirror());
-  assert(!mirror_alive || loader_alive, "loader must be alive if the mirror is"
-                        " but not the other way around with anonymous classes");
-  return mirror_alive;
-}
-
-void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses) {
+void Klass::clean_weak_klass_links(bool clean_alive_klasses) {
   if (!ClassUnloading) {
     return;
   }
@@ -407,11 +394,11 @@
   while (!stack.is_empty()) {
     Klass* current = stack.pop();
 
-    assert(current->is_loader_alive(is_alive), "just checking, this should be live");
+    assert(current->is_loader_alive(), "just checking, this should be live");
 
     // Find and set the first alive subklass
     Klass* sub = current->subklass();
-    while (sub != NULL && !sub->is_loader_alive(is_alive)) {
+    while (sub != NULL && !sub->is_loader_alive()) {
 #ifndef PRODUCT
       if (log_is_enabled(Trace, class, unload)) {
         ResourceMark rm;
@@ -427,7 +414,7 @@
 
     // Find and set the first alive sibling
     Klass* sibling = current->next_sibling();
-    while (sibling != NULL && !sibling->is_loader_alive(is_alive)) {
+    while (sibling != NULL && !sibling->is_loader_alive()) {
       if (log_is_enabled(Trace, class, unload)) {
         ResourceMark rm;
         log_trace(class, unload)("[Unlinking class (sibling) %s]", sibling->external_name());
@@ -442,12 +429,12 @@
     // Clean the implementors list and method data.
     if (clean_alive_klasses && current->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(current);
-      ik->clean_weak_instanceklass_links(is_alive);
+      ik->clean_weak_instanceklass_links();
 
       // JVMTI RedefineClasses creates previous versions that are not in
       // the class hierarchy, so process them here.
       while ((ik = ik->previous_versions()) != NULL) {
-        ik->clean_weak_instanceklass_links(is_alive);
+        ik->clean_weak_instanceklass_links();
       }
     }
   }
--- a/src/hotspot/share/oops/klass.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/klass.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_OOPS_KLASS_HPP
 #define SHARE_VM_OOPS_KLASS_HPP
 
+#include "classfile/classLoaderData.hpp"
 #include "gc/shared/specialized_oop_closures.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
@@ -52,7 +53,6 @@
 // Forward declarations.
 template <class T> class Array;
 template <class T> class GrowableArray;
-class ClassLoaderData;
 class fieldDescriptor;
 class KlassSizeStats;
 class klassVtable;
@@ -634,13 +634,12 @@
   virtual MetaspaceObj::Type type() const { return ClassType; }
 
   // Iff the class loader (or mirror for anonymous classes) is alive the
-  // Klass is considered alive.
-  // The is_alive closure passed in depends on the Garbage Collector used.
-  bool is_loader_alive(BoolObjectClosure* is_alive);
+  // Klass is considered alive.  Has already been marked as unloading.
+  bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }
 
-  static void clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses = true);
-  static void clean_subklass_tree(BoolObjectClosure* is_alive) {
-    clean_weak_klass_links(is_alive, false /* clean_alive_klasses */);
+  static void clean_weak_klass_links(bool clean_alive_klasses = true);
+  static void clean_subklass_tree() {
+    clean_weak_klass_links(false /* clean_alive_klasses */);
   }
 
   // GC specific object visitors
--- a/src/hotspot/share/oops/methodData.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/methodData.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -71,9 +71,9 @@
   }
 }
 
-void DataLayout::clean_weak_klass_links(BoolObjectClosure* cl) {
+void DataLayout::clean_weak_klass_links(bool always_clean) {
   ResourceMark m;
-  data_in()->clean_weak_klass_links(cl);
+  data_in()->clean_weak_klass_links(always_clean);
 }
 
 
@@ -315,23 +315,20 @@
   }
 }
 
-bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) {
-  Klass* k = (Klass*)klass_part(p);
-  return k != NULL && k->is_loader_alive(is_alive_cl);
-}
-
-void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void TypeStackSlotEntries::clean_weak_klass_links(bool always_clean) {
   for (int i = 0; i < _number_of_entries; i++) {
     intptr_t p = type(i);
-    if (!is_loader_alive(is_alive_cl, p)) {
+    Klass* k = (Klass*)klass_part(p);
+    if (k != NULL && (always_clean || !k->is_loader_alive())) {
       set_type(i, with_status((Klass*)NULL, p));
     }
   }
 }
 
-void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void ReturnTypeEntry::clean_weak_klass_links(bool always_clean) {
   intptr_t p = type();
-  if (!is_loader_alive(is_alive_cl, p)) {
+  Klass* k = (Klass*)klass_part(p);
+  if (k != NULL && (always_clean || !k->is_loader_alive())) {
     set_type(with_status((Klass*)NULL, p));
   }
 }
@@ -408,21 +405,21 @@
 // that the check is reached, and a series of (Klass*, count) pairs
 // which are used to store a type profile for the receiver of the check.
 
-void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void ReceiverTypeData::clean_weak_klass_links(bool always_clean) {
     for (uint row = 0; row < row_limit(); row++) {
     Klass* p = receiver(row);
-    if (p != NULL && !p->is_loader_alive(is_alive_cl)) {
+    if (p != NULL && (always_clean || !p->is_loader_alive())) {
       clear_row(row);
     }
   }
 }
 
 #if INCLUDE_JVMCI
-void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
-  ReceiverTypeData::clean_weak_klass_links(is_alive_cl);
+void VirtualCallData::clean_weak_klass_links(bool always_clean) {
+  ReceiverTypeData::clean_weak_klass_links(always_clean);
   for (uint row = 0; row < method_row_limit(); row++) {
     Method* p = method(row);
-    if (p != NULL && !p->method_holder()->is_loader_alive(is_alive_cl)) {
+    if (p != NULL && (always_clean || !p->method_holder()->is_loader_alive())) {
       clear_method_row(row);
     }
   }
@@ -1669,12 +1666,11 @@
 
 // Check for entries that reference an unloaded method
 class CleanExtraDataKlassClosure : public CleanExtraDataClosure {
-private:
-  BoolObjectClosure* _is_alive;
+  bool _always_clean;
 public:
-  CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {}
+  CleanExtraDataKlassClosure(bool always_clean) : _always_clean(always_clean) {}
   bool is_live(Method* m) {
-    return m->method_holder()->is_loader_alive(_is_alive);
+    return !(_always_clean) && m->method_holder()->is_loader_alive();
   }
 };
 
@@ -1757,19 +1753,19 @@
 #endif
 }
 
-void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
+void MethodData::clean_method_data(bool always_clean) {
   ResourceMark rm;
   for (ProfileData* data = first_data();
        is_valid(data);
        data = next_data(data)) {
-    data->clean_weak_klass_links(is_alive);
+    data->clean_weak_klass_links(always_clean);
   }
   ParametersTypeData* parameters = parameters_type_data();
   if (parameters != NULL) {
-    parameters->clean_weak_klass_links(is_alive);
+    parameters->clean_weak_klass_links(always_clean);
   }
 
-  CleanExtraDataKlassClosure cl(is_alive);
+  CleanExtraDataKlassClosure cl(always_clean);
   clean_extra_data(&cl);
   verify_extra_data_clean(&cl);
 }
--- a/src/hotspot/share/oops/methodData.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/methodData.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -30,6 +30,7 @@
 #include "oops/metadata.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.hpp"
+#include "runtime/atomic.hpp"
 #include "utilities/align.hpp"
 #if INCLUDE_JVMCI
 #include "jvmci/jvmci_globals.hpp"
@@ -253,7 +254,7 @@
   ProfileData* data_in();
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* cl);
+  void clean_weak_klass_links(bool always_clean);
 
   // Redefinition support
   void clean_weak_method_links();
@@ -504,7 +505,7 @@
   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {}
+  virtual void clean_weak_klass_links(bool always_clean) {}
 
   // Redefinition support
   virtual void clean_weak_method_links() {}
@@ -819,9 +820,6 @@
 
   static void print_klass(outputStream* st, intptr_t k);
 
-  // GC support
-  static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p);
-
 protected:
   // ProfileData object these entries are part of
   ProfileData* _pd;
@@ -929,7 +927,7 @@
   }
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  void clean_weak_klass_links(bool always_clean);
 
   void print_data_on(outputStream* st) const;
 };
@@ -972,7 +970,7 @@
   }
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  void clean_weak_klass_links(bool always_clean);
 
   void print_data_on(outputStream* st) const;
 };
@@ -1156,12 +1154,12 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
+  virtual void clean_weak_klass_links(bool always_clean) {
     if (has_arguments()) {
-      _args.clean_weak_klass_links(is_alive_closure);
+      _args.clean_weak_klass_links(always_clean);
     }
     if (has_return()) {
-      _ret.clean_weak_klass_links(is_alive_closure);
+      _ret.clean_weak_klass_links(always_clean);
     }
   }
 
@@ -1302,7 +1300,7 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean);
 
 #ifdef CC_INTERP
   static int receiver_type_data_size_in_bytes() {
@@ -1432,7 +1430,7 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean);
 
   // Redefinition support
   virtual void clean_weak_method_links();
@@ -1561,13 +1559,13 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
-    ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean) {
+    ReceiverTypeData::clean_weak_klass_links(always_clean);
     if (has_arguments()) {
-      _args.clean_weak_klass_links(is_alive_closure);
+      _args.clean_weak_klass_links(always_clean);
     }
     if (has_return()) {
-      _ret.clean_weak_klass_links(is_alive_closure);
+      _ret.clean_weak_klass_links(always_clean);
     }
   }
 
@@ -2020,8 +2018,8 @@
     _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current));
   }
 
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
-    _parameters.clean_weak_klass_links(is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean) {
+    _parameters.clean_weak_klass_links(always_clean);
   }
 
   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
@@ -2609,7 +2607,7 @@
   static bool profile_parameters();
   static bool profile_return_jsr292_only();
 
-  void clean_method_data(BoolObjectClosure* is_alive);
+  void clean_method_data(bool always_clean);
   void clean_weak_method_links();
   DEBUG_ONLY(void verify_clean_weak_method_links();)
   Mutex* extra_data_lock() { return &_extra_data_lock; }
--- a/src/hotspot/share/oops/oop.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/oop.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -122,10 +122,9 @@
 
 // used only for asserts and guarantees
 bool oopDesc::is_oop(oop obj, bool ignore_mark_word) {
-  if (!check_obj_alignment(obj)) return false;
-  if (!Universe::heap()->is_in_reserved(obj)) return false;
-  // obj is aligned and accessible in heap
-  if (Universe::heap()->is_in_reserved(obj->klass_or_null())) return false;
+  if (!Universe::heap()->is_oop(obj)) {
+    return false;
+  }
 
   // Header verification: the mark is typically non-NULL. If we're
   // at a safepoint, it must not be null.
--- a/src/hotspot/share/oops/oopHandle.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/oopHandle.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
 #define SHARE_VM_OOPS_OOPHANDLE_HPP
 
 #include "oops/oop.hpp"
-#include "runtime/atomic.hpp"
-#include "runtime/orderAccess.hpp"
 
 // Simple class for encapsulating oop pointers stored in metadata.
 // These are different from Handle.  The Handle class stores pointers
@@ -45,10 +43,10 @@
   OopHandle() : _obj(NULL) {}
   OopHandle(oop* w) : _obj(w) {}
 
-  oop resolve() const { return (_obj == NULL) ? (oop)NULL : *_obj; }
+  inline oop resolve() const;
 
   // Used only for removing handle.
-  oop* ptr_raw() { return _obj; }
+  oop* ptr_raw() const { return _obj; }
 };
 
 #endif // SHARE_VM_OOPS_OOPHANDLE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/oopHandle.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+#define SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+
+#include "oops/access.inline.hpp"
+#include "oops/oopHandle.hpp"
+
+inline oop OopHandle::resolve() const {
+  return (_obj == NULL) ? (oop)NULL : RootAccess<IN_CONCURRENT_ROOT>::oop_load(_obj);
+}
+
+#endif //  SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+
--- a/src/hotspot/share/oops/weakHandle.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/weakHandle.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -51,8 +51,8 @@
 void WeakHandle<T>::release() const {
   // Only release if the pointer to the object has been created.
   if (_obj != NULL) {
-    // Clear the WeakHandle.  For class loader data race, the handle may not have
-    // been previously cleared by GC.
+    // Clear the WeakHandle.  For race in creating ClassLoaderData, we can release this
+    // WeakHandle before it is cleared by GC.
     RootAccess<ON_PHANTOM_OOP_REF>::oop_store(_obj, (oop)NULL);
     get_storage()->release(_obj);
   }
--- a/src/hotspot/share/oops/weakHandle.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/oops/weakHandle.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -63,4 +63,6 @@
   void print_on(outputStream* st) const;
 };
 
+typedef WeakHandle<vm_class_loader_data> ClassLoaderWeakHandle;
+
 #endif // SHARE_VM_OOPS_WEAKHANDLE_HPP
--- a/src/hotspot/share/opto/library_call.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/opto/library_call.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -3488,6 +3488,7 @@
 Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
   Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
   Node* load = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
+  // mirror = ((OopHandle)mirror)->resolve();
   return make_load(NULL, load, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
 }
 
--- a/src/hotspot/share/opto/memnode.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/opto/memnode.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -2215,12 +2215,16 @@
   // mirror go completely dead.  (Current exception:  Class
   // mirrors may appear in debug info, but we could clean them out by
   // introducing a new debug info operator for Klass.java_mirror).
+  //
+  // If the code pattern requires a barrier for
+  //   mirror = ((OopHandle)mirror)->resolve();
+  // this won't match.
 
   if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
       && offset == java_lang_Class::klass_offset_in_bytes()) {
     if (base->is_Load()) {
       Node* base2 = base->in(MemNode::Address);
-      if (base2->is_Load()) { /* direct load of a load which is the oophandle */
+      if (base2->is_Load()) { /* direct load of a load which is the OopHandle */
         Node* adr2 = base2->in(MemNode::Address);
         const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
         if (tkls != NULL && !tkls->empty()
--- a/src/hotspot/share/opto/phaseX.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/opto/phaseX.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1628,8 +1628,11 @@
       Node* imem = use->as_Initialize()->proj_out_or_null(TypeFunc::Memory);
       if (imem != NULL)  add_users_to_worklist0(imem);
     }
-    // Loading the java mirror from a klass oop requires two loads and the type
+    // Loading the java mirror from a Klass requires two loads and the type
     // of the mirror load depends on the type of 'n'. See LoadNode::Value().
+    // If the code pattern requires a barrier for
+    //   mirror = ((OopHandle)mirror)->resolve();
+    // this won't match.
     if (use_op == Op_LoadP && use->bottom_type()->isa_rawptr()) {
       for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
         Node* u = use->fast_out(i2);
@@ -1774,8 +1777,11 @@
             worklist.push(phi);
           }
         }
-        // Loading the java mirror from a klass oop requires two loads and the type
+        // Loading the java mirror from a Klass requires two loads and the type
         // of the mirror load depends on the type of 'n'. See LoadNode::Value().
+        // If the code pattern requires a barrier for
+        //   mirror = ((OopHandle)mirror)->resolve();
+        // this won't match.
         if (m_op == Op_LoadP && m->bottom_type()->isa_rawptr()) {
           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
             Node* u = m->fast_out(i2);
--- a/src/hotspot/share/opto/subnode.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/opto/subnode.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -886,7 +886,7 @@
   if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
 
   Node* adr = n->in(MemNode::Address);
-  // First load from OopHandle
+  // First load from OopHandle: ((OopHandle)mirror)->resolve(); may need barrier.
   if (adr->Opcode() != Op_LoadP || !phase->type(adr)->isa_rawptr()) return NULL;
   adr = adr->in(MemNode::Address);
 
--- a/src/hotspot/share/prims/jvm.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/jvm.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -2768,15 +2768,14 @@
   return len;
 }
 
-
 // HotSpot specific jio method
-void jio_print(const char* s) {
+void jio_print(const char* s, size_t len) {
   // Try to make this function as atomic as possible.
   if (Arguments::vfprintf_hook() != NULL) {
-    jio_fprintf(defaultStream::output_stream(), "%s", s);
+    jio_fprintf(defaultStream::output_stream(), "%.*s", (int)len, s);
   } else {
     // Make an unused local variable to avoid warning from gcc 4.x compiler.
-    size_t count = ::write(defaultStream::output_fd(), s, (int)strlen(s));
+    size_t count = ::write(defaultStream::output_fd(), s, (int)len);
   }
 }
 
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -29,6 +29,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "prims/jvmtiEnvBase.hpp"
 #include "prims/jvmtiEventController.inline.hpp"
 #include "prims/jvmtiExtensions.hpp"
@@ -1478,6 +1479,13 @@
 
 GrowableArray<OopHandle>* JvmtiModuleClosure::_tbl = NULL;
 
+void JvmtiModuleClosure::do_module(ModuleEntry* entry) {
+  assert_locked_or_safepoint(Module_lock);
+  OopHandle module = entry->module_handle();
+  guarantee(module.resolve() != NULL, "module object is NULL");
+  _tbl->push(module);
+}
+
 jvmtiError
 JvmtiModuleClosure::get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr) {
   ResourceMark rm;
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -639,13 +639,7 @@
 private:
   static GrowableArray<OopHandle> *_tbl; // Protected with Module_lock
 
-  static void do_module(ModuleEntry* entry) {
-    assert_locked_or_safepoint(Module_lock);
-    OopHandle module = entry->module_handle();
-    guarantee(module.resolve() != NULL, "module object is NULL");
-    _tbl->push(module);
-  }
-
+  static void do_module(ModuleEntry* entry);
 public:
   jvmtiError get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr);
 };
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "memory/universe.hpp"
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -30,6 +30,7 @@
 #include "oops/oop.inline.hpp"
 #include "oops/method.hpp"
 #include "oops/symbol.hpp"
+#include "oops/weakHandle.inline.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/mutexLocker.hpp"
@@ -39,7 +40,7 @@
 
 
 oop ResolvedMethodEntry::object() {
-  return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(literal_addr());
+  return literal().resolve();
 }
 
 oop ResolvedMethodEntry::object_no_keepalive() {
@@ -48,11 +49,11 @@
   // not leak out past a thread transition where a safepoint can happen.
   // A subsequent oop_load without AS_NO_KEEPALIVE (the object() accessor)
   // keeps the oop alive before doing so.
-  return RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(literal_addr());
+  return literal().peek();
 }
 
 ResolvedMethodTable::ResolvedMethodTable()
-  : Hashtable<oop, mtClass>(_table_size, sizeof(ResolvedMethodEntry)) { }
+  : Hashtable<ClassLoaderWeakHandle, mtClass>(_table_size, sizeof(ResolvedMethodEntry)) { }
 
 oop ResolvedMethodTable::lookup(int index, unsigned int hash, Method* method) {
   for (ResolvedMethodEntry* p = bucket(index); p != NULL; p = p->next()) {
@@ -62,7 +63,7 @@
       oop target = p->object_no_keepalive();
 
       // The method is in the table as a target already
-      if (java_lang_invoke_ResolvedMethodName::vmtarget(target) == method) {
+      if (target != NULL && java_lang_invoke_ResolvedMethodName::vmtarget(target) == method) {
         ResourceMark rm;
         log_debug(membername, table) ("ResolvedMethod entry found for %s index %d",
                                        method->name_and_sig_as_C_string(), index);
@@ -88,7 +89,7 @@
   return lookup(index, hash, method);
 }
 
-oop ResolvedMethodTable::basic_add(Method* method, oop rmethod_name) {
+oop ResolvedMethodTable::basic_add(Method* method, Handle rmethod_name) {
   assert_locked_or_safepoint(ResolvedMethodTable_lock);
 
   unsigned int hash = compute_hash(method);
@@ -100,12 +101,13 @@
     return entry;
   }
 
-  ResolvedMethodEntry* p = (ResolvedMethodEntry*) Hashtable<oop, mtClass>::new_entry(hash, rmethod_name);
-  Hashtable<oop, mtClass>::add_entry(index, p);
+  ClassLoaderWeakHandle w = ClassLoaderWeakHandle::create(rmethod_name);
+  ResolvedMethodEntry* p = (ResolvedMethodEntry*) Hashtable<ClassLoaderWeakHandle, mtClass>::new_entry(hash, w);
+  Hashtable<ClassLoaderWeakHandle, mtClass>::add_entry(index, p);
   ResourceMark rm;
   log_debug(membername, table) ("ResolvedMethod entry added for %s index %d",
                                  method->name_and_sig_as_C_string(), index);
-  return rmethod_name;
+  return rmethod_name();
 }
 
 ResolvedMethodTable* ResolvedMethodTable::_the_table = NULL;
@@ -134,7 +136,7 @@
   // have any membernames in the table.
   method->method_holder()->set_has_resolved_methods();
 
-  return _the_table->basic_add(method, resolved_method_name());
+  return _the_table->basic_add(method, resolved_method_name);
 }
 
 // Removing entries
@@ -143,7 +145,7 @@
 
 // Serially invoke removed unused oops from the table.
 // This is done late during GC.
-void ResolvedMethodTable::unlink(BoolObjectClosure* is_alive) {
+void ResolvedMethodTable::unlink() {
   _oops_removed = 0;
   _oops_counted = 0;
   for (int i = 0; i < _the_table->table_size(); ++i) {
@@ -151,38 +153,27 @@
     ResolvedMethodEntry* entry = _the_table->bucket(i);
     while (entry != NULL) {
       _oops_counted++;
-      if (is_alive->do_object_b(entry->object_no_keepalive())) {
+      oop l = entry->object_no_keepalive();
+      if (l != NULL) {
         p = entry->next_addr();
       } else {
+        // Entry has been removed.
         _oops_removed++;
         if (log_is_enabled(Debug, membername, table)) {
-          Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(entry->object_no_keepalive());
-          ResourceMark rm;
-          log_debug(membername, table) ("ResolvedMethod entry removed for %s index %d",
-                                           m->name_and_sig_as_C_string(), i);
+          log_debug(membername, table) ("ResolvedMethod entry removed for index %d", i);
         }
+        entry->literal().release();
         *p = entry->next();
         _the_table->free_entry(entry);
       }
       // get next entry
-      entry = (ResolvedMethodEntry*)HashtableEntry<oop, mtClass>::make_ptr(*p);
+      entry = (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::make_ptr(*p);
     }
   }
   log_debug(membername, table) ("ResolvedMethod entries counted %d removed %d",
                                 _oops_counted, _oops_removed);
 }
 
-// Serially invoke "f->do_oop" on the locations of all oops in the table.
-void ResolvedMethodTable::oops_do(OopClosure* f) {
-  for (int i = 0; i < _the_table->table_size(); ++i) {
-    ResolvedMethodEntry* entry = _the_table->bucket(i);
-    while (entry != NULL) {
-      f->do_oop(entry->literal_addr());
-      entry = entry->next();
-    }
-  }
-}
-
 #ifndef PRODUCT
 void ResolvedMethodTable::print() {
   for (int i = 0; i < table_size(); ++i) {
@@ -190,9 +181,11 @@
     while (entry != NULL) {
       tty->print("%d : ", i);
       oop rmethod_name = entry->object_no_keepalive();
-      rmethod_name->print();
-      Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name);
-      m->print();
+      if (rmethod_name != NULL) {
+        rmethod_name->print();
+        Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name);
+        m->print();
+      }
       entry = entry->next();
     }
   }
@@ -205,9 +198,15 @@
   assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
   // For each entry in RMT, change to new method
   for (int i = 0; i < _the_table->table_size(); ++i) {
-    ResolvedMethodEntry* entry = _the_table->bucket(i);
-    while (entry != NULL) {
+    for (ResolvedMethodEntry* entry = _the_table->bucket(i);
+         entry != NULL;
+         entry = entry->next()) {
+
       oop mem_name = entry->object_no_keepalive();
+      // except ones removed
+      if (mem_name == NULL) {
+        continue;
+      }
       Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
 
       if (old_method->is_old()) {
@@ -235,7 +234,6 @@
           ("ResolvedMethod method update: %s(%s)",
            new_method->name()->as_C_string(), new_method->signature()->as_C_string());
       }
-      entry = entry->next();
     }
   }
 }
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/resolvedMethodTable.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,22 +26,23 @@
 #define SHARE_VM_PRIMS_RESOLVEDMETHOD_HPP
 
 #include "oops/symbol.hpp"
+#include "oops/weakHandle.hpp"
 #include "utilities/hashtable.hpp"
 
 // Hashtable to record Method* used in ResolvedMethods, via. ResolvedMethod oops.
 // This is needed for redefinition to replace Method* with redefined versions.
 
-// Entry in a ResolvedMethodTable, mapping a single oop of java_lang_invoke_ResolvedMethodName which
-// holds JVM Method* in vmtarget.
+// Entry in a ResolvedMethodTable, mapping a ClassLoaderWeakHandle for a single oop of
+// java_lang_invoke_ResolvedMethodName which holds JVM Method* in vmtarget.
 
-class ResolvedMethodEntry : public HashtableEntry<oop, mtClass> {
+class ResolvedMethodEntry : public HashtableEntry<ClassLoaderWeakHandle, mtClass> {
  public:
   ResolvedMethodEntry* next() const {
-    return (ResolvedMethodEntry*)HashtableEntry<oop, mtClass>::next();
+    return (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next();
   }
 
   ResolvedMethodEntry** next_addr() {
-    return (ResolvedMethodEntry**)HashtableEntry<oop, mtClass>::next_addr();
+    return (ResolvedMethodEntry**)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next_addr();
   }
 
   oop object();
@@ -50,7 +51,7 @@
   void print_on(outputStream* st) const;
 };
 
-class ResolvedMethodTable : public Hashtable<oop, mtClass> {
+class ResolvedMethodTable : public Hashtable<ClassLoaderWeakHandle, mtClass> {
   enum Constants {
     _table_size  = 1007
   };
@@ -61,11 +62,11 @@
   static ResolvedMethodTable* _the_table;
 private:
   ResolvedMethodEntry* bucket(int i) {
-    return (ResolvedMethodEntry*) Hashtable<oop, mtClass>::bucket(i);
+    return (ResolvedMethodEntry*) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket(i);
   }
 
   ResolvedMethodEntry** bucket_addr(int i) {
-    return (ResolvedMethodEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
+    return (ResolvedMethodEntry**) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket_addr(i);
   }
 
   unsigned int compute_hash(Method* method);
@@ -75,7 +76,7 @@
   oop lookup(Method* method);
 
   // must be done under ResolvedMethodTable_lock
-  oop basic_add(Method* method, oop rmethod_name);
+  oop basic_add(Method* method, Handle rmethod_name);
 
 public:
   ResolvedMethodTable();
@@ -95,8 +96,7 @@
 #endif // INCLUDE_JVMTI
 
   // Cleanup cleared entries
-  static void unlink(BoolObjectClosure* is_alive);
-  static void oops_do(OopClosure* f);
+  static void unlink();
 
 #ifndef PRODUCT
   void print();
--- a/src/hotspot/share/prims/whitebox.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -933,8 +933,6 @@
   return result;
 WB_END
 
-static AlwaysFalseClosure always_false;
-
 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION(env);
@@ -951,7 +949,7 @@
       mdo->set_arg_modified(i, 0);
     }
     MutexLockerEx mu(mdo->extra_data_lock());
-    mdo->clean_method_data(&always_false);
+    mdo->clean_method_data(/*always_clean*/true);
   }
 
   mh->clear_not_c1_compilable();
--- a/src/hotspot/share/runtime/arguments.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1820,18 +1820,6 @@
 
   GCConfig::initialize();
 
-#if COMPILER2_OR_JVMCI
-  // Shared spaces work fine with other GCs but causes bytecode rewriting
-  // to be disabled, which hurts interpreter performance and decreases
-  // server performance.  When -server is specified, keep the default off
-  // unless it is asked for.  Future work: either add bytecode rewriting
-  // at link time, or rewrite bytecodes in non-shared methods.
-  if (is_server_compilation_mode_vm() && !DumpSharedSpaces && !RequireSharedSpaces &&
-      (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
-    no_shared_spaces("COMPILER2 default: -Xshare:auto | off, have to manually setup to on.");
-  }
-#endif
-
 #if defined(IA32)
   // Only server compiler can optimize safepoints well enough.
   if (!is_server_compilation_mode_vm()) {
--- a/src/hotspot/share/runtime/globals.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/globals.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1486,6 +1486,20 @@
           range(0, max_jint)                                                \
           constraint(CICompilerCountConstraintFunc, AfterErgo)              \
                                                                             \
+  product(bool, UseDynamicNumberOfCompilerThreads, true,                    \
+          "Dynamically choose the number of parallel compiler threads")     \
+                                                                            \
+  diagnostic(bool, ReduceNumberOfCompilerThreads, true,                     \
+             "Reduce the number of parallel compiler threads when they "    \
+             "are not used")                                                \
+                                                                            \
+  diagnostic(bool, TraceCompilerThreads, false,                             \
+             "Trace creation and removal of compiler threads")              \
+                                                                            \
+  develop(bool, InjectCompilerCreationFailure, false,                       \
+          "Inject thread creation failures for "                            \
+          "UseDynamicNumberOfCompilerThreads")                              \
+                                                                            \
   product(intx, CompilationPolicyChoice, 0,                                 \
           "which compilation policy (0-3)")                                 \
           range(0, 3)                                                       \
--- a/src/hotspot/share/runtime/javaFrameAnchor.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/javaFrameAnchor.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
 #define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
 
+#include "runtime/orderAccess.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
--- a/src/hotspot/share/runtime/mutex.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/mutex.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,8 @@
        access         = event          +   1,
        special        = access         +   2,
        suspend_resume = special        +   1,
-       leaf           = suspend_resume +   2,
+       vmweak         = suspend_resume +   2,
+       leaf           = vmweak         +   2,
        safepoint      = leaf           +  10,
        barrier        = safepoint      +   1,
        nonleaf        = barrier        +   1,
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -182,6 +182,9 @@
   def(CGC_lock                     , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);      // coordinate between fore- and background GC
   def(STS_lock                     , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
 
+  def(VMWeakAlloc_lock             , PaddedMutex  , vmweak,      true,  Monitor::_safepoint_check_never);
+  def(VMWeakActive_lock            , PaddedMutex  , vmweak-1,    true,  Monitor::_safepoint_check_never);
+
   if (UseConcMarkSweepGC || UseG1GC) {
     def(FullGCCount_lock           , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
   }
@@ -262,8 +265,6 @@
   def(JNIGlobalActive_lock         , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
   def(JNIWeakAlloc_lock            , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
   def(JNIWeakActive_lock           , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
-  def(VMWeakAlloc_lock             , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
-  def(VMWeakActive_lock            , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
   def(JNICritical_lock             , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always);     // used for JNI critical regions
   def(AdapterHandlerLibrary_lock   , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
 
--- a/src/hotspot/share/runtime/safepoint.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -28,6 +28,7 @@
 #include "asm/assembler.hpp"
 #include "code/nmethod.hpp"
 #include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/extendedPC.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/runtime/thread.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/thread.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1495,7 +1495,6 @@
 jlong* JavaThread::_jvmci_old_thread_counters;
 
 bool jvmci_counters_include(JavaThread* thread) {
-  oop threadObj = thread->threadObj();
   return !JVMCICountersExcludeCompiler || !thread->is_Compiler_thread();
 }
 
@@ -3360,6 +3359,11 @@
 #endif
 }
 
+CompilerThread::~CompilerThread() {
+  // Delete objects which were allocated on heap.
+  delete _counters;
+}
+
 bool CompilerThread::can_call_java() const {
   return _compiler != NULL && _compiler->is_jvmci();
 }
--- a/src/hotspot/share/runtime/thread.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/thread.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -2029,12 +2029,14 @@
   BufferBlob*           _buffer_blob;
 
   AbstractCompiler*     _compiler;
+  TimeStamp             _idle_time;
 
  public:
 
   static CompilerThread* current();
 
   CompilerThread(CompileQueue* queue, CompilerCounters* counters);
+  ~CompilerThread();
 
   bool is_Compiler_thread() const                { return true; }
 
@@ -2064,6 +2066,11 @@
     _log = log;
   }
 
+  void start_idle_timer()                        { _idle_time.update(); }
+  jlong idle_time_millis() {
+    return TimeHelper::counter_to_millis(_idle_time.ticks_since_update());
+  }
+
 #ifndef PRODUCT
  private:
   IdealGraphPrinter *_ideal_graph_printer;
--- a/src/hotspot/share/runtime/vmStructs.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -543,7 +543,7 @@
   /*******************/                                                                                                              \
   /* ClassLoaderData */                                                                                                              \
   /*******************/                                                                                                              \
-  nonstatic_field(ClassLoaderData,             _class_loader,                                 oop)                                   \
+  nonstatic_field(ClassLoaderData,             _class_loader,                                 OopHandle)                             \
   nonstatic_field(ClassLoaderData,             _next,                                         ClassLoaderData*)                      \
   volatile_nonstatic_field(ClassLoaderData,    _klasses,                                      Klass*)                                \
   nonstatic_field(ClassLoaderData,             _is_anonymous,                                 bool)                                  \
--- a/src/hotspot/share/services/classLoadingService.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/services/classLoadingService.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,7 @@
       len = name->utf8_length();                    \
     }                                               \
     HOTSPOT_CLASS_##type( /* type = unloaded, loaded */ \
-      data, len, (void*)(clss)->class_loader(), (shared)); \
+      data, len, (void*)(clss)->class_loader_data(), (shared)); \
   }
 
 #else //  ndef DTRACE_ENABLED
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -931,7 +931,7 @@
 //---<  BEGIN  >--- CodeHeap State Analytics.
 CodeHeapAnalyticsDCmd::CodeHeapAnalyticsDCmd(outputStream* output, bool heap) :
                                              DCmdWithParser(output, heap),
-  _function("function", "Function to be performed (aggregate, UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, discard", "STRING", false, "all"),
+  _function("function", "Function to be performed (aggregate, UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, discard", "STRING", false, "all"),
   _granularity("granularity", "Detail level - smaller value -> more detail", "STRING", false, "4096") {
   _dcmdparser.add_dcmd_argument(&_function);
   _dcmdparser.add_dcmd_argument(&_granularity);
--- a/src/hotspot/share/trace/traceStream.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/trace/traceStream.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "trace/traceStream.hpp"
 #if INCLUDE_TRACE
-#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/klass.hpp"
--- a/src/hotspot/share/utilities/bitMap.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/utilities/bitMap.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,7 @@
 };
 
 template <class Allocator>
-BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits) {
+BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear) {
   size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
   size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
 
@@ -86,7 +86,7 @@
                            MIN2(old_size_in_words, new_size_in_words));
     }
 
-    if (new_size_in_words > old_size_in_words) {
+    if (clear && new_size_in_words > old_size_in_words) {
       clear_range_of_words(map, old_size_in_words, new_size_in_words);
     }
   }
@@ -99,9 +99,9 @@
 }
 
 template <class Allocator>
-bm_word_t* BitMap::allocate(const Allocator& allocator, idx_t size_in_bits) {
+bm_word_t* BitMap::allocate(const Allocator& allocator, idx_t size_in_bits, bool clear) {
   // Reuse reallocate to ensure that the new memory is cleared.
-  return reallocate(allocator, NULL, 0, size_in_bits);
+  return reallocate(allocator, NULL, 0, size_in_bits, clear);
 }
 
 template <class Allocator>
@@ -153,8 +153,8 @@
     : BitMap(allocate(ArenaBitMapAllocator(arena), size_in_bits), size_in_bits) {
 }
 
-CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags)
-    : BitMap(allocate(CHeapBitMapAllocator(flags), size_in_bits), size_in_bits), _flags(flags) {
+CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags, bool clear)
+    : BitMap(allocate(CHeapBitMapAllocator(flags), size_in_bits, clear), size_in_bits), _flags(flags) {
 }
 
 CHeapBitMap::~CHeapBitMap() {
--- a/src/hotspot/share/utilities/bitMap.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/utilities/bitMap.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -123,11 +123,11 @@
 
   // Allocates and clears the bitmap memory.
   template <class Allocator>
-  static bm_word_t* allocate(const Allocator&, idx_t size_in_bits);
+  static bm_word_t* allocate(const Allocator&, idx_t size_in_bits, bool clear = true);
 
   // Reallocates and clears the new bitmap memory.
   template <class Allocator>
-  static bm_word_t* reallocate(const Allocator&, bm_word_t* map, idx_t old_size_in_bits, idx_t new_size_in_bits);
+  static bm_word_t* reallocate(const Allocator&, bm_word_t* map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear = true);
 
   // Free the bitmap memory.
   template <class Allocator>
@@ -359,7 +359,7 @@
  public:
   CHeapBitMap(MEMFLAGS flags = mtInternal) : BitMap(NULL, 0), _flags(flags) {}
   // Clears the bitmap memory.
-  CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags = mtInternal);
+  CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags = mtInternal, bool clear = true);
   ~CHeapBitMap();
 
   // Resize the backing bitmap memory.
--- a/src/hotspot/share/utilities/globalCounter.inline.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/utilities/globalCounter.inline.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -26,7 +26,7 @@
 #define SHARE_UTILITIES_GLOBAL_COUNTER_INLINE_HPP
 
 #include "runtime/orderAccess.inline.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
 #include "utilities/globalCounter.hpp"
 
 inline void GlobalCounter::critical_section_begin(Thread *thread) {
--- a/src/hotspot/share/utilities/hashtable.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/utilities/hashtable.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/weakHandle.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/hashtable.hpp"
@@ -148,7 +149,6 @@
   }
   // give the new table the free list as well
   new_table->copy_freelist(this);
-  assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?");
 
   // Destroy memory used by the buckets in the hashtable.  The memory
   // for the elements has been used in a new table and is not
@@ -263,6 +263,10 @@
   }
 }
 
+static int literal_size(ClassLoaderWeakHandle v) {
+  return literal_size(v.peek());
+}
+
 template <MEMFLAGS F> bool BasicHashtable<F>::resize(int new_size) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
@@ -382,6 +386,13 @@
 }
 
 #ifndef PRODUCT
+template <class T> void print_literal(T l) {
+  l->print();
+}
+
+static void print_literal(ClassLoaderWeakHandle l) {
+  l.print();
+}
 
 template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
   ResourceMark rm;
@@ -390,7 +401,7 @@
     HashtableEntry<T, F>* entry = bucket(i);
     while(entry != NULL) {
       tty->print("%d : ", i);
-      entry->literal()->print();
+      print_literal(entry->literal());
       tty->cr();
       entry = entry->next();
     }
@@ -443,21 +454,19 @@
 #endif
 template class Hashtable<ConstantPool*, mtClass>;
 template class RehashableHashtable<Symbol*, mtSymbol>;
-template class RehashableHashtable<oopDesc*, mtSymbol>;
+template class RehashableHashtable<oop, mtSymbol>;
 template class Hashtable<Symbol*, mtSymbol>;
 template class Hashtable<Klass*, mtClass>;
 template class Hashtable<InstanceKlass*, mtClass>;
-template class Hashtable<oop, mtClass>;
+template class Hashtable<ClassLoaderWeakHandle, mtClass>;
 template class Hashtable<Symbol*, mtModule>;
-#if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS)
 template class Hashtable<oop, mtSymbol>;
-template class RehashableHashtable<oop, mtSymbol>;
-#endif // SOLARIS || CHECK_UNHANDLED_OOPS
-template class Hashtable<oopDesc*, mtSymbol>;
+template class Hashtable<ClassLoaderWeakHandle, mtSymbol>;
 template class Hashtable<Symbol*, mtClass>;
 template class HashtableEntry<Symbol*, mtSymbol>;
 template class HashtableEntry<Symbol*, mtClass>;
 template class HashtableEntry<oop, mtSymbol>;
+template class HashtableEntry<ClassLoaderWeakHandle, mtSymbol>;
 template class HashtableBucket<mtClass>;
 template class BasicHashtableEntry<mtSymbol>;
 template class BasicHashtableEntry<mtCode>;
--- a/src/hotspot/share/utilities/ostream.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/hotspot/share/utilities/ostream.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -36,7 +36,9 @@
 #include "utilities/vmError.hpp"
 #include "utilities/xmlstream.hpp"
 
-extern "C" void jio_print(const char* s); // Declarationtion of jvm method
+// Declarations of jvm methods
+extern "C" void jio_print(const char* s, size_t len);
+extern "C" int jio_printf(const char *fmt, ...);
 
 outputStream::outputStream(int width) {
   _width       = width;
@@ -612,19 +614,15 @@
 
   // Try again to open the file in the temp directory.
   delete file;
-  char warnbuf[O_BUFLEN*2];
-  jio_snprintf(warnbuf, sizeof(warnbuf), "Warning:  Cannot open log file: %s\n", log_name);
-  // Note:  This feature is for maintainer use only.  No need for L10N.
-  jio_print(warnbuf);
+  // Note: This feature is for maintainer use only.  No need for L10N.
+  jio_printf("Warning:  Cannot open log file: %s\n", log_name);
   try_name = make_log_name(log_name, os::get_temp_directory());
   if (try_name == NULL) {
     warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory());
     return NULL;
   }
 
-  jio_snprintf(warnbuf, sizeof(warnbuf),
-               "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
-  jio_print(warnbuf);
+  jio_printf("Warning:  Forcing option -XX:LogFile=%s\n", try_name);
 
   file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
   FREE_C_HEAP_ARRAY(char, try_name);
@@ -824,20 +822,6 @@
   tty_lock->unlock();
 }
 
-
-// Yuck:  jio_print does not accept char*/len.
-static void call_jio_print(const char* s, size_t len) {
-  char buffer[O_BUFLEN+100];
-  if (len > sizeof(buffer)-1) {
-    warning("increase O_BUFLEN in ostream.cpp -- output truncated");
-    len = sizeof(buffer)-1;
-  }
-  strncpy(buffer, s, len);
-  buffer[len] = '\0';
-  jio_print(buffer);
-}
-
-
 void defaultStream::write(const char* s, size_t len) {
   intx thread_id = os::current_thread_id();
   intx holder = hold(thread_id);
@@ -845,11 +829,7 @@
   if (DisplayVMOutput &&
       (_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) {
     // print to output stream. It can be redirected by a vfprintf hook
-    if (s[len] == '\0') {
-      jio_print(s);
-    } else {
-      call_jio_print(s, len);
-    }
+    jio_print(s, len);
   }
 
   // print to log file
--- a/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m	Tue Apr 24 10:20:22 2018 +0100
@@ -438,12 +438,11 @@
             if (passwordChars == NULL) {
                 goto errOut;
             }
-            passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
 
-            // clear the password and release
-            memset(passwordChars, 0, passwordLen);
-            (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
-                JNI_ABORT);
+            passwordStrRef = CFStringCreateWithCharactersNoCopy(NULL, passwordChars, passwordLen, kCFAllocatorNull);
+            if (passwordStrRef == NULL) {
+                goto errOut;
+            }
         }
     }
 
@@ -471,7 +470,12 @@
 errOut:
     if (exportedData) CFRelease(exportedData);
     if (passwordStrRef) CFRelease(passwordStrRef);
-
+    if (passwordChars) {
+        // clear the password and release
+        memset(passwordChars, 0, passwordLen);
+        (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
+            JNI_ABORT);
+    }
     return returnValue;
 }
 
@@ -538,12 +542,11 @@
             if (passwordChars == NULL) {
                 goto errOut;
             }
-            passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
 
-            // clear the password and release
-            memset(passwordChars, 0, passwordLen);
-            (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
-                JNI_ABORT);
+            passwordStrRef = CFStringCreateWithCharactersNoCopy(NULL, passwordChars, passwordLen, kCFAllocatorNull);
+            if (passwordStrRef == NULL) {
+                goto errOut;
+            }
         }
     }
 
@@ -581,7 +584,14 @@
         CFRelease(createdItems);
     }
 
-errOut: ;
+errOut:
+    if (passwordStrRef) CFRelease(passwordStrRef);
+    if (passwordChars) {
+        // clear the password and release
+        memset(passwordChars, 0, passwordLen);
+        (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
+            JNI_ABORT);
+    }
 
 JNF_COCOA_EXIT(env);
 
--- a/src/java.base/share/classes/java/util/Optional.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/Optional.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -160,6 +160,17 @@
     }
 
     /**
+     * If a value is  not present, returns {@code true}, otherwise
+     * {@code false}.
+     *
+     * @return  {@code true} if a value is not present, otherwise {@code false}
+     * @since   11
+     */
+    public boolean isEmpty() {
+        return value == null;
+    }
+
+    /**
      * If a value is present, performs the given action with the value,
      * otherwise does nothing.
      *
--- a/src/java.base/share/classes/java/util/OptionalDouble.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/OptionalDouble.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,6 +140,17 @@
     }
 
     /**
+     * If a value is not present, returns {@code true}, otherwise
+     * {@code false}.
+     *
+     * @return  {@code true} if a value is not present, otherwise {@code false}
+     * @since   11
+     */
+    public boolean isEmpty() {
+        return !isPresent;
+    }
+
+    /**
      * If a value is present, performs the given action with the value,
      * otherwise does nothing.
      *
--- a/src/java.base/share/classes/java/util/OptionalInt.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/OptionalInt.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,6 +140,17 @@
     }
 
     /**
+     * If a value is not present, returns {@code true}, otherwise
+     * {@code false}.
+     *
+     * @return  {@code true} if a value is not present, otherwise {@code false}
+     * @since   11
+     */
+    public boolean isEmpty() {
+        return !isPresent;
+    }
+
+    /**
      * If a value is present, performs the given action with the value,
      * otherwise does nothing.
      *
--- a/src/java.base/share/classes/java/util/OptionalLong.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/OptionalLong.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,6 +140,17 @@
     }
 
     /**
+     * If a value is not present, returns {@code true}, otherwise
+     * {@code false}.
+     *
+     * @return  {@code true} if a value is not present, otherwise {@code false}
+     * @since   11
+     */
+    public boolean isEmpty() {
+        return !isPresent;
+    }
+
+    /**
      * If a value is present, performs the given action with the value,
      * otherwise does nothing.
      *
--- a/src/java.base/share/classes/java/util/jar/Attributes.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/jar/Attributes.java	Tue Apr 24 10:20:22 2018 +0100
@@ -28,10 +28,10 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.Comparator;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import sun.util.logging.PlatformLogger;
@@ -116,7 +116,7 @@
      * @throws IllegalArgumentException if the attribute name is invalid
      */
     public String getValue(String name) {
-        return (String)get(new Attributes.Name(name));
+        return (String)get(Name.of(name));
     }
 
     /**
@@ -168,7 +168,7 @@
      * @exception IllegalArgumentException if the attribute name is invalid
      */
     public String putValue(String name, String value) {
-        return (String)put(new Name(name), value);
+        return (String)put(Name.of(name), value);
     }
 
     /**
@@ -371,7 +371,7 @@
      */
     @SuppressWarnings("deprecation")
     void read(Manifest.FastInputStream is, byte[] lbuf) throws IOException {
-        String name = null, value = null;
+        String name = null, value;
         byte[] lastline = null;
 
         int len;
@@ -447,8 +447,21 @@
      * for more information about valid attribute names and values.
      */
     public static class Name {
-        private String name;
-        private int hashCode = -1;
+        private final String name;
+        private final int hashCode;
+
+        /**
+         * Avoid allocation for common Names
+         */
+        private static final Map<String, Name> KNOWN_NAMES;
+
+        static final Name of(String name) {
+            Name n = KNOWN_NAMES.get(name);
+            if (n != null) {
+                return n;
+            }
+            return new Name(name);
+        }
 
         /**
          * Constructs a new attribute name using the given string name.
@@ -459,38 +472,33 @@
          * @exception NullPointerException if the attribute name was null
          */
         public Name(String name) {
-            if (name == null) {
-                throw new NullPointerException("name");
-            }
-            if (!isValid(name)) {
-                throw new IllegalArgumentException(name);
-            }
+            this.hashCode = hash(name);
             this.name = name.intern();
         }
 
-        private static boolean isValid(String name) {
+        // Checks the string is valid
+        private final int hash(String name) {
+            Objects.requireNonNull(name, "name");
             int len = name.length();
             if (len > 70 || len == 0) {
-                return false;
+                throw new IllegalArgumentException(name);
             }
+            // Calculate hash code case insensitively
+            int h = 0;
             for (int i = 0; i < len; i++) {
-                if (!isValid(name.charAt(i))) {
-                    return false;
+                char c = name.charAt(i);
+                if (c >= 'a' && c <= 'z') {
+                    // hashcode must be identical for upper and lower case
+                    h = h * 31 + (c - 0x20);
+                } else if ((c >= 'A' && c <= 'Z' ||
+                        c >= '0' && c <= '9' ||
+                        c == '_' || c == '-')) {
+                    h = h * 31 + c;
+                } else {
+                    throw new IllegalArgumentException(name);
                 }
             }
-            return true;
-        }
-
-        private static boolean isValid(char c) {
-            return isAlpha(c) || isDigit(c) || c == '_' || c == '-';
-        }
-
-        private static boolean isAlpha(char c) {
-            return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-        }
-
-        private static boolean isDigit(char c) {
-            return c >= '0' && c <= '9';
+            return h;
         }
 
         /**
@@ -500,9 +508,12 @@
          *         specified attribute object
          */
         public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
             if (o instanceof Name) {
-                Comparator<String> c = String.CASE_INSENSITIVE_ORDER;
-                return c.compare(name, ((Name)o).name) == 0;
+                Name other = (Name)o;
+                return other.name.equalsIgnoreCase(name);
             } else {
                 return false;
             }
@@ -512,9 +523,6 @@
          * Computes the hash value for this attribute name.
          */
         public int hashCode() {
-            if (hashCode == -1) {
-                hashCode = name.toLowerCase(Locale.ROOT).hashCode();
-            }
             return hashCode;
         }
 
@@ -573,7 +581,7 @@
          */
         public static final Name SEALED = new Name("Sealed");
 
-       /**
+        /**
          * {@code Name} object for {@code Extension-List} manifest attribute
          * used for the extension mechanism that is no longer supported.
          */
@@ -620,7 +628,7 @@
         @Deprecated
         public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id");
 
-       /**
+        /**
          * {@code Name} object for {@code Implementation-URL}
          * manifest attribute.
          *
@@ -654,5 +662,55 @@
          * @since   9
          */
         public static final Name MULTI_RELEASE = new Name("Multi-Release");
+
+        private static void addName(Map<String, Name> names, Name name) {
+            names.put(name.name, name);
+        }
+
+        static {
+            var names = new HashMap<String, Name>(64);
+            addName(names, MANIFEST_VERSION);
+            addName(names, SIGNATURE_VERSION);
+            addName(names, CONTENT_TYPE);
+            addName(names, CLASS_PATH);
+            addName(names, MAIN_CLASS);
+            addName(names, SEALED);
+            addName(names, EXTENSION_LIST);
+            addName(names, EXTENSION_NAME);
+            addName(names, IMPLEMENTATION_TITLE);
+            addName(names, IMPLEMENTATION_VERSION);
+            addName(names, IMPLEMENTATION_VENDOR);
+            addName(names, SPECIFICATION_TITLE);
+            addName(names, SPECIFICATION_VERSION);
+            addName(names, SPECIFICATION_VENDOR);
+            addName(names, MULTI_RELEASE);
+
+            // Common attributes used in MANIFEST.MF et.al; adding these has a
+            // small footprint cost, but is likely to be quickly paid for by
+            // reducing allocation when reading and parsing typical manifests
+            addName(names, new Name("Add-Exports"));
+            addName(names, new Name("Add-Opens"));
+            addName(names, new Name("Ant-Version"));
+            addName(names, new Name("Archiver-Version"));
+            addName(names, new Name("Build-Jdk"));
+            addName(names, new Name("Built-By"));
+            addName(names, new Name("Bnd-LastModified"));
+            addName(names, new Name("Bundle-Description"));
+            addName(names, new Name("Bundle-DocURL"));
+            addName(names, new Name("Bundle-License"));
+            addName(names, new Name("Bundle-ManifestVersion"));
+            addName(names, new Name("Bundle-Name"));
+            addName(names, new Name("Bundle-Vendor"));
+            addName(names, new Name("Bundle-Version"));
+            addName(names, new Name("Bundle-SymbolicName"));
+            addName(names, new Name("Created-By"));
+            addName(names, new Name("Export-Package"));
+            addName(names, new Name("Import-Package"));
+            addName(names, new Name("Name"));
+            addName(names, new Name("SHA1-Digest"));
+            addName(names, new Name("X-Compile-Source-JDK"));
+            addName(names, new Name("X-Compile-Target-JDK"));
+            KNOWN_NAMES = names;
+        }
     }
 }
--- a/src/java.base/share/classes/java/util/zip/Deflater.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/zip/Deflater.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,13 @@
 package java.util.zip;
 
 import java.lang.ref.Cleaner.Cleanable;
+import java.lang.ref.Reference;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.Objects;
+
 import jdk.internal.ref.CleanerFactory;
+import sun.nio.ch.DirectBuffer;
 
 /**
  * This class provides support for general purpose compression using the
@@ -35,8 +41,14 @@
  * protected by patents. It is fully described in the specifications at
  * the <a href="package-summary.html#package.description">java.util.zip
  * package description</a>.
- *
- * <p>The following code fragment demonstrates a trivial compression
+ * <p>
+ * This class deflates sequences of bytes into ZLIB compressed data format.
+ * The input byte sequence is provided in either byte array or byte buffer,
+ * via one of the {@code setInput()} methods. The output byte sequence is
+ * written to the output byte array or byte buffer passed to the
+ * {@code deflate()} methods.
+ * <p>
+ * The following code fragment demonstrates a trivial compression
  * and decompression of a string using {@code Deflater} and
  * {@code Inflater}.
  *
@@ -92,8 +104,9 @@
 public class Deflater {
 
     private final DeflaterZStreamRef zsRef;
-    private byte[] buf = new byte[0];
-    private int off, len;
+    private ByteBuffer input = ZipUtils.defaultBuf;
+    private byte[] inputArray;
+    private int inputPos, inputLim;
     private int level, strategy;
     private boolean setParams;
     private boolean finish, finished;
@@ -170,9 +183,14 @@
      */
     public static final int FULL_FLUSH = 3;
 
+    /**
+     * Flush mode to use at the end of output.  Can only be provided by the
+     * user by way of {@link #finish()}.
+     */
+    private static final int FINISH = 4;
+
     static {
         ZipUtils.loadLibrary();
-        initIDs();
     }
 
     /**
@@ -208,59 +226,70 @@
     }
 
     /**
-     * Sets input data for compression. This should be called whenever
-     * needsInput() returns true indicating that more input data is required.
-     * @param b the input data bytes
+     * Sets input data for compression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     * <p>
+     * @param input the input data bytes
      * @param off the start offset of the data
      * @param len the length of the data
      * @see Deflater#needsInput
      */
-    public void setInput(byte[] b, int off, int len) {
-        if (b== null) {
-            throw new NullPointerException();
-        }
-        if (off < 0 || len < 0 || off > b.length - len) {
+    public void setInput(byte[] input, int off, int len) {
+        if (off < 0 || len < 0 || off > input.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
         synchronized (zsRef) {
-            this.buf = b;
-            this.off = off;
-            this.len = len;
+            this.input = null;
+            this.inputArray = input;
+            this.inputPos = off;
+            this.inputLim = off + len;
         }
     }
 
     /**
-     * Sets input data for compression. This should be called whenever
-     * needsInput() returns true indicating that more input data is required.
-     * @param b the input data bytes
+     * Sets input data for compression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     * <p>
+     * @param input the input data bytes
      * @see Deflater#needsInput
      */
-    public void setInput(byte[] b) {
-        setInput(b, 0, b.length);
+    public void setInput(byte[] input) {
+        setInput(input, 0, input.length);
     }
 
     /**
-     * Sets preset dictionary for compression. A preset dictionary is used
-     * when the history buffer can be predetermined. When the data is later
-     * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
-     * in order to get the Adler-32 value of the dictionary required for
-     * decompression.
-     * @param b the dictionary data bytes
-     * @param off the start offset of the data
-     * @param len the length of the data
-     * @see Inflater#inflate
-     * @see Inflater#getAdler
+     * Sets input data for compression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     * <p>
+     * The given buffer's position will be advanced as deflate
+     * operations are performed, up to the buffer's limit.
+     * The input buffer may be modified (refilled) between deflate
+     * operations; doing so is equivalent to creating a new buffer
+     * and setting it with this method.
+     * <p>
+     * Modifying the input buffer's contents, position, or limit
+     * concurrently with an deflate operation will result in
+     * undefined behavior, which may include incorrect operation
+     * results or operation failure.
+     *
+     * @param input the input data bytes
+     * @see Deflater#needsInput
+     * @since 11
      */
-    public void setDictionary(byte[] b, int off, int len) {
-        if (b == null) {
-            throw new NullPointerException();
-        }
-        if (off < 0 || len < 0 || off > b.length - len) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
+    public void setInput(ByteBuffer input) {
+        Objects.requireNonNull(input);
         synchronized (zsRef) {
-            ensureOpen();
-            setDictionary(zsRef.address(), b, off, len);
+            this.input = input;
+            this.inputArray = null;
         }
     }
 
@@ -270,12 +299,69 @@
      * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
      * in order to get the Adler-32 value of the dictionary required for
      * decompression.
-     * @param b the dictionary data bytes
+     * @param dictionary the dictionary data bytes
+     * @param off the start offset of the data
+     * @param len the length of the data
+     * @see Inflater#inflate
+     * @see Inflater#getAdler
+     */
+    public void setDictionary(byte[] dictionary, int off, int len) {
+        if (off < 0 || len < 0 || off > dictionary.length - len) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        synchronized (zsRef) {
+            ensureOpen();
+            setDictionary(zsRef.address(), dictionary, off, len);
+        }
+    }
+
+    /**
+     * Sets preset dictionary for compression. A preset dictionary is used
+     * when the history buffer can be predetermined. When the data is later
+     * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
+     * in order to get the Adler-32 value of the dictionary required for
+     * decompression.
+     * @param dictionary the dictionary data bytes
      * @see Inflater#inflate
      * @see Inflater#getAdler
      */
-    public void setDictionary(byte[] b) {
-        setDictionary(b, 0, b.length);
+    public void setDictionary(byte[] dictionary) {
+        setDictionary(dictionary, 0, dictionary.length);
+    }
+
+    /**
+     * Sets preset dictionary for compression. A preset dictionary is used
+     * when the history buffer can be predetermined. When the data is later
+     * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
+     * in order to get the Adler-32 value of the dictionary required for
+     * decompression.
+     * <p>
+     * The bytes in given byte buffer will be fully consumed by this method.  On
+     * return, its position will equal its limit.
+     *
+     * @param dictionary the dictionary data bytes
+     * @see Inflater#inflate
+     * @see Inflater#getAdler
+     */
+    public void setDictionary(ByteBuffer dictionary) {
+        synchronized (zsRef) {
+            int position = dictionary.position();
+            int remaining = Math.max(dictionary.limit() - position, 0);
+            ensureOpen();
+            if (dictionary.isDirect()) {
+                long address = ((DirectBuffer) dictionary).address();
+                try {
+                    setDictionaryBuffer(zsRef.address(), address + position, remaining);
+                } finally {
+                    Reference.reachabilityFence(dictionary);
+                }
+            } else {
+                byte[] array = ZipUtils.getBufferArray(dictionary);
+                int offset = ZipUtils.getBufferOffset(dictionary);
+                setDictionary(zsRef.address(), array, offset + position, remaining);
+            }
+            dictionary.position(position + remaining);
+        }
     }
 
     /**
@@ -331,14 +417,17 @@
     }
 
     /**
-     * Returns true if the input data buffer is empty and setInput()
-     * should be called in order to provide more input.
+     * Returns true if no data remains in the input buffer. This can
+     * be used to determine if one of the {@code setInput()} methods should be
+     * called in order to provide more input.
+     *
      * @return true if the input data buffer is empty and setInput()
      * should be called in order to provide more input
      */
     public boolean needsInput() {
         synchronized (zsRef) {
-            return len <= 0;
+            ByteBuffer input = this.input;
+            return input == null ? inputLim == inputPos : ! input.hasRemaining();
         }
     }
 
@@ -375,14 +464,14 @@
      * yields the same result as the invocation of
      * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}.
      *
-     * @param b the buffer for the compressed data
+     * @param output the buffer for the compressed data
      * @param off the start offset of the data
      * @param len the maximum number of bytes of compressed data
      * @return the actual number of bytes of compressed data written to the
      *         output buffer
      */
-    public int deflate(byte[] b, int off, int len) {
-        return deflate(b, off, len, NO_FLUSH);
+    public int deflate(byte[] output, int off, int len) {
+        return deflate(output, off, len, NO_FLUSH);
     }
 
     /**
@@ -396,12 +485,32 @@
      * yields the same result as the invocation of
      * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}.
      *
-     * @param b the buffer for the compressed data
+     * @param output the buffer for the compressed data
      * @return the actual number of bytes of compressed data written to the
      *         output buffer
      */
-    public int deflate(byte[] b) {
-        return deflate(b, 0, b.length, NO_FLUSH);
+    public int deflate(byte[] output) {
+        return deflate(output, 0, output.length, NO_FLUSH);
+    }
+
+    /**
+     * Compresses the input data and fills specified buffer with compressed
+     * data. Returns actual number of bytes of compressed data. A return value
+     * of 0 indicates that {@link #needsInput() needsInput} should be called
+     * in order to determine if more input data is required.
+     *
+     * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
+     * An invocation of this method of the form {@code deflater.deflate(output)}
+     * yields the same result as the invocation of
+     * {@code deflater.deflate(output, Deflater.NO_FLUSH)}.
+     *
+     * @param output the buffer for the compressed data
+     * @return the actual number of bytes of compressed data written to the
+     *         output buffer
+     * @since 11
+     */
+    public int deflate(ByteBuffer output) {
+        return deflate(output, NO_FLUSH);
     }
 
     /**
@@ -441,7 +550,11 @@
      * repeatedly output to the output buffer every time this method is
      * invoked.
      *
-     * @param b the buffer for the compressed data
+     * <p>If the {@link #setInput(ByteBuffer)} method was called to provide a buffer
+     * for input, the input buffer's position will be advanced by the number of bytes
+     * consumed by this operation.
+     *
+     * @param output the buffer for the compressed data
      * @param off the start offset of the data
      * @param len the maximum number of bytes of compressed data
      * @param flush the compression flush mode
@@ -451,25 +564,248 @@
      * @throws IllegalArgumentException if the flush mode is invalid
      * @since 1.7
      */
-    public int deflate(byte[] b, int off, int len, int flush) {
-        if (b == null) {
-            throw new NullPointerException();
+    public int deflate(byte[] output, int off, int len, int flush) {
+        if (off < 0 || len < 0 || off > output.length - len) {
+            throw new ArrayIndexOutOfBoundsException();
         }
-        if (off < 0 || len < 0 || off > b.length - len) {
-            throw new ArrayIndexOutOfBoundsException();
+        if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) {
+            throw new IllegalArgumentException();
         }
         synchronized (zsRef) {
             ensureOpen();
-            if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
-                flush == FULL_FLUSH) {
-                int thisLen = this.len;
-                int n = deflateBytes(zsRef.address(), b, off, len, flush);
-                bytesWritten += n;
-                bytesRead += (thisLen - this.len);
-                return n;
+
+            ByteBuffer input = this.input;
+            if (finish) {
+                // disregard given flush mode in this case
+                flush = FINISH;
+            }
+            int params;
+            if (setParams) {
+                // bit 0: true to set params
+                // bit 1-2: strategy (0, 1, or 2)
+                // bit 3-31: level (0..9 or -1)
+                params = 1 | strategy << 1 | level << 3;
+            } else {
+                params = 0;
+            }
+            int inputPos;
+            long result;
+            if (input == null) {
+                inputPos = this.inputPos;
+                result = deflateBytesBytes(zsRef.address(),
+                    inputArray, inputPos, inputLim - inputPos,
+                    output, off, len,
+                    flush, params);
+            } else {
+                inputPos = input.position();
+                int inputRem = Math.max(input.limit() - inputPos, 0);
+                if (input.isDirect()) {
+                    try {
+                        long inputAddress = ((DirectBuffer) input).address();
+                        result = deflateBufferBytes(zsRef.address(),
+                            inputAddress + inputPos, inputRem,
+                            output, off, len,
+                            flush, params);
+                    } finally {
+                        Reference.reachabilityFence(input);
+                    }
+                } else {
+                    byte[] inputArray = ZipUtils.getBufferArray(input);
+                    int inputOffset = ZipUtils.getBufferOffset(input);
+                    result = deflateBytesBytes(zsRef.address(),
+                        inputArray, inputOffset + inputPos, inputRem,
+                        output, off, len,
+                        flush, params);
+                }
+            }
+            int read = (int) (result & 0x7fff_ffffL);
+            int written = (int) (result >>> 31 & 0x7fff_ffffL);
+            if ((result >>> 62 & 1) != 0) {
+                finished = true;
+            }
+            if (params != 0 && (result >>> 63 & 1) == 0) {
+                setParams = false;
+            }
+            if (input != null) {
+                input.position(inputPos + read);
+            } else {
+                this.inputPos = inputPos + read;
             }
+            bytesWritten += written;
+            bytesRead += read;
+            return written;
+        }
+    }
+
+    /**
+     * Compresses the input data and fills the specified buffer with compressed
+     * data. Returns actual number of bytes of data compressed.
+     *
+     * <p>Compression flush mode is one of the following three modes:
+     *
+     * <ul>
+     * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data
+     * to accumulate, before producing output, in order to achieve the best
+     * compression (should be used in normal use scenario). A return value
+     * of 0 in this flush mode indicates that {@link #needsInput()} should
+     * be called in order to determine if more input data is required.
+     *
+     * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed,
+     * to the specified output buffer, so that an inflater that works on
+     * compressed data can get all input data available so far (In particular
+     * the {@link #needsInput()} returns {@code true} after this invocation
+     * if enough output space is provided). Flushing with {@link #SYNC_FLUSH}
+     * may degrade compression for some compression algorithms and so it
+     * should be used only when necessary.
+     *
+     * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with
+     * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater
+     * that works on the compressed output data can restart from this point
+     * if previous compressed data has been damaged or if random access is
+     * desired. Using {@link #FULL_FLUSH} too often can seriously degrade
+     * compression.
+     * </ul>
+     *
+     * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if
+     * the return value is equal to the {@linkplain ByteBuffer#remaining() remaining space}
+     * of the buffer, this method should be invoked again with the same
+     * {@code flush} parameter and more output space. Make sure that
+     * the buffer has at least 6 bytes of remaining space to avoid the
+     * flush marker (5 bytes) being repeatedly output to the output buffer
+     * every time this method is invoked.
+     *
+     * <p>On success, the position of the given {@code output} byte buffer will be
+     * advanced by as many bytes as were produced by the operation, which is equal
+     * to the number returned by this method.
+     *
+     * <p>If the {@link #setInput(ByteBuffer)} method was called to provide a buffer
+     * for input, the input buffer's position will be advanced by the number of bytes
+     * consumed by this operation.
+     *
+     * @param output the buffer for the compressed data
+     * @param flush the compression flush mode
+     * @return the actual number of bytes of compressed data written to
+     *         the output buffer
+     *
+     * @throws IllegalArgumentException if the flush mode is invalid
+     * @since 11
+     */
+    public int deflate(ByteBuffer output, int flush) {
+        if (output.isReadOnly()) {
+            throw new ReadOnlyBufferException();
+        }
+        if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) {
             throw new IllegalArgumentException();
         }
+        synchronized (zsRef) {
+            ensureOpen();
+
+            ByteBuffer input = this.input;
+            if (finish) {
+                // disregard given flush mode in this case
+                flush = FINISH;
+            }
+            int params;
+            if (setParams) {
+                // bit 0: true to set params
+                // bit 1-2: strategy (0, 1, or 2)
+                // bit 3-31: level (0..9 or -1)
+                params = 1 | strategy << 1 | level << 3;
+            } else {
+                params = 0;
+            }
+            int outputPos = output.position();
+            int outputRem = Math.max(output.limit() - outputPos, 0);
+            int inputPos;
+            long result;
+            if (input == null) {
+                inputPos = this.inputPos;
+                if (output.isDirect()) {
+                    long outputAddress = ((DirectBuffer) output).address();
+                    try {
+                        result = deflateBytesBuffer(zsRef.address(),
+                            inputArray, inputPos, inputLim - inputPos,
+                            outputAddress + outputPos, outputRem,
+                            flush, params);
+                    } finally {
+                        Reference.reachabilityFence(output);
+                    }
+                } else {
+                    byte[] outputArray = ZipUtils.getBufferArray(output);
+                    int outputOffset = ZipUtils.getBufferOffset(output);
+                    result = deflateBytesBytes(zsRef.address(),
+                        inputArray, inputPos, inputLim - inputPos,
+                        outputArray, outputOffset + outputPos, outputRem,
+                        flush, params);
+                }
+            } else {
+                inputPos = input.position();
+                int inputRem = Math.max(input.limit() - inputPos, 0);
+                if (input.isDirect()) {
+                    long inputAddress = ((DirectBuffer) input).address();
+                    try {
+                        if (output.isDirect()) {
+                            long outputAddress = outputPos + ((DirectBuffer) output).address();
+                            try {
+                                result = deflateBufferBuffer(zsRef.address(),
+                                    inputAddress + inputPos, inputRem,
+                                    outputAddress, outputRem,
+                                    flush, params);
+                            } finally {
+                                Reference.reachabilityFence(output);
+                            }
+                        } else {
+                            byte[] outputArray = ZipUtils.getBufferArray(output);
+                            int outputOffset = ZipUtils.getBufferOffset(output);
+                            result = deflateBufferBytes(zsRef.address(),
+                                inputAddress + inputPos, inputRem,
+                                outputArray, outputOffset + outputPos, outputRem,
+                                flush, params);
+                        }
+                    } finally {
+                        Reference.reachabilityFence(input);
+                    }
+                } else {
+                    byte[] inputArray = ZipUtils.getBufferArray(input);
+                    int inputOffset = ZipUtils.getBufferOffset(input);
+                    if (output.isDirect()) {
+                        long outputAddress = ((DirectBuffer) output).address();
+                        try {
+                            result = deflateBytesBuffer(zsRef.address(),
+                                inputArray, inputOffset + inputPos, inputRem,
+                                outputAddress + outputPos, outputRem,
+                                flush, params);
+                        } finally {
+                            Reference.reachabilityFence(output);
+                        }
+                    } else {
+                        byte[] outputArray = ZipUtils.getBufferArray(output);
+                        int outputOffset = ZipUtils.getBufferOffset(output);
+                        result = deflateBytesBytes(zsRef.address(),
+                            inputArray, inputOffset + inputPos, inputRem,
+                            outputArray, outputOffset + outputPos, outputRem,
+                            flush, params);
+                    }
+                }
+            }
+            int read = (int) (result & 0x7fff_ffffL);
+            int written = (int) (result >>> 31 & 0x7fff_ffffL);
+            if ((result >>> 62 & 1) != 0) {
+                finished = true;
+            }
+            if (params != 0 && (result >>> 63 & 1) == 0) {
+                setParams = false;
+            }
+            if (input != null) {
+                input.position(inputPos + read);
+            } else {
+                this.inputPos = inputPos + read;
+            }
+            output.position(outputPos + written);
+            bytesWritten += written;
+            bytesRead += read;
+            return written;
+        }
     }
 
     /**
@@ -545,7 +881,8 @@
             reset(zsRef.address());
             finish = false;
             finished = false;
-            off = len = 0;
+            input = ZipUtils.defaultBuf;
+            inputArray = null;
             bytesRead = bytesWritten = 0;
         }
     }
@@ -560,7 +897,7 @@
     public void end() {
         synchronized (zsRef) {
             zsRef.clean();
-            buf = null;
+            input = ZipUtils.defaultBuf;
         }
     }
 
@@ -585,11 +922,26 @@
             throw new NullPointerException("Deflater has been closed");
     }
 
-    private static native void initIDs();
     private static native long init(int level, int strategy, boolean nowrap);
-    private static native void setDictionary(long addr, byte[] b, int off, int len);
-    private native int deflateBytes(long addr, byte[] b, int off, int len,
-                                    int flush);
+    private static native void setDictionary(long addr, byte[] b, int off,
+                                             int len);
+    private static native void setDictionaryBuffer(long addr, long bufAddress, int len);
+    private native long deflateBytesBytes(long addr,
+        byte[] inputArray, int inputOff, int inputLen,
+        byte[] outputArray, int outputOff, int outputLen,
+        int flush, int params);
+    private native long deflateBytesBuffer(long addr,
+        byte[] inputArray, int inputOff, int inputLen,
+        long outputAddress, int outputLen,
+        int flush, int params);
+    private native long deflateBufferBytes(long addr,
+        long inputAddress, int inputLen,
+        byte[] outputArray, int outputOff, int outputLen,
+        int flush, int params);
+    private native long deflateBufferBuffer(long addr,
+        long inputAddress, int inputLen,
+        long outputAddress, int outputLen,
+        int flush, int params);
     private static native int getAdler(long addr);
     private static native void reset(long addr);
     private static native void end(long addr);
--- a/src/java.base/share/classes/java/util/zip/Inflater.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/zip/Inflater.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,13 @@
 package java.util.zip;
 
 import java.lang.ref.Cleaner.Cleanable;
+import java.lang.ref.Reference;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.Objects;
+
 import jdk.internal.ref.CleanerFactory;
+import sun.nio.ch.DirectBuffer;
 
 /**
  * This class provides support for general purpose decompression using the
@@ -35,8 +41,13 @@
  * protected by patents. It is fully described in the specifications at
  * the <a href="package-summary.html#package.description">java.util.zip
  * package description</a>.
- *
- * <p>The following code fragment demonstrates a trivial compression
+ * <p>
+ * This class inflates sequences of ZLIB compressed bytes. The input byte
+ * sequence is provided in either byte array or byte buffer, via one of the
+ * {@code setInput()} methods. The output byte sequence is written to the
+ * output byte array or byte buffer passed to the {@code deflate()} methods.
+ * <p>
+ * The following code fragment demonstrates a trivial compression
  * and decompression of a string using {@code Deflater} and
  * {@code Inflater}.
  *
@@ -92,14 +103,20 @@
 public class Inflater {
 
     private final InflaterZStreamRef zsRef;
-    private byte[] buf = defaultBuf;
-    private int off, len;
+    private ByteBuffer input = ZipUtils.defaultBuf;
+    private byte[] inputArray;
+    private int inputPos, inputLim;
     private boolean finished;
     private boolean needDict;
     private long bytesRead;
     private long bytesWritten;
 
-    private static final byte[] defaultBuf = new byte[0];
+    /*
+     * These fields are used as an "out" parameter from JNI when a
+     * DataFormatException is thrown during the inflate operation.
+     */
+    private int inputConsumed;
+    private int outputConsumed;
 
     static {
         ZipUtils.loadLibrary();
@@ -129,37 +146,71 @@
     }
 
     /**
-     * Sets input data for decompression. Should be called whenever
-     * needsInput() returns true indicating that more input data is
-     * required.
-     * @param b the input data bytes
+     * Sets input data for decompression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     *
+     * @param input the input data bytes
      * @param off the start offset of the input data
      * @param len the length of the input data
      * @see Inflater#needsInput
      */
-    public void setInput(byte[] b, int off, int len) {
-        if (b == null) {
-            throw new NullPointerException();
-        }
-        if (off < 0 || len < 0 || off > b.length - len) {
+    public void setInput(byte[] input, int off, int len) {
+        if (off < 0 || len < 0 || off > input.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
         synchronized (zsRef) {
-            this.buf = b;
-            this.off = off;
-            this.len = len;
+            this.input = null;
+            this.inputArray = input;
+            this.inputPos = off;
+            this.inputLim = off + len;
         }
     }
 
     /**
-     * Sets input data for decompression. Should be called whenever
-     * needsInput() returns true indicating that more input data is
-     * required.
-     * @param b the input data bytes
+     * Sets input data for decompression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     *
+     * @param input the input data bytes
      * @see Inflater#needsInput
      */
-    public void setInput(byte[] b) {
-        setInput(b, 0, b.length);
+    public void setInput(byte[] input) {
+        setInput(input, 0, input.length);
+    }
+
+    /**
+     * Sets input data for decompression.
+     * <p>
+     * One of the {@code setInput()} methods should be called whenever
+     * {@code needsInput()} returns true indicating that more input data
+     * is required.
+     * <p>
+     * The given buffer's position will be advanced as inflate
+     * operations are performed, up to the buffer's limit.
+     * The input buffer may be modified (refilled) between inflate
+     * operations; doing so is equivalent to creating a new buffer
+     * and setting it with this method.
+     * <p>
+     * Modifying the input buffer's contents, position, or limit
+     * concurrently with an inflate operation will result in
+     * undefined behavior, which may include incorrect operation
+     * results or operation failure.
+     *
+     * @param input the input data bytes
+     * @see Inflater#needsInput
+     * @since 11
+     */
+    public void setInput(ByteBuffer input) {
+        Objects.requireNonNull(input);
+        synchronized (zsRef) {
+            this.input = input;
+            this.inputArray = null;
+        }
     }
 
     /**
@@ -167,22 +218,19 @@
      * called when inflate() returns 0 and needsDictionary() returns true
      * indicating that a preset dictionary is required. The method getAdler()
      * can be used to get the Adler-32 value of the dictionary needed.
-     * @param b the dictionary data bytes
+     * @param dictionary the dictionary data bytes
      * @param off the start offset of the data
      * @param len the length of the data
      * @see Inflater#needsDictionary
      * @see Inflater#getAdler
      */
-    public void setDictionary(byte[] b, int off, int len) {
-        if (b == null) {
-            throw new NullPointerException();
-        }
-        if (off < 0 || len < 0 || off > b.length - len) {
+    public void setDictionary(byte[] dictionary, int off, int len) {
+        if (off < 0 || len < 0 || off > dictionary.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
         synchronized (zsRef) {
             ensureOpen();
-            setDictionary(zsRef.address(), b, off, len);
+            setDictionary(zsRef.address(), dictionary, off, len);
             needDict = false;
         }
     }
@@ -192,12 +240,48 @@
      * called when inflate() returns 0 and needsDictionary() returns true
      * indicating that a preset dictionary is required. The method getAdler()
      * can be used to get the Adler-32 value of the dictionary needed.
-     * @param b the dictionary data bytes
+     * @param dictionary the dictionary data bytes
      * @see Inflater#needsDictionary
      * @see Inflater#getAdler
      */
-    public void setDictionary(byte[] b) {
-        setDictionary(b, 0, b.length);
+    public void setDictionary(byte[] dictionary) {
+        setDictionary(dictionary, 0, dictionary.length);
+    }
+
+    /**
+     * Sets the preset dictionary to the bytes in the given buffer. Should be
+     * called when inflate() returns 0 and needsDictionary() returns true
+     * indicating that a preset dictionary is required. The method getAdler()
+     * can be used to get the Adler-32 value of the dictionary needed.
+     * <p>
+     * The bytes in given byte buffer will be fully consumed by this method.  On
+     * return, its position will equal its limit.
+     *
+     * @param dictionary the dictionary data bytes
+     * @see Inflater#needsDictionary
+     * @see Inflater#getAdler
+     * @since 11
+     */
+    public void setDictionary(ByteBuffer dictionary) {
+        synchronized (zsRef) {
+            int position = dictionary.position();
+            int remaining = Math.max(dictionary.limit() - position, 0);
+            ensureOpen();
+            if (dictionary.isDirect()) {
+                long address = ((DirectBuffer) dictionary).address();
+                try {
+                    setDictionaryBuffer(zsRef.address(), address + position, remaining);
+                } finally {
+                    Reference.reachabilityFence(dictionary);
+                }
+            } else {
+                byte[] array = ZipUtils.getBufferArray(dictionary);
+                int offset = ZipUtils.getBufferOffset(dictionary);
+                setDictionary(zsRef.address(), array, offset + position, remaining);
+            }
+            dictionary.position(position + remaining);
+            needDict = false;
+        }
     }
 
     /**
@@ -208,19 +292,22 @@
      */
     public int getRemaining() {
         synchronized (zsRef) {
-            return len;
+            ByteBuffer input = this.input;
+            return input == null ? inputLim - inputPos : input.remaining();
         }
     }
 
     /**
      * Returns true if no data remains in the input buffer. This can
-     * be used to determine if #setInput should be called in order
-     * to provide more input.
+     * be used to determine if one of the {@code setInput()} methods should be
+     * called in order to provide more input.
+     *
      * @return true if no data remains in the input buffer
      */
     public boolean needsInput() {
         synchronized (zsRef) {
-            return len <= 0;
+            ByteBuffer input = this.input;
+            return input == null ? inputLim == inputPos : ! input.hasRemaining();
         }
     }
 
@@ -254,30 +341,103 @@
      * determine if more input data or a preset dictionary is required.
      * In the latter case, getAdler() can be used to get the Adler-32
      * value of the dictionary required.
-     * @param b the buffer for the uncompressed data
+     * <p>
+     * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer
+     * for input, the input buffer's position will be advanced by the number of bytes
+     * consumed by this operation, even in the event that a {@link DataFormatException}
+     * is thrown.
+     * <p>
+     * The {@linkplain #getRemaining() remaining byte count} will be reduced by
+     * the number of consumed input bytes.  If the {@link #setInput(ByteBuffer)}
+     * method was called to provide a buffer for input, the input buffer's position
+     * will be advanced the number of consumed bytes.
+     * <p>
+     * These byte totals, as well as
+     * the {@linkplain #getBytesRead() total bytes read}
+     * and the {@linkplain #getBytesWritten() total bytes written}
+     * values, will be updated even in the event that a {@link DataFormatException}
+     * is thrown to reflect the amount of data consumed and produced before the
+     * exception occurred.
+     *
+     * @param output the buffer for the uncompressed data
      * @param off the start offset of the data
      * @param len the maximum number of uncompressed bytes
      * @return the actual number of uncompressed bytes
-     * @exception DataFormatException if the compressed data format is invalid
+     * @throws DataFormatException if the compressed data format is invalid
      * @see Inflater#needsInput
      * @see Inflater#needsDictionary
      */
-    public int inflate(byte[] b, int off, int len)
+    public int inflate(byte[] output, int off, int len)
         throws DataFormatException
     {
-        if (b == null) {
-            throw new NullPointerException();
-        }
-        if (off < 0 || len < 0 || off > b.length - len) {
+        if (off < 0 || len < 0 || off > output.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
         synchronized (zsRef) {
             ensureOpen();
-            int thisLen = this.len;
-            int n = inflateBytes(zsRef.address(), b, off, len);
-            bytesWritten += n;
-            bytesRead += (thisLen - this.len);
-            return n;
+            ByteBuffer input = this.input;
+            long result;
+            int inputPos;
+            try {
+                if (input == null) {
+                    inputPos = this.inputPos;
+                    try {
+                        result = inflateBytesBytes(zsRef.address(),
+                            inputArray, inputPos, inputLim - inputPos,
+                            output, off, len);
+                    } catch (DataFormatException e) {
+                        this.inputPos = inputPos + inputConsumed;
+                        throw e;
+                    }
+                } else {
+                    inputPos = input.position();
+                    try {
+                        int inputRem = Math.max(input.limit() - inputPos, 0);
+                        if (input.isDirect()) {
+                            try {
+                                long inputAddress = ((DirectBuffer) input).address();
+                                result = inflateBufferBytes(zsRef.address(),
+                                    inputAddress + inputPos, inputRem,
+                                    output, off, len);
+                            } finally {
+                                Reference.reachabilityFence(input);
+                            }
+                        } else {
+                            byte[] inputArray = ZipUtils.getBufferArray(input);
+                            int inputOffset = ZipUtils.getBufferOffset(input);
+                            result = inflateBytesBytes(zsRef.address(),
+                                inputArray, inputOffset + inputPos, inputRem,
+                                output, off, len);
+                        }
+                    } catch (DataFormatException e) {
+                        input.position(inputPos + inputConsumed);
+                        throw e;
+                    }
+                }
+            } catch (DataFormatException e) {
+                bytesRead += inputConsumed;
+                inputConsumed = 0;
+                int written = outputConsumed;
+                bytesWritten += written;
+                outputConsumed = 0;
+                throw e;
+            }
+            int read = (int) (result & 0x7fff_ffffL);
+            int written = (int) (result >>> 31 & 0x7fff_ffffL);
+            if ((result >>> 62 & 1) != 0) {
+                finished = true;
+            }
+            if ((result >>> 63 & 1) != 0) {
+                needDict = true;
+            }
+            if (input != null) {
+                input.position(inputPos + read);
+            } else {
+                this.inputPos = inputPos + read;
+            }
+            bytesWritten += written;
+            bytesRead += read;
+            return written;
         }
     }
 
@@ -288,14 +448,177 @@
      * determine if more input data or a preset dictionary is required.
      * In the latter case, getAdler() can be used to get the Adler-32
      * value of the dictionary required.
-     * @param b the buffer for the uncompressed data
+     * <p>
+     * The {@linkplain #getRemaining() remaining byte count} will be reduced by
+     * the number of consumed input bytes.  If the {@link #setInput(ByteBuffer)}
+     * method was called to provide a buffer for input, the input buffer's position
+     * will be advanced the number of consumed bytes.
+     * <p>
+     * These byte totals, as well as
+     * the {@linkplain #getBytesRead() total bytes read}
+     * and the {@linkplain #getBytesWritten() total bytes written}
+     * values, will be updated even in the event that a {@link DataFormatException}
+     * is thrown to reflect the amount of data consumed and produced before the
+     * exception occurred.
+     *
+     * @param output the buffer for the uncompressed data
      * @return the actual number of uncompressed bytes
-     * @exception DataFormatException if the compressed data format is invalid
+     * @throws DataFormatException if the compressed data format is invalid
      * @see Inflater#needsInput
      * @see Inflater#needsDictionary
      */
-    public int inflate(byte[] b) throws DataFormatException {
-        return inflate(b, 0, b.length);
+    public int inflate(byte[] output) throws DataFormatException {
+        return inflate(output, 0, output.length);
+    }
+
+    /**
+     * Uncompresses bytes into specified buffer. Returns actual number
+     * of bytes uncompressed. A return value of 0 indicates that
+     * needsInput() or needsDictionary() should be called in order to
+     * determine if more input data or a preset dictionary is required.
+     * In the latter case, getAdler() can be used to get the Adler-32
+     * value of the dictionary required.
+     * <p>
+     * On success, the position of the given {@code output} byte buffer will be
+     * advanced by as many bytes as were produced by the operation, which is equal
+     * to the number returned by this method.  Note that the position of the
+     * {@code output} buffer will be advanced even in the event that a
+     * {@link DataFormatException} is thrown.
+     * <p>
+     * The {@linkplain #getRemaining() remaining byte count} will be reduced by
+     * the number of consumed input bytes.  If the {@link #setInput(ByteBuffer)}
+     * method was called to provide a buffer for input, the input buffer's position
+     * will be advanced the number of consumed bytes.
+     * <p>
+     * These byte totals, as well as
+     * the {@linkplain #getBytesRead() total bytes read}
+     * and the {@linkplain #getBytesWritten() total bytes written}
+     * values, will be updated even in the event that a {@link DataFormatException}
+     * is thrown to reflect the amount of data consumed and produced before the
+     * exception occurred.
+     *
+     * @param output the buffer for the uncompressed data
+     * @return the actual number of uncompressed bytes
+     * @throws DataFormatException if the compressed data format is invalid
+     * @throws ReadOnlyBufferException if the given output buffer is read-only
+     * @see Inflater#needsInput
+     * @see Inflater#needsDictionary
+     * @since 11
+     */
+    public int inflate(ByteBuffer output) throws DataFormatException {
+        if (output.isReadOnly()) {
+            throw new ReadOnlyBufferException();
+        }
+        synchronized (zsRef) {
+            ensureOpen();
+            ByteBuffer input = this.input;
+            long result;
+            int inputPos;
+            int outputPos = output.position();
+            int outputRem = Math.max(output.limit() - outputPos, 0);
+            try {
+                if (input == null) {
+                    inputPos = this.inputPos;
+                    try {
+                        if (output.isDirect()) {
+                            long outputAddress = ((DirectBuffer) output).address();
+                            try {
+                                result = inflateBytesBuffer(zsRef.address(),
+                                    inputArray, inputPos, inputLim - inputPos,
+                                    outputAddress + outputPos, outputRem);
+                            } finally {
+                                Reference.reachabilityFence(output);
+                            }
+                        } else {
+                            byte[] outputArray = ZipUtils.getBufferArray(output);
+                            int outputOffset = ZipUtils.getBufferOffset(output);
+                            result = inflateBytesBytes(zsRef.address(),
+                                inputArray, inputPos, inputLim - inputPos,
+                                outputArray, outputOffset + outputPos, outputRem);
+                        }
+                    } catch (DataFormatException e) {
+                        this.inputPos = inputPos + inputConsumed;
+                        throw e;
+                    }
+                } else {
+                    inputPos = input.position();
+                    int inputRem = Math.max(input.limit() - inputPos, 0);
+                    try {
+                        if (input.isDirect()) {
+                            long inputAddress = ((DirectBuffer) input).address();
+                            try {
+                                if (output.isDirect()) {
+                                    long outputAddress = ((DirectBuffer) output).address();
+                                    try {
+                                        result = inflateBufferBuffer(zsRef.address(),
+                                            inputAddress + inputPos, inputRem,
+                                            outputAddress + outputPos, outputRem);
+                                    } finally {
+                                        Reference.reachabilityFence(output);
+                                    }
+                                } else {
+                                    byte[] outputArray = ZipUtils.getBufferArray(output);
+                                    int outputOffset = ZipUtils.getBufferOffset(output);
+                                    result = inflateBufferBytes(zsRef.address(),
+                                        inputAddress + inputPos, inputRem,
+                                        outputArray, outputOffset + outputPos, outputRem);
+                                }
+                            } finally {
+                                Reference.reachabilityFence(input);
+                            }
+                        } else {
+                            byte[] inputArray = ZipUtils.getBufferArray(input);
+                            int inputOffset = ZipUtils.getBufferOffset(input);
+                            if (output.isDirect()) {
+                                long outputAddress = ((DirectBuffer) output).address();
+                                try {
+                                    result = inflateBytesBuffer(zsRef.address(),
+                                        inputArray, inputOffset + inputPos, inputRem,
+                                        outputAddress + outputPos, outputRem);
+                                } finally {
+                                    Reference.reachabilityFence(output);
+                                }
+                            } else {
+                                byte[] outputArray = ZipUtils.getBufferArray(output);
+                                int outputOffset = ZipUtils.getBufferOffset(output);
+                                result = inflateBytesBytes(zsRef.address(),
+                                    inputArray, inputOffset + inputPos, inputRem,
+                                    outputArray, outputOffset + outputPos, outputRem);
+                            }
+                        }
+                    } catch (DataFormatException e) {
+                        input.position(inputPos + inputConsumed);
+                        throw e;
+                    }
+                }
+            } catch (DataFormatException e) {
+                bytesRead += inputConsumed;
+                inputConsumed = 0;
+                int written = outputConsumed;
+                output.position(outputPos + written);
+                bytesWritten += written;
+                outputConsumed = 0;
+                throw e;
+            }
+            int read = (int) (result & 0x7fff_ffffL);
+            int written = (int) (result >>> 31 & 0x7fff_ffffL);
+            if ((result >>> 62 & 1) != 0) {
+                finished = true;
+            }
+            if ((result >>> 63 & 1) != 0) {
+                needDict = true;
+            }
+            if (input != null) {
+                input.position(inputPos + read);
+            } else {
+                this.inputPos = inputPos + read;
+            }
+            // Note: this method call also serves to keep the byteBuffer ref alive
+            output.position(outputPos + written);
+            bytesWritten += written;
+            bytesRead += read;
+            return written;
+        }
     }
 
     /**
@@ -368,10 +691,10 @@
         synchronized (zsRef) {
             ensureOpen();
             reset(zsRef.address());
-            buf = defaultBuf;
+            input = ZipUtils.defaultBuf;
+            inputArray = null;
             finished = false;
             needDict = false;
-            off = len = 0;
             bytesRead = bytesWritten = 0;
         }
     }
@@ -386,7 +709,8 @@
     public void end() {
         synchronized (zsRef) {
             zsRef.clean();
-            buf = null;
+            input = ZipUtils.defaultBuf;
+            inputArray = null;
         }
     }
 
@@ -416,18 +740,23 @@
             throw new NullPointerException("Inflater has been closed");
     }
 
-    boolean ended() {
-        synchronized (zsRef) {
-            return zsRef.address() == 0;
-        }
-    }
-
     private static native void initIDs();
     private static native long init(boolean nowrap);
     private static native void setDictionary(long addr, byte[] b, int off,
                                              int len);
-    private native int inflateBytes(long addr, byte[] b, int off, int len)
-            throws DataFormatException;
+    private static native void setDictionaryBuffer(long addr, long bufAddress, int len);
+    private native long inflateBytesBytes(long addr,
+        byte[] inputArray, int inputOff, int inputLen,
+        byte[] outputArray, int outputOff, int outputLen) throws DataFormatException;
+    private native long inflateBytesBuffer(long addr,
+        byte[] inputArray, int inputOff, int inputLen,
+        long outputAddress, int outputLen) throws DataFormatException;
+    private native long inflateBufferBytes(long addr,
+        long inputAddress, int inputLen,
+        byte[] outputArray, int outputOff, int outputLen) throws DataFormatException;
+    private native long inflateBufferBuffer(long addr,
+        long inputAddress, int inputLen,
+        long outputAddress, int outputLen) throws DataFormatException;
     private static native int getAdler(long addr);
     private static native void reset(long addr);
     private static native void end(long addr);
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package java.util.zip;
 
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
 import java.nio.file.attribute.FileTime;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -37,6 +39,9 @@
 
 import static java.util.zip.ZipConstants.ENDHDR;
 
+import jdk.internal.misc.Unsafe;
+import sun.nio.ch.DirectBuffer;
+
 class ZipUtils {
 
     // used to adjust values between Windows and java epoch
@@ -45,6 +50,9 @@
     // used to indicate the corresponding windows time is not available
     public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE;
 
+    // static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0);
+    static final ByteBuffer defaultBuf = ByteBuffer.allocate(0);
+
     /**
      * Converts Windows time (in microseconds, UTC/GMT) time to FileTime.
      */
@@ -281,4 +289,17 @@
             AccessController.doPrivileged(pa);
         }
     }
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb");
+    private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset");
+
+    static byte[] getBufferArray(ByteBuffer byteBuffer) {
+        return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset);
+    }
+
+    static int getBufferOffset(ByteBuffer byteBuffer) {
+        return unsafe.getInt(byteBuffer, byteBufferOffsetOffset);
+    }
 }
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Tue Apr 24 10:20:22 2018 +0100
@@ -113,6 +113,8 @@
 \                  one or more argument files containing options\n\
 \    -disable-@files\n\
 \                  prevent further argument file expansion\n\
+\    --enable-preview\n\
+\                  allow classes to depend on preview features of this release
 \To specify an argument for a long option, you can use --<name>=<value> or\n\
 \--<name> <value>.\n
 
--- a/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/classes/sun/security/provider/PolicyFile.java	Tue Apr 24 10:20:22 2018 +0100
@@ -40,7 +40,7 @@
 import java.io.FilePermission;
 import java.net.SocketPermission;
 import java.net.NetPermission;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.ConcurrentHashMap;
 import jdk.internal.misc.JavaSecurityAccess;
 import static jdk.internal.misc.JavaSecurityAccess.ProtectionDomainCache;
 import jdk.internal.misc.SharedSecrets;
@@ -248,7 +248,8 @@
     private static final int DEFAULT_CACHE_SIZE = 1;
 
     // contains the policy grant entries, PD cache, and alias mapping
-    private AtomicReference<PolicyInfo> policyInfo = new AtomicReference<>();
+    // can be updated if refresh() is called
+    private volatile PolicyInfo policyInfo;
 
     private boolean expandProperties = true;
     private boolean allowSystemProperties = true;
@@ -268,8 +269,8 @@
      * previously parsed and have syntax errors, so that they can be
      * subsequently ignored.
      */
-    private static AtomicReference<Set<URL>> badPolicyURLs =
-        new AtomicReference<>(new HashSet<>());
+    private static Set<URL> badPolicyURLs =
+        Collections.newSetFromMap(new ConcurrentHashMap<URL,Boolean>());
 
     // The default.policy file
     private static final URL DEFAULT_POLICY_URL =
@@ -341,7 +342,7 @@
         // System.out.println("number caches=" + numCaches);
         PolicyInfo newInfo = new PolicyInfo(numCaches);
         initPolicyFile(newInfo, url);
-        policyInfo.set(newInfo);
+        policyInfo = newInfo;
     }
 
     private void initPolicyFile(final PolicyInfo newInfo, final URL url) {
@@ -498,7 +499,7 @@
 
         // skip parsing policy file if it has been previously parsed and
         // has syntax errors
-        if (badPolicyURLs.get().contains(policy)) {
+        if (badPolicyURLs.contains(policy)) {
             if (debug != null) {
                 debug.println("skipping bad policy file: " + policy);
             }
@@ -539,10 +540,7 @@
                 throw new InternalError("Failed to load default.policy", pe);
             }
             // record bad policy file to avoid later reparsing it
-            badPolicyURLs.updateAndGet(k -> {
-                k.add(policy);
-                return k;
-            });
+            badPolicyURLs.add(policy);
             Object[] source = {policy, pe.getNonlocalizedMessage()};
             System.err.println(LocalizedMessage.getNonlocalized
                 (POLICY + ".error.parsing.policy.message", source));
@@ -991,9 +989,7 @@
      */
     @Override
     public boolean implies(ProtectionDomain pd, Permission p) {
-        PolicyInfo pi = policyInfo.get();
-        ProtectionDomainCache pdMap = pi.getPdMapping();
-
+        ProtectionDomainCache pdMap = policyInfo.getPdMapping();
         PermissionCollection pc = pdMap.get(pd);
 
         if (pc != null) {
@@ -1139,9 +1135,7 @@
     private Permissions getPermissions(Permissions perms,
                                        final CodeSource cs,
                                        Principal[] principals) {
-        PolicyInfo pi = policyInfo.get();
-
-        for (PolicyEntry entry : pi.policyEntries) {
+        for (PolicyEntry entry : policyInfo.policyEntries) {
             addPermissions(perms, cs, principals, entry);
         }
 
--- a/src/java.base/share/native/launcher/main.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/launcher/main.c	Tue Apr 24 10:20:22 2018 +0100
@@ -93,7 +93,7 @@
     __initenv = _environ;
 
 #else /* JAVAW */
-JNIEXPORT int JNICALL
+JNIEXPORT int
 main(int argc, char **argv)
 {
     int margc;
--- a/src/java.base/share/native/libjimage/jimage.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libjimage/jimage.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -55,7 +55,7 @@
  *   }
  *   ...
  */
-extern "C" JNIEXPORT JImageFile* JNICALL
+extern "C" JNIEXPORT JImageFile*
 JIMAGE_Open(const char *name, jint* error) {
     // TODO - return a meaningful error code
     *error = 0;
@@ -72,7 +72,7 @@
  * Ex.
  *  (*JImageClose)(image);
  */
-extern "C" JNIEXPORT void JNICALL
+extern "C" JNIEXPORT void
 JIMAGE_Close(JImageFile* image) {
     ImageFileReader::close((ImageFileReader*) image);
 }
@@ -89,7 +89,7 @@
  *  tty->print_cr(package);
  *  -> java.base
  */
-extern "C" JNIEXPORT const char* JNICALL
+extern "C" JNIEXPORT const char*
 JIMAGE_PackageToModule(JImageFile* image, const char* package_name) {
     return ((ImageFileReader*) image)->get_image_module_data()->package_to_module(package_name);
 }
@@ -108,7 +108,7 @@
  *   JImageLocationRef location = (*JImageFindResource)(image,
  *                                 "java.base", "9.0", "java/lang/String.class", &size);
  */
-extern "C" JNIEXPORT JImageLocationRef JNICALL
+extern "C" JNIEXPORT JImageLocationRef
 JIMAGE_FindResource(JImageFile* image,
         const char* module_name, const char* version, const char* name,
         jlong* size) {
@@ -155,7 +155,7 @@
  *  char* buffer = new char[size];
  *  (*JImageGetResource)(image, location, buffer, size);
  */
-extern "C" JNIEXPORT jlong JNICALL
+extern "C" JNIEXPORT jlong
 JIMAGE_GetResource(JImageFile* image, JImageLocationRef location,
         char* buffer, jlong size) {
     ((ImageFileReader*) image)->get_resource((u4) location, (u1*) buffer);
@@ -184,7 +184,7 @@
  *   }
  *   (*JImageResourceIterator)(image, ctw_visitor, loader);
  */
-extern "C" JNIEXPORT void JNICALL
+extern "C" JNIEXPORT void
 JIMAGE_ResourceIterator(JImageFile* image,
         JImageResourceVisitor_t visitor, void* arg) {
     ImageFileReader* imageFile = (ImageFileReader*) image;
@@ -226,7 +226,7 @@
  *   char path[JIMAGE_MAX_PATH];
  *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
  */
-extern "C" JNIEXPORT bool JNICALL
+extern "C" JNIEXPORT bool
 JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
                                     char* path, size_t max) {
     ImageFileReader* imageFile = (ImageFileReader*) image;
--- a/src/java.base/share/native/libjimage/jimage.hpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libjimage/jimage.hpp	Tue Apr 24 10:20:22 2018 +0100
@@ -72,7 +72,7 @@
  *   ...
  */
 
-extern "C" JNIEXPORT JImageFile* JNICALL
+extern "C" JNIEXPORT JImageFile*
 JIMAGE_Open(const char *name, jint* error);
 
 typedef JImageFile* (*JImageOpen_t)(const char *name, jint* error);
@@ -87,7 +87,7 @@
  *  (*JImageClose)(image);
  */
 
-extern "C" JNIEXPORT void JNICALL
+extern "C" JNIEXPORT void
 JIMAGE_Close(JImageFile* jimage);
 
 typedef void (*JImageClose_t)(JImageFile* jimage);
@@ -106,7 +106,7 @@
  *  -> java.base
  */
 
-extern "C" JNIEXPORT const char * JNICALL
+extern "C" JNIEXPORT const char *
 JIMAGE_PackageToModule(JImageFile* jimage, const char* package_name);
 
 typedef const char* (*JImagePackageToModule_t)(JImageFile* jimage, const char* package_name);
@@ -150,7 +150,7 @@
  *  char* buffer = new char[size];
  *  (*JImageGetResource)(image, location, buffer, size);
  */
-extern "C" JNIEXPORT jlong JNICALL
+extern "C" JNIEXPORT jlong
 JIMAGE_GetResource(JImageFile* jimage, JImageLocationRef location,
         char* buffer, jlong size);
 
@@ -185,7 +185,7 @@
         const char* module_name, const char* version, const char* package,
         const char* name, const char* extension, void* arg);
 
-extern "C" JNIEXPORT void JNICALL
+extern "C" JNIEXPORT void
 JIMAGE_ResourceIterator(JImageFile* jimage,
         JImageResourceVisitor_t visitor, void *arg);
 
@@ -202,7 +202,7 @@
  *   char path[JIMAGE_MAX_PATH];
  *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
  */
-extern "C" JNIEXPORT bool JNICALL
+extern "C" JNIEXPORT bool
 JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
                                     char* path, size_t max);
 
--- a/src/java.base/share/native/libzip/CRC32.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libzip/CRC32.c	Tue Apr 24 10:20:22 2018 +0100
@@ -54,7 +54,7 @@
     return crc;
 }
 
-JNIEXPORT jint JNICALL
+JNIEXPORT jint
 ZIP_CRC32(jint crc, const jbyte *buf, jint len)
 {
     return crc32(crc, (Bytef*)buf, len);
--- a/src/java.base/share/native/libzip/Deflater.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libzip/Deflater.c	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,34 +38,6 @@
 
 #define DEF_MEM_LEVEL 8
 
-static jfieldID levelID;
-static jfieldID strategyID;
-static jfieldID setParamsID;
-static jfieldID finishID;
-static jfieldID finishedID;
-static jfieldID bufID, offID, lenID;
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls)
-{
-    levelID = (*env)->GetFieldID(env, cls, "level", "I");
-    CHECK_NULL(levelID);
-    strategyID = (*env)->GetFieldID(env, cls, "strategy", "I");
-    CHECK_NULL(strategyID);
-    setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z");
-    CHECK_NULL(setParamsID);
-    finishID = (*env)->GetFieldID(env, cls, "finish", "Z");
-    CHECK_NULL(finishID);
-    finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
-    CHECK_NULL(finishedID);
-    bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
-    CHECK_NULL(bufID);
-    offID = (*env)->GetFieldID(env, cls, "off", "I");
-    CHECK_NULL(offID);
-    lenID = (*env)->GetFieldID(env, cls, "len", "I");
-    CHECK_NULL(lenID);
-}
-
 JNIEXPORT jlong JNICALL
 Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,
                                  jint strategy, jboolean nowrap)
@@ -104,17 +76,9 @@
     }
 }
 
-JNIEXPORT void JNICALL
-Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
-                                          jarray b, jint off, jint len)
+static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len)
 {
-    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
-    int res;
-    if (buf == 0) {/* out of memory */
-        return;
-    }
-    res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len);
-    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len);
     switch (res) {
     case Z_OK:
         break;
@@ -127,94 +91,173 @@
     }
 }
 
-JNIEXPORT jint JNICALL
-Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr,
-                                         jarray b, jint off, jint len, jint flush)
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
+                                          jbyteArray b, jint off, jint len)
+{
+    jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (buf == NULL) /* out of memory */
+        return;
+    doSetDictionary(env, addr, buf + off, len);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr,
+                                          jlong bufferAddr, jint len)
+{
+    jbyte *buf = jlong_to_ptr(bufferAddr);
+    doSetDictionary(env, addr, buf, len);
+}
+
+static jlong doDeflate(JNIEnv *env, jobject this, jlong addr,
+                       jbyte *input, jint inputLen,
+                       jbyte *output, jint outputLen,
+                       jint flush, jint params)
 {
     z_stream *strm = jlong_to_ptr(addr);
+    jint inputUsed = 0, outputUsed = 0;
+    int finished = 0;
+    int setParams = params & 1;
 
-    jarray this_buf = (*env)->GetObjectField(env, this, bufID);
-    jint this_off = (*env)->GetIntField(env, this, offID);
-    jint this_len = (*env)->GetIntField(env, this, lenID);
-    jbyte *in_buf;
-    jbyte *out_buf;
-    int res;
-    if ((*env)->GetBooleanField(env, this, setParamsID)) {
-        int level = (*env)->GetIntField(env, this, levelID);
-        int strategy = (*env)->GetIntField(env, this, strategyID);
-        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
-        if (in_buf == NULL) {
-            // Throw OOME only when length is not zero
-            if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
-                JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
-        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
-        if (out_buf == NULL) {
-            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
-            if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
-                JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
+    strm->next_in  = (Bytef *) input;
+    strm->next_out = (Bytef *) output;
+    strm->avail_in  = inputLen;
+    strm->avail_out = outputLen;
 
-        strm->next_in = (Bytef *) (in_buf + this_off);
-        strm->next_out = (Bytef *) (out_buf + off);
-        strm->avail_in = this_len;
-        strm->avail_out = len;
-        res = deflateParams(strm, level, strategy);
-        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
-        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+    if (setParams) {
+        int strategy = (params >> 1) & 3;
+        int level = params >> 3;
+        int res = deflateParams(strm, level, strategy);
         switch (res) {
         case Z_OK:
-            (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+            setParams = 0;
+            /* fall through */
         case Z_BUF_ERROR:
-            this_off += this_len - strm->avail_in;
-            (*env)->SetIntField(env, this, offID, this_off);
-            (*env)->SetIntField(env, this, lenID, strm->avail_in);
-            return (jint) (len - strm->avail_out);
+            inputUsed = inputLen - strm->avail_in;
+            outputUsed = outputLen - strm->avail_out;
+            break;
         default:
             JNU_ThrowInternalError(env, strm->msg);
             return 0;
         }
     } else {
-        jboolean finish = (*env)->GetBooleanField(env, this, finishID);
-        in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
-        if (in_buf == NULL) {
-            if (this_len != 0)
-                JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
-        out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
-        if (out_buf == NULL) {
-            (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
-            if (len != 0)
-                JNU_ThrowOutOfMemoryError(env, 0);
-
-            return 0;
-        }
-
-        strm->next_in = (Bytef *) (in_buf + this_off);
-        strm->next_out = (Bytef *) (out_buf + off);
-        strm->avail_in = this_len;
-        strm->avail_out = len;
-        res = deflate(strm, finish ? Z_FINISH : flush);
-        (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
-        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
+        int res = deflate(strm, flush);
         switch (res) {
         case Z_STREAM_END:
-            (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+            finished = 1;
             /* fall through */
         case Z_OK:
         case Z_BUF_ERROR:
-            this_off += this_len - strm->avail_in;
-            (*env)->SetIntField(env, this, offID, this_off);
-            (*env)->SetIntField(env, this, lenID, strm->avail_in);
-            return len - strm->avail_out;
+            inputUsed = inputLen - strm->avail_in;
+            outputUsed = outputLen - strm->avail_out;
+            break;
         default:
             JNU_ThrowInternalError(env, strm->msg);
             return 0;
         }
     }
+    return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jbyteArray inputArray, jint inputOff, jint inputLen,
+                                         jbyteArray outputArray, jint outputOff, jint outputLen,
+                                         jint flush, jint params)
+{
+    jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);
+    jbyte *output;
+    jlong retVal;
+    if (input == NULL) {
+        if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+    output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);
+    if (output == NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+        if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+
+    retVal = doDeflate(env, this, addr,
+            input + inputOff, inputLen,
+            output + outputOff, outputLen,
+            flush, params);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+
+    return retVal;
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr,
+                                         jbyteArray inputArray, jint inputOff, jint inputLen,
+                                         jlong outputBuffer, jint outputLen,
+                                         jint flush, jint params)
+{
+    jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);
+    jbyte *output;
+    jlong retVal;
+    if (input == NULL) {
+        if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+    output = jlong_to_ptr(outputBuffer);
+
+    retVal = doDeflate(env, this, addr,
+            input + inputOff, inputLen,
+            output, outputLen,
+            flush, params);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+
+    return retVal;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jlong inputBuffer, jint inputLen,
+                                         jbyteArray outputArray, jint outputOff, jint outputLen,
+                                         jint flush, jint params)
+{
+    jbyte *input = jlong_to_ptr(inputBuffer);
+    jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);
+    jlong retVal;
+    if (output == NULL) {
+        if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+
+    retVal = doDeflate(env, this, addr,
+            input, inputLen,
+            output + outputOff, outputLen,
+            flush, params);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0);
+
+    return retVal;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr,
+                                         jlong inputBuffer, jint inputLen,
+                                         jlong outputBuffer, jint outputLen,
+                                         jint flush, jint params)
+{
+    jbyte *input = jlong_to_ptr(inputBuffer);
+    jbyte *output = jlong_to_ptr(outputBuffer);
+
+    return doDeflate(env, this, addr,
+            input, inputLen,
+            output, outputLen,
+            flush, params);
 }
 
 JNIEXPORT jint JNICALL
--- a/src/java.base/share/native/libzip/Inflater.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libzip/Inflater.c	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,23 +42,16 @@
 #define ThrowDataFormatException(env, msg) \
         JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
 
-static jfieldID needDictID;
-static jfieldID finishedID;
-static jfieldID bufID, offID, lenID;
+static jfieldID inputConsumedID;
+static jfieldID outputConsumedID;
 
 JNIEXPORT void JNICALL
 Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
 {
-    needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z");
-    CHECK_NULL(needDictID);
-    finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
-    CHECK_NULL(finishedID);
-    bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
-    CHECK_NULL(bufID);
-    offID = (*env)->GetFieldID(env, cls, "off", "I");
-    CHECK_NULL(offID);
-    lenID = (*env)->GetFieldID(env, cls, "len", "I");
-    CHECK_NULL(lenID);
+    inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I");
+    outputConsumedID = (*env)->GetFieldID(env, cls, "outputConsumed", "I");
+    CHECK_NULL(inputConsumedID);
+    CHECK_NULL(outputConsumedID);
 }
 
 JNIEXPORT jlong JNICALL
@@ -94,16 +87,9 @@
     }
 }
 
-JNIEXPORT void JNICALL
-Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
-                                          jarray b, jint off, jint len)
+static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len)
 {
-    Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
-    int res;
-    if (buf == 0) /* out of memory */
-        return;
-    res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len);
-    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+    int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len);
     switch (res) {
     case Z_OK:
         break;
@@ -117,68 +103,168 @@
     }
 }
 
-JNIEXPORT jint JNICALL
-Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
-                                         jarray b, jint off, jint len)
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
+                                          jbyteArray b, jint off, jint len)
+{
+    jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+    if (buf == NULL) /* out of memory */
+        return;
+    doSetDictionary(env, addr, buf + off, len);
+    (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr,
+                                          jlong bufferAddr, jint len)
+{
+    jbyte *buf = jlong_to_ptr(bufferAddr);
+    doSetDictionary(env, addr, buf, len);
+}
+
+static jlong doInflate(JNIEnv *env, jobject this, jlong addr,
+                       jbyte *input, jint inputLen,
+                       jbyte *output, jint outputLen)
 {
     z_stream *strm = jlong_to_ptr(addr);
-    jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
-    jint this_off = (*env)->GetIntField(env, this, offID);
-    jint this_len = (*env)->GetIntField(env, this, lenID);
-
-    jbyte *in_buf;
-    jbyte *out_buf;
+    jint inputUsed = 0, outputUsed = 0;
+    int finished = 0;
+    int needDict = 0;
     int ret;
 
-    in_buf  = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
-    if (in_buf == NULL) {
-        if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
-            JNU_ThrowOutOfMemoryError(env, 0);
-        return 0;
-    }
-    out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
-    if (out_buf == NULL) {
-        (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
-        if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
-            JNU_ThrowOutOfMemoryError(env, 0);
-        return 0;
-    }
-    strm->next_in  = (Bytef *) (in_buf + this_off);
-    strm->next_out = (Bytef *) (out_buf + off);
-    strm->avail_in  = this_len;
-    strm->avail_out = len;
+    strm->next_in  = (Bytef *) input;
+    strm->next_out = (Bytef *) output;
+    strm->avail_in  = inputLen;
+    strm->avail_out = outputLen;
+
     ret = inflate(strm, Z_PARTIAL_FLUSH);
-    (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
-    (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
 
     switch (ret) {
     case Z_STREAM_END:
-        (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+        finished = 1;
         /* fall through */
     case Z_OK:
-        this_off += this_len - strm->avail_in;
-        (*env)->SetIntField(env, this, offID, this_off);
-        (*env)->SetIntField(env, this, lenID, strm->avail_in);
-        return (jint) (len - strm->avail_out);
+        inputUsed = inputLen - strm->avail_in;
+        outputUsed = outputLen - strm->avail_out;
+        break;
     case Z_NEED_DICT:
-        (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
+        needDict = 1;
         /* Might have consumed some input here! */
-        this_off += this_len - strm->avail_in;
-        (*env)->SetIntField(env, this, offID, this_off);
-        (*env)->SetIntField(env, this, lenID, strm->avail_in);
-        return 0;
+        inputUsed = inputLen - strm->avail_in;
+        /* zlib is unclear about whether output may be produced */
+        outputUsed = outputLen - strm->avail_out;
+        break;
     case Z_BUF_ERROR:
-        return 0;
+        break;
     case Z_DATA_ERROR:
+        inputUsed = inputLen - strm->avail_in;
+        (*env)->SetIntField(env, this, inputConsumedID, inputUsed);
+        outputUsed = outputLen - strm->avail_out;
+        (*env)->SetIntField(env, this, outputConsumedID, outputUsed);
         ThrowDataFormatException(env, strm->msg);
-        return 0;
+        break;
     case Z_MEM_ERROR:
         JNU_ThrowOutOfMemoryError(env, 0);
-        return 0;
+        break;
     default:
         JNU_ThrowInternalError(env, strm->msg);
-        return 0;
+        break;
+    }
+    return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jbyteArray inputArray, jint inputOff, jint inputLen,
+                                         jbyteArray outputArray, jint outputOff, jint outputLen)
+{
+    jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);
+    jbyte *output;
+    jlong retVal;
+
+    if (input == NULL) {
+        if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+    output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);
+    if (output == NULL) {
+        (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+        if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
     }
+
+    retVal = doInflate(env, this, addr,
+            input + inputOff, inputLen,
+            output + outputOff, outputLen);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+
+    return retVal;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr,
+                                         jbyteArray inputArray, jint inputOff, jint inputLen,
+                                         jlong outputBuffer, jint outputLen)
+{
+    jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0);
+    jbyte *output;
+    jlong retVal;
+
+    if (input == NULL) {
+        if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+    output = jlong_to_ptr(outputBuffer);
+
+    retVal = doInflate(env, this, addr,
+            input + inputOff, inputLen,
+            output, outputLen);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0);
+
+    return retVal;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr,
+                                         jlong inputBuffer, jint inputLen,
+                                         jbyteArray outputArray, jint outputOff, jint outputLen)
+{
+    jbyte *input = jlong_to_ptr(inputBuffer);
+    jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0);
+    jlong retVal;
+
+    if (output == NULL) {
+        if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL)
+            JNU_ThrowOutOfMemoryError(env, 0);
+        return 0L;
+    }
+
+    retVal = doInflate(env, this, addr,
+            input, inputLen,
+            output + outputOff, outputLen);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);
+
+    return retVal;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr,
+                                         jlong inputBuffer, jint inputLen,
+                                         jlong outputBuffer, jint outputLen)
+{
+    jbyte *input = jlong_to_ptr(inputBuffer);
+    jbyte *output = jlong_to_ptr(outputBuffer);
+
+    return doInflate(env, this, addr,
+            input, inputLen,
+            output, outputLen);
 }
 
 JNIEXPORT jint JNICALL
--- a/src/java.base/share/native/libzip/zip_util.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libzip/zip_util.c	Tue Apr 24 10:20:22 2018 +0100
@@ -881,7 +881,7 @@
  * set to the error message text if msg != 0. Otherwise, *msg will be
  * set to NULL. Caller doesn't need to free the error message.
  */
-JNIEXPORT jzfile * JNICALL
+JNIEXPORT jzfile *
 ZIP_Open(const char *name, char **pmsg)
 {
     jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
@@ -895,7 +895,7 @@
 /*
  * Closes the specified zip file object.
  */
-JNIEXPORT void JNICALL
+JNIEXPORT void
 ZIP_Close(jzfile *zip)
 {
     MLOCK(zfiles_lock);
@@ -1115,7 +1115,7 @@
  * Returns the zip entry corresponding to the specified name, or
  * NULL if not found.
  */
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
 {
     if (ulen == 0) {
@@ -1238,7 +1238,7 @@
  * Returns the n'th (starting at zero) zip file entry, or NULL if the
  * specified index was out of range.
  */
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_GetNextEntry(jzfile *zip, jint n)
 {
     jzentry *result;
@@ -1439,7 +1439,7 @@
  * The current implementation does not support reading an entry that
  * has the size bigger than 2**32 bytes in ONE invocation.
  */
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
 {
     jzentry *entry = ZIP_GetEntry(zip, name, 0);
@@ -1456,7 +1456,7 @@
  * Note: this is called from the separately delivered VM (hotspot/classic)
  * so we have to be careful to maintain the expected behaviour.
  */
-JNIEXPORT jboolean JNICALL
+JNIEXPORT jboolean
 ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
 {
     char *msg;
@@ -1515,7 +1515,7 @@
     return JNI_TRUE;
 }
 
-JNIEXPORT jboolean JNICALL
+JNIEXPORT jboolean
 ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg)
 {
     z_stream strm;
--- a/src/java.base/share/native/libzip/zip_util.h	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/share/native/libzip/zip_util.h	Tue Apr 24 10:20:22 2018 +0100
@@ -241,16 +241,16 @@
  */
 #define ZIP_ENDCHAIN ((jint)-1)
 
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP);
 
-JNIEXPORT jboolean JNICALL
+JNIEXPORT jboolean
 ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entrynm);
 
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_GetNextEntry(jzfile *zip, jint n);
 
-JNIEXPORT jzfile * JNICALL
+JNIEXPORT jzfile *
 ZIP_Open(const char *name, char **pmsg);
 
 jzfile *
@@ -265,10 +265,10 @@
 jzfile *
 ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, jboolean usemmap);
 
-JNIEXPORT void JNICALL
+JNIEXPORT void
 ZIP_Close(jzfile *zip);
 
-JNIEXPORT jzentry * JNICALL
+JNIEXPORT jzentry *
 ZIP_GetEntry(jzfile *zip, char *name, jint ulen);
 JNIEXPORT void JNICALL
 ZIP_Lock(jzfile *zip);
@@ -281,7 +281,7 @@
 jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
 jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
 
-JNIEXPORT jboolean JNICALL
+JNIEXPORT jboolean
 ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
 
 #endif /* !_ZIP_H_ */
--- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,7 @@
     hostname[0] = '\0';
     if (gethostname(hostname, NI_MAXHOST) != 0) {
         strcpy(hostname, "localhost");
+#if defined(__solaris__)
     } else {
         // try to resolve hostname via nameservice
         // if it is known but getnameinfo fails, hostname will still be the
@@ -86,6 +87,12 @@
             freeaddrinfo(res);
         }
     }
+#else
+    } else {
+        // make sure string is null-terminated
+        hostname[NI_MAXHOST] = '\0';
+    }
+#endif
     return (*env)->NewStringUTF(env, hostname);
 }
 
--- a/src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.net;
-
-import java.io.IOException;
-import java.io.FileDescriptor;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.misc.JavaIOFileDescriptorAccess;
-
-/**
- * This class defines the plain SocketImpl that is used on Windows platforms
- * greater or equal to Windows Vista. These platforms have a dual
- * layer TCP/IP stack and can handle both IPv4 and IPV6 through a
- * single file descriptor.
- *
- * @author Chris Hegarty
- */
-
-class DualStackPlainSocketImpl extends AbstractPlainSocketImpl {
-
-    private static final JavaIOFileDescriptorAccess fdAccess =
-        SharedSecrets.getJavaIOFileDescriptorAccess();
-
-    // true if this socket is exclusively bound
-    private final boolean exclusiveBind;
-
-    // emulates SO_REUSEADDR when exclusiveBind is true
-    private boolean isReuseAddress;
-
-    public DualStackPlainSocketImpl(boolean exclBind) {
-        exclusiveBind = exclBind;
-    }
-
-    public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
-        this.fd = fd;
-        exclusiveBind = exclBind;
-    }
-
-    void socketCreate(boolean stream) throws IOException {
-        if (fd == null)
-            throw new SocketException("Socket closed");
-
-        int newfd = socket0(stream, false /*v6 Only*/);
-
-        fdAccess.set(fd, newfd);
-    }
-
-    void socketConnect(InetAddress address, int port, int timeout)
-        throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (address == null)
-            throw new NullPointerException("inet address argument is null.");
-
-        int connectResult;
-        if (timeout <= 0) {
-            connectResult = connect0(nativefd, address, port);
-        } else {
-            configureBlocking(nativefd, false);
-            try {
-                connectResult = connect0(nativefd, address, port);
-                if (connectResult == WOULDBLOCK) {
-                    waitForConnect(nativefd, timeout);
-                }
-            } finally {
-                configureBlocking(nativefd, true);
-            }
-        }
-        /*
-         * We need to set the local port field. If bind was called
-         * previous to the connect (by the client) then localport field
-         * will already be set.
-         */
-        if (localport == 0)
-            localport = localPort0(nativefd);
-    }
-
-    void socketBind(InetAddress address, int port) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (address == null)
-            throw new NullPointerException("inet address argument is null.");
-
-        bind0(nativefd, address, port, exclusiveBind);
-        if (port == 0) {
-            localport = localPort0(nativefd);
-        } else {
-            localport = port;
-        }
-
-        this.address = address;
-    }
-
-    void socketListen(int backlog) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        listen0(nativefd, backlog);
-    }
-
-    void socketAccept(SocketImpl s) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (s == null)
-            throw new NullPointerException("socket is null");
-
-        int newfd = -1;
-        InetSocketAddress[] isaa = new InetSocketAddress[1];
-        if (timeout <= 0) {
-            newfd = accept0(nativefd, isaa);
-        } else {
-            configureBlocking(nativefd, false);
-            try {
-                waitForNewConnection(nativefd, timeout);
-                newfd = accept0(nativefd, isaa);
-                if (newfd != -1) {
-                    configureBlocking(newfd, true);
-                }
-            } finally {
-                configureBlocking(nativefd, true);
-            }
-        }
-        /* Update (SocketImpl)s' fd */
-        fdAccess.set(s.fd, newfd);
-        /* Update socketImpls remote port, address and localport */
-        InetSocketAddress isa = isaa[0];
-        s.port = isa.getPort();
-        s.address = isa.getAddress();
-        s.localport = localport;
-    }
-
-    int socketAvailable() throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        return available0(nativefd);
-    }
-
-    void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
-        if (fd == null)
-            throw new SocketException("Socket closed");
-
-        if (!fd.valid())
-            return;
-
-        final int nativefd = fdAccess.get(fd);
-        fdAccess.set(fd, -1);
-        close0(nativefd);
-    }
-
-    void socketShutdown(int howto) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        shutdown0(nativefd, howto);
-    }
-
-    // Intentional fallthrough after SO_REUSEADDR
-    @SuppressWarnings("fallthrough")
-    void socketSetOption(int opt, boolean on, Object value)
-        throws SocketException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (opt == SO_TIMEOUT) {  // timeout implemented through select.
-            return;
-        }
-        // SO_REUSEPORT is not supported on Windows.
-        if (opt == SO_REUSEPORT) {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-
-        int optionValue = 0;
-
-        switch(opt) {
-            case SO_REUSEADDR :
-                if (exclusiveBind) {
-                    // SO_REUSEADDR emulated when using exclusive bind
-                    isReuseAddress = on;
-                    return;
-                }
-                // intentional fallthrough
-            case TCP_NODELAY :
-            case SO_OOBINLINE :
-            case SO_KEEPALIVE :
-                optionValue = on ? 1 : 0;
-                break;
-            case SO_SNDBUF :
-            case SO_RCVBUF :
-            case IP_TOS :
-                optionValue = ((Integer)value).intValue();
-                break;
-            case SO_LINGER :
-                if (on) {
-                    optionValue =  ((Integer)value).intValue();
-                } else {
-                    optionValue = -1;
-                }
-                break;
-            default :/* shouldn't get here */
-                throw new SocketException("Option not supported");
-        }
-
-        setIntOption(nativefd, opt, optionValue);
-    }
-
-    int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
-        int nativefd = checkAndReturnNativeFD();
-
-        // SO_BINDADDR is not a socket option.
-        if (opt == SO_BINDADDR) {
-            localAddress(nativefd, (InetAddressContainer)iaContainerObj);
-            return 0;  // return value doesn't matter.
-        }
-        // SO_REUSEPORT is not supported on Windows.
-        if (opt == SO_REUSEPORT) {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-
-        // SO_REUSEADDR emulated when using exclusive bind
-        if (opt == SO_REUSEADDR && exclusiveBind)
-            return isReuseAddress? 1 : -1;
-
-        int value = getIntOption(nativefd, opt);
-
-        switch (opt) {
-            case TCP_NODELAY :
-            case SO_OOBINLINE :
-            case SO_KEEPALIVE :
-            case SO_REUSEADDR :
-                return (value == 0) ? -1 : 1;
-        }
-        return value;
-    }
-
-    void socketSendUrgentData(int data) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        sendOOB(nativefd, data);
-    }
-
-    private int checkAndReturnNativeFD() throws SocketException {
-        if (fd == null || !fd.valid())
-            throw new SocketException("Socket closed");
-
-        return fdAccess.get(fd);
-    }
-
-    static final int WOULDBLOCK = -2;       // Nothing available (non-blocking)
-
-    static {
-        initIDs();
-    }
-
-    /* Native methods */
-
-    static native void initIDs();
-
-    static native int socket0(boolean stream, boolean v6Only) throws IOException;
-
-    static native void bind0(int fd, InetAddress localAddress, int localport,
-                             boolean exclBind)
-        throws IOException;
-
-    static native int connect0(int fd, InetAddress remote, int remotePort)
-        throws IOException;
-
-    static native void waitForConnect(int fd, int timeout) throws IOException;
-
-    static native int localPort0(int fd) throws IOException;
-
-    static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
-
-    static native void listen0(int fd, int backlog) throws IOException;
-
-    static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
-
-    static native void waitForNewConnection(int fd, int timeout) throws IOException;
-
-    static native int available0(int fd) throws IOException;
-
-    static native void close0(int fd) throws IOException;
-
-    static native void shutdown0(int fd, int howto) throws IOException;
-
-    static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
-
-    static native int getIntOption(int fd, int cmd) throws SocketException;
-
-    static native void sendOOB(int fd, int data) throws IOException;
-
-    static native void configureBlocking(int fd, boolean blocking) throws IOException;
-}
--- a/src/java.base/windows/classes/java/net/PlainSocketImpl.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.base/windows/classes/java/net/PlainSocketImpl.java	Tue Apr 24 10:20:22 2018 +0100
@@ -24,310 +24,335 @@
  */
 package java.net;
 
-import java.io.*;
+import java.io.IOException;
+import java.io.FileDescriptor;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import sun.security.action.GetPropertyAction;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
 
-/*
- * This class PlainSocketImpl simply delegates to the appropriate real
- * SocketImpl. We do this because PlainSocketImpl is already extended
- * by SocksSocketImpl.
- * <p>
- * There are two possibilities for the real SocketImpl,
- * TwoStacksPlainSocketImpl or DualStackPlainSocketImpl. We use
- * DualStackPlainSocketImpl on systems that have a dual stack
- * TCP implementation. Otherwise we create an instance of
- * TwoStacksPlainSocketImpl and delegate to it.
+/**
+ * On Windows system we simply delegate to native methods.
  *
  * @author Chris Hegarty
  */
 
 class PlainSocketImpl extends AbstractPlainSocketImpl {
-    private AbstractPlainSocketImpl impl;
+
+    private static final JavaIOFileDescriptorAccess fdAccess =
+        SharedSecrets.getJavaIOFileDescriptorAccess();
 
-    /* java.net.preferIPv4Stack */
-    private static final boolean preferIPv4Stack;
+    private static final boolean preferIPv4Stack =
+            Boolean.parseBoolean(AccessController.doPrivileged(
+                new GetPropertyAction("java.net.preferIPv4Stack", "false")));
 
-    /* True if exclusive binding is on for Windows */
-    private static final boolean exclusiveBind;
+    /**
+     * Empty value of sun.net.useExclusiveBind is treated as 'true'.
+     */
+    private static final boolean useExclusiveBind;
 
     static {
-        preferIPv4Stack = Boolean.parseBoolean(
-        AccessController.doPrivileged(
-                new GetPropertyAction("java.net.preferIPv4Stack")));
-
         String exclBindProp = AccessController.doPrivileged(
                 new GetPropertyAction("sun.net.useExclusiveBind", ""));
-        exclusiveBind = (exclBindProp.isEmpty())
-                ? true
-                : Boolean.parseBoolean(exclBindProp);
+        useExclusiveBind = exclBindProp.isEmpty()
+                || Boolean.parseBoolean(exclBindProp);
     }
 
+    // emulates SO_REUSEADDR when useExclusiveBind is true
+    private boolean isReuseAddress;
+
     /**
      * Constructs an empty instance.
      */
-    PlainSocketImpl() {
-        if (!preferIPv4Stack) {
-            impl = new DualStackPlainSocketImpl(exclusiveBind);
-        } else {
-            impl = new TwoStacksPlainSocketImpl(exclusiveBind);
-        }
+    public PlainSocketImpl() {
     }
 
     /**
      * Constructs an instance with the given file descriptor.
      */
-    PlainSocketImpl(FileDescriptor fd) {
-        if (!preferIPv4Stack) {
-            impl = new DualStackPlainSocketImpl(fd, exclusiveBind);
-        } else {
-            impl = new TwoStacksPlainSocketImpl(fd, exclusiveBind);
-        }
-    }
-
-    // Override methods in SocketImpl that access impl's fields.
-
-    protected FileDescriptor getFileDescriptor() {
-        return impl.getFileDescriptor();
+    public PlainSocketImpl(FileDescriptor fd) {
+        this.fd = fd;
     }
 
-    protected InetAddress getInetAddress() {
-        return impl.getInetAddress();
-    }
+    @Override
+    void socketCreate(boolean stream) throws IOException {
+        if (fd == null)
+            throw new SocketException("Socket closed");
 
-    protected int getPort() {
-        return impl.getPort();
-    }
+        int newfd = socket0(stream);
 
-    protected int getLocalPort() {
-        return impl.getLocalPort();
-    }
-
-    void setSocket(Socket soc) {
-        impl.setSocket(soc);
+        fdAccess.set(fd, newfd);
     }
 
-    Socket getSocket() {
-        return impl.getSocket();
-    }
+    @Override
+    void socketConnect(InetAddress address, int port, int timeout)
+        throws IOException {
+        int nativefd = checkAndReturnNativeFD();
 
-    void setServerSocket(ServerSocket soc) {
-        impl.setServerSocket(soc);
-    }
+        if (address == null)
+            throw new NullPointerException("inet address argument is null.");
 
-    ServerSocket getServerSocket() {
-        return impl.getServerSocket();
-    }
+        if (preferIPv4Stack && !(address instanceof Inet4Address))
+            throw new SocketException("Protocol family not supported");
 
-    public String toString() {
-        return impl.toString();
-    }
-
-    // Override methods in AbstractPlainSocketImpl that access impl's fields.
-
-    protected synchronized void create(boolean stream) throws IOException {
-        impl.create(stream);
-
-        // set fd to delegate's fd to be compatible with older releases
-        this.fd = impl.fd;
-    }
-
-    protected void connect(String host, int port)
-        throws UnknownHostException, IOException
-    {
-        impl.connect(host, port);
+        int connectResult;
+        if (timeout <= 0) {
+            connectResult = connect0(nativefd, address, port);
+        } else {
+            configureBlocking(nativefd, false);
+            try {
+                connectResult = connect0(nativefd, address, port);
+                if (connectResult == WOULDBLOCK) {
+                    waitForConnect(nativefd, timeout);
+                }
+            } finally {
+                configureBlocking(nativefd, true);
+            }
+        }
+        /*
+         * We need to set the local port field. If bind was called
+         * previous to the connect (by the client) then localport field
+         * will already be set.
+         */
+        if (localport == 0)
+            localport = localPort0(nativefd);
     }
 
-    protected void connect(InetAddress address, int port) throws IOException {
-        impl.connect(address, port);
-    }
+    @Override
+    void socketBind(InetAddress address, int port) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+
+        if (address == null)
+            throw new NullPointerException("inet address argument is null.");
 
-    protected void connect(SocketAddress address, int timeout) throws IOException {
-        impl.connect(address, timeout);
+        if (preferIPv4Stack && !(address instanceof Inet4Address))
+            throw new SocketException("Protocol family not supported");
+
+        bind0(nativefd, address, port, useExclusiveBind);
+        if (port == 0) {
+            localport = localPort0(nativefd);
+        } else {
+            localport = port;
+        }
+
+        this.address = address;
     }
 
-    public void setOption(int opt, Object val) throws SocketException {
-        if (opt == SocketOptions.SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        }
-        impl.setOption(opt, val);
-    }
+    @Override
+    void socketListen(int backlog) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
 
-    public Object getOption(int opt) throws SocketException {
-        if (opt == SocketOptions.SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        }
-        return impl.getOption(opt);
-    }
-
-    synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
-        impl.doConnect(address, port, timeout);
+        listen0(nativefd, backlog);
     }
 
-    protected synchronized void bind(InetAddress address, int lport)
-        throws IOException
-    {
-        impl.bind(address, lport);
+    @Override
+    void socketAccept(SocketImpl s) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+
+        if (s == null)
+            throw new NullPointerException("socket is null");
+
+        int newfd = -1;
+        InetSocketAddress[] isaa = new InetSocketAddress[1];
+        if (timeout <= 0) {
+            newfd = accept0(nativefd, isaa);
+        } else {
+            configureBlocking(nativefd, false);
+            try {
+                waitForNewConnection(nativefd, timeout);
+                newfd = accept0(nativefd, isaa);
+                if (newfd != -1) {
+                    configureBlocking(newfd, true);
+                }
+            } finally {
+                configureBlocking(nativefd, true);
+            }
+        }
+        /* Update (SocketImpl)s' fd */
+        fdAccess.set(s.fd, newfd);
+        /* Update socketImpls remote port, address and localport */
+        InetSocketAddress isa = isaa[0];
+        s.port = isa.getPort();
+        s.address = isa.getAddress();
+        s.localport = localport;
+        if (preferIPv4Stack && !(s.address instanceof Inet4Address))
+            throw new SocketException("Protocol family not supported");
     }
 
-    protected synchronized void accept(SocketImpl s) throws IOException {
-        if (s instanceof PlainSocketImpl) {
-            // pass in the real impl not the wrapper.
-            SocketImpl delegate = ((PlainSocketImpl)s).impl;
-            delegate.address = new InetAddress();
-            delegate.fd = new FileDescriptor();
-            impl.accept(delegate);
-            // set fd to delegate's fd to be compatible with older releases
-            s.fd = delegate.fd;
-        } else {
-            impl.accept(s);
-        }
+    @Override
+    int socketAvailable() throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        return available0(nativefd);
     }
 
-    void setFileDescriptor(FileDescriptor fd) {
-        impl.setFileDescriptor(fd);
+    @Override
+    void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
+        if (fd == null)
+            throw new SocketException("Socket closed");
+
+        if (!fd.valid())
+            return;
+
+        final int nativefd = fdAccess.get(fd);
+        fdAccess.set(fd, -1);
+        close0(nativefd);
     }
 
-    void setAddress(InetAddress address) {
-        impl.setAddress(address);
-    }
-
-    void setPort(int port) {
-        impl.setPort(port);
-    }
-
-    void setLocalPort(int localPort) {
-        impl.setLocalPort(localPort);
+    @Override
+    void socketShutdown(int howto) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        shutdown0(nativefd, howto);
     }
 
-    protected synchronized InputStream getInputStream() throws IOException {
-        return impl.getInputStream();
-    }
+    // Intentional fallthrough after SO_REUSEADDR
+    @SuppressWarnings("fallthrough")
+    @Override
+    void socketSetOption(int opt, boolean on, Object value)
+        throws SocketException {
 
-    void setInputStream(SocketInputStream in) {
-        impl.setInputStream(in);
-    }
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
 
-    protected synchronized OutputStream getOutputStream() throws IOException {
-        return impl.getOutputStream();
-    }
+        int nativefd = checkAndReturnNativeFD();
 
-    protected void close() throws IOException {
-        try {
-            impl.close();
-        } finally {
-            // set fd to delegate's fd to be compatible with older releases
-            this.fd = null;
+        if (opt == SO_TIMEOUT) {
+            if (preferIPv4Stack) {
+                // Don't enable the socket option on ServerSocket as it's
+                // meaningless (we don't receive on a ServerSocket).
+                if (serverSocket == null) {
+                    setSoTimeout0(nativefd, ((Integer)value).intValue());
+                }
+            } // else timeout is implemented through select.
+            return;
         }
-    }
 
-    void reset() throws IOException {
-        try {
-            impl.reset();
-        } finally {
-            // set fd to delegate's fd to be compatible with older releases
-            this.fd = null;
-        }
-    }
+        int optionValue = 0;
 
-    protected void shutdownInput() throws IOException {
-        impl.shutdownInput();
-    }
-
-    protected void shutdownOutput() throws IOException {
-        impl.shutdownOutput();
-    }
-
-    protected void sendUrgentData(int data) throws IOException {
-        impl.sendUrgentData(data);
-    }
+        switch(opt) {
+            case SO_REUSEADDR:
+                if (useExclusiveBind) {
+                    // SO_REUSEADDR emulated when using exclusive bind
+                    isReuseAddress = on;
+                    return;
+                }
+                // intentional fallthrough
+            case TCP_NODELAY:
+            case SO_OOBINLINE:
+            case SO_KEEPALIVE:
+                optionValue = on ? 1 : 0;
+                break;
+            case SO_SNDBUF:
+            case SO_RCVBUF:
+            case IP_TOS:
+                optionValue = ((Integer)value).intValue();
+                break;
+            case SO_LINGER:
+                if (on) {
+                    optionValue = ((Integer)value).intValue();
+                } else {
+                    optionValue = -1;
+                }
+                break;
+            default :/* shouldn't get here */
+                throw new SocketException("Option not supported");
+        }
 
-    FileDescriptor acquireFD() {
-        return impl.acquireFD();
-    }
-
-    void releaseFD() {
-        impl.releaseFD();
-    }
-
-    boolean isConnectionReset() {
-        return impl.isConnectionReset();
-    }
-
-    void setConnectionReset() {
-        impl.setConnectionReset();
-    }
-
-    public boolean isClosedOrPending() {
-        return impl.isClosedOrPending();
+        setIntOption(nativefd, opt, optionValue);
     }
 
-    public int getTimeout() {
-        return impl.getTimeout();
-    }
+    @Override
+    int socketGetOption(int opt, Object iaContainerObj)
+        throws SocketException {
 
-    // Override methods in AbstractPlainSocketImpl that need to be implemented.
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+
+        int nativefd = checkAndReturnNativeFD();
 
-    void socketCreate(boolean isServer) throws IOException {
-        impl.socketCreate(isServer);
-    }
+        // SO_BINDADDR is not a socket option.
+        if (opt == SO_BINDADDR) {
+            localAddress(nativefd, (InetAddressContainer)iaContainerObj);
+            return 0;  // return value doesn't matter.
+        }
+
+        // SO_REUSEADDR emulated when using exclusive bind
+        if (opt == SO_REUSEADDR && useExclusiveBind)
+            return isReuseAddress ? 1 : -1;
 
-    void socketConnect(InetAddress address, int port, int timeout)
-        throws IOException {
-        impl.socketConnect(address, port, timeout);
+        int value = getIntOption(nativefd, opt);
+
+        switch (opt) {
+            case TCP_NODELAY:
+            case SO_OOBINLINE:
+            case SO_KEEPALIVE:
+            case SO_REUSEADDR:
+                return (value == 0) ? -1 : 1;
+        }
+        return value;
     }
 
-    void socketBind(InetAddress address, int port)
-        throws IOException {
-        impl.socketBind(address, port);
+    @Override
+    void socketSendUrgentData(int data) throws IOException {
+        int nativefd = checkAndReturnNativeFD();
+        sendOOB(nativefd, data);
     }
 
-    void socketListen(int count) throws IOException {
-        impl.socketListen(count);
-    }
+    private int checkAndReturnNativeFD() throws SocketException {
+        if (fd == null || !fd.valid())
+            throw new SocketException("Socket closed");
 
-    void socketAccept(SocketImpl s) throws IOException {
-        impl.socketAccept(s);
-    }
-
-    int socketAvailable() throws IOException {
-        return impl.socketAvailable();
+        return fdAccess.get(fd);
     }
 
-    void socketClose0(boolean useDeferredClose) throws IOException {
-        impl.socketClose0(useDeferredClose);
-    }
-
-    void socketShutdown(int howto) throws IOException {
-        impl.socketShutdown(howto);
-    }
+    static final int WOULDBLOCK = -2;       // Nothing available (non-blocking)
 
-    void socketSetOption(int cmd, boolean on, Object value)
-        throws SocketException {
-        if (cmd == SocketOptions.SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        }
-        impl.socketSetOption(cmd, on, value);
+    static {
+        initIDs();
     }
 
-    int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
-        if (opt == SocketOptions.SO_REUSEPORT) {
-            // SO_REUSEPORT is not supported on Windows.
-            throw new UnsupportedOperationException("unsupported option");
-        }
-        return impl.socketGetOption(opt, iaContainerObj);
-    }
+    /* Native methods */
+
+    static native void initIDs();
+
+    static native int socket0(boolean stream) throws IOException;
+
+    static native void bind0(int fd, InetAddress localAddress, int localport,
+                             boolean exclBind)
+        throws IOException;
+
+    static native int connect0(int fd, InetAddress remote, int remotePort)
+        throws IOException;
+
+    static native void waitForConnect(int fd, int timeout) throws IOException;
+
+    static native int localPort0(int fd) throws IOException;
+
+    static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
+
+    static native void listen0(int fd, int backlog) throws IOException;
 
-    void socketSendUrgentData(int data) throws IOException {
-        impl.socketSendUrgentData(data);
-    }
+    static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
+
+    static native void waitForNewConnection(int fd, int timeout) throws IOException;
+
+    static native int available0(int fd) throws IOException;
+
+    static native void close0(int fd) throws IOException;
+
+    static native void shutdown0(int fd, int howto) throws IOException;
 
-    static boolean isReusePortAvailable() {
-        // SO_REUSEPORT is not supported on Windows.
-        return false;
-    }
+    static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
+
+    static native void setSoTimeout0(int fd, int timeout) throws SocketException;
+
+    static native int getIntOption(int fd, int cmd) throws SocketException;
+
+    static native void sendOOB(int fd, int data) throws IOException;
+
+    static native void configureBlocking(int fd, boolean blocking) throws IOException;
 }
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.net;
-
-import java.io.IOException;
-import java.io.FileDescriptor;
-import sun.net.ResourceManager;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.misc.JavaIOFileDescriptorAccess;
-
-/*
- * This class defines the plain SocketImpl that is used when
- * the System property java.net.preferIPv4Stack is set to true.
- *
- * @author Chris Hegarty
- */
-
-class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl {
-
-    private static final JavaIOFileDescriptorAccess fdAccess =
-        SharedSecrets.getJavaIOFileDescriptorAccess();
-
-    // true if this socket is exclusively bound
-    private final boolean exclusiveBind;
-
-    // emulates SO_REUSEADDR when exclusiveBind is true
-    private boolean isReuseAddress;
-
-    public TwoStacksPlainSocketImpl(boolean exclBind) {
-        exclusiveBind = exclBind;
-    }
-
-    public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) {
-        this.fd = fd;
-        exclusiveBind = exclBind;
-    }
-
-    void socketCreate(boolean stream) throws IOException {
-        if (fd == null)
-            throw new SocketException("Socket closed");
-
-        int newfd = socket0(stream, false /*v6 Only*/);
-
-        fdAccess.set(fd, newfd);
-    }
-
-    @Override
-    void socketConnect(InetAddress address, int port, int timeout)
-        throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (address == null)
-            throw new NullPointerException("inet address argument is null.");
-
-        int connectResult;
-        if (timeout <= 0) {
-            connectResult = connect0(nativefd, address, port);
-        } else {
-            configureBlocking(nativefd, false);
-            try {
-                connectResult = connect0(nativefd, address, port);
-                if (connectResult == WOULDBLOCK) {
-                    waitForConnect(nativefd, timeout);
-                }
-            } finally {
-                configureBlocking(nativefd, true);
-            }
-        }
-        /*
-         * We need to set the local port field. If bind was called
-         * previous to the connect (by the client) then localport field
-         * will already be set.
-         */
-        if (localport == 0)
-            localport = localPort0(nativefd);
-    }
-
-    @Override
-    void socketBind(InetAddress address, int port) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (address == null)
-            throw new NullPointerException("inet address argument is null.");
-
-        bind0(nativefd, address, port, exclusiveBind);
-        if (port == 0) {
-            localport = localPort0(nativefd);
-        } else {
-            localport = port;
-        }
-
-        this.address = address;
-    }
-
-    @Override
-    void socketListen(int backlog) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        listen0(nativefd, backlog);
-    }
-
-    @Override
-    void socketAccept(SocketImpl s) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (s == null)
-            throw new NullPointerException("socket is null");
-
-        int newfd = -1;
-        InetSocketAddress[] isaa = new InetSocketAddress[1];
-        if (timeout <= 0) {
-            newfd = accept0(nativefd, isaa);
-        } else {
-            configureBlocking(nativefd, false);
-            try {
-                waitForNewConnection(nativefd, timeout);
-                newfd = accept0(nativefd, isaa);
-                if (newfd != -1) {
-                    configureBlocking(newfd, true);
-                }
-            } finally {
-                configureBlocking(nativefd, true);
-            }
-        }
-        /* Update (SocketImpl)s' fd */
-        fdAccess.set(s.fd, newfd);
-        /* Update socketImpls remote port, address and localport */
-        InetSocketAddress isa = isaa[0];
-        s.port = isa.getPort();
-        s.address = isa.getAddress();
-        s.localport = localport;
-    }
-
-    @Override
-    int socketAvailable() throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        return available0(nativefd);
-    }
-
-    @Override
-    void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
-        if (fd == null)
-            throw new SocketException("Socket closed");
-
-        if (!fd.valid())
-            return;
-
-        final int nativefd = fdAccess.get(fd);
-        fdAccess.set(fd, -1);
-        close0(nativefd);
-    }
-
-    @Override
-    void socketShutdown(int howto) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        shutdown0(nativefd, howto);
-    }
-
-    // Intentional fallthrough after SO_REUSEADDR
-    @SuppressWarnings("fallthrough")
-    @Override
-    void socketSetOption(int opt, boolean on, Object value)
-        throws SocketException {
-        int nativefd = checkAndReturnNativeFD();
-
-        if (opt == SO_TIMEOUT) {
-            // Don't enable the socket option on ServerSocket as it's
-            // meaningless (we don't receive on a ServerSocket).
-            if (serverSocket == null) {
-                setSoTimeout0(nativefd, ((Integer)value).intValue());
-            }
-            return;
-        }
-        // SO_REUSEPORT is not supported on Windows.
-        if (opt == SO_REUSEPORT) {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-
-        int optionValue = 0;
-
-        switch(opt) {
-            case SO_REUSEADDR :
-                if (exclusiveBind) {
-                    // SO_REUSEADDR emulated when using exclusive bind
-                    isReuseAddress = on;
-                    return;
-                }
-                // intentional fallthrough
-            case TCP_NODELAY :
-            case SO_OOBINLINE :
-            case SO_KEEPALIVE :
-                optionValue = on ? 1 : 0;
-                break;
-            case SO_SNDBUF :
-            case SO_RCVBUF :
-            case IP_TOS :
-                optionValue = ((Integer)value).intValue();
-                break;
-            case SO_LINGER :
-                if (on) {
-                    optionValue =  ((Integer)value).intValue();
-                } else {
-                    optionValue = -1;
-                }
-                break;
-            default :/* shouldn't get here */
-                throw new SocketException("Option not supported");
-        }
-
-        setIntOption(nativefd, opt, optionValue);
-    }
-
-    @Override
-    int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
-        int nativefd = checkAndReturnNativeFD();
-
-        // SO_BINDADDR is not a socket option.
-        if (opt == SO_BINDADDR) {
-            localAddress(nativefd, (InetAddressContainer)iaContainerObj);
-            return 0;  // return value doesn't matter.
-        }
-        // SO_REUSEPORT is not supported on Windows.
-        if (opt == SO_REUSEPORT) {
-            throw new UnsupportedOperationException("unsupported option");
-        }
-
-        // SO_REUSEADDR emulated when using exclusive bind
-        if (opt == SO_REUSEADDR && exclusiveBind)
-            return isReuseAddress? 1 : -1;
-
-        int value = getIntOption(nativefd, opt);
-
-        switch (opt) {
-            case TCP_NODELAY :
-            case SO_OOBINLINE :
-            case SO_KEEPALIVE :
-            case SO_REUSEADDR :
-                return (value == 0) ? -1 : 1;
-        }
-        return value;
-    }
-
-    @Override
-    void socketSendUrgentData(int data) throws IOException {
-        int nativefd = checkAndReturnNativeFD();
-        sendOOB(nativefd, data);
-    }
-
-    private int checkAndReturnNativeFD() throws SocketException {
-        if (fd == null || !fd.valid())
-            throw new SocketException("Socket closed");
-
-        return fdAccess.get(fd);
-    }
-
-    static final int WOULDBLOCK = -2;       // Nothing available (non-blocking)
-
-    static {
-        initIDs();
-    }
-
-    /* Native methods */
-
-    static native void initIDs();
-
-    static native int socket0(boolean stream, boolean v6Only) throws IOException;
-
-    static native void bind0(int fd, InetAddress localAddress, int localport,
-                             boolean exclBind)
-        throws IOException;
-
-    static native int connect0(int fd, InetAddress remote, int remotePort)
-        throws IOException;
-
-    static native void waitForConnect(int fd, int timeout) throws IOException;
-
-    static native int localPort0(int fd) throws IOException;
-
-    static native void localAddress(int fd, InetAddressContainer in) throws SocketException;
-
-    static native void listen0(int fd, int backlog) throws IOException;
-
-    static native int accept0(int fd, InetSocketAddress[] isaa) throws IOException;
-
-    static native void waitForNewConnection(int fd, int timeout) throws IOException;
-
-    static native int available0(int fd) throws IOException;
-
-    static native void close0(int fd) throws IOException;
-
-    static native void shutdown0(int fd, int howto) throws IOException;
-
-    static native void setIntOption(int fd, int cmd, int optionValue) throws SocketException;
-
-    static native void setSoTimeout0(int fd, int timeout) throws SocketException;
-
-    static native int getIntOption(int fd, int cmd) throws SocketException;
-
-    static native void sendOOB(int fd, int data) throws IOException;
-
-    static native void configureBlocking(int fd, boolean blocking) throws IOException;
-}
--- a/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,478 +0,0 @@
-/*
- * 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
- * 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 "net_util.h"
-
-#include "java_net_DualStackPlainSocketImpl.h"
-#include "java_net_SocketOptions.h"
-
-#define SET_BLOCKING 0
-#define SET_NONBLOCKING 1
-
-static jclass isa_class;        /* java.net.InetSocketAddress */
-static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_initIDs
-  (JNIEnv *env, jclass clazz) {
-
-    jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-    CHECK_NULL(cls);
-    isa_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(isa_class);
-    isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
-                                     "(Ljava/net/InetAddress;I)V");
-    CHECK_NULL(isa_ctorID);
-    initInetAddressIDs(env);
-
-    // implement read timeout with select.
-    isRcvTimeoutSupported = JNI_FALSE;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    socket0
- * Signature: (ZZ)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_socket0
-  (JNIEnv *env, jclass clazz, jboolean stream, jboolean v6Only /*unused*/) {
-    int fd, rv, opt=0;
-
-    fd = NET_Socket(AF_INET6, (stream ? SOCK_STREAM : SOCK_DGRAM), 0);
-    if (fd == INVALID_SOCKET) {
-        NET_ThrowNew(env, WSAGetLastError(), "create");
-        return -1;
-    }
-
-    rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
-    if (rv == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "create");
-    }
-
-    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
-
-    return fd;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    bind0
- * Signature: (ILjava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_bind0
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port,
-   jboolean exclBind)
-{
-    SOCKETADDRESS sa;
-    int rv, sa_len = 0;
-
-    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
-                                  &sa_len, JNI_TRUE) != 0) {
-      return;
-    }
-
-    rv = NET_WinBind(fd, &sa, sa_len, exclBind);
-
-    if (rv == SOCKET_ERROR)
-        NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    connect0
- * Signature: (ILjava/net/InetAddress;I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_connect0
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
-    SOCKETADDRESS sa;
-    int rv, sa_len = 0;
-
-    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
-                                  &sa_len, JNI_TRUE) != 0) {
-      return -1;
-    }
-
-    rv = connect(fd, &sa.sa, sa_len);
-    if (rv == SOCKET_ERROR) {
-        int err = WSAGetLastError();
-        if (err == WSAEWOULDBLOCK) {
-            return java_net_DualStackPlainSocketImpl_WOULDBLOCK;
-        } else if (err == WSAEADDRNOTAVAIL) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
-                "connect: Address is invalid on local machine, or port is not valid on remote machine");
-        } else {
-            NET_ThrowNew(env, err, "connect");
-        }
-        return -1;  // return value not important.
-    }
-    return rv;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    waitForConnect
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForConnect
-  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
-    int rv, retry;
-    int optlen = sizeof(rv);
-    fd_set wr, ex;
-    struct timeval t;
-
-    FD_ZERO(&wr);
-    FD_ZERO(&ex);
-    FD_SET(fd, &wr);
-    FD_SET(fd, &ex);
-    t.tv_sec = timeout / 1000;
-    t.tv_usec = (timeout % 1000) * 1000;
-
-    /*
-     * Wait for timeout, connection established or
-     * connection failed.
-     */
-    rv = select(fd+1, 0, &wr, &ex, &t);
-
-    /*
-     * Timeout before connection is established/failed so
-     * we throw exception and shutdown input/output to prevent
-     * socket from being used.
-     * The socket should be closed immediately by the caller.
-     */
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                        "connect timed out");
-        shutdown( fd, SD_BOTH );
-        return;
-    }
-
-    /*
-     * Socket is writable or error occurred. On some Windows editions
-     * the socket will appear writable when the connect fails so we
-     * check for error rather than writable.
-     */
-    if (!FD_ISSET(fd, &ex)) {
-        return;         /* connection established */
-    }
-
-    /*
-     * Connection failed. The logic here is designed to work around
-     * bug on Windows NT whereby using getsockopt to obtain the
-     * last error (SO_ERROR) indicates there is no error. The workaround
-     * on NT is to allow winsock to be scheduled and this is done by
-     * yielding and retrying. As yielding is problematic in heavy
-     * load conditions we attempt up to 3 times to get the error reason.
-     */
-    for (retry=0; retry<3; retry++) {
-        NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
-                       (char*)&rv, &optlen);
-        if (rv) {
-            break;
-        }
-        Sleep(0);
-    }
-
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Unable to establish connection");
-    } else {
-        NET_ThrowNew(env, rv, "connect");
-    }
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    localPort0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_localPort0
-  (JNIEnv *env, jclass clazz, jint fd) {
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-
-    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
-        if (WSAGetLastError() == WSAENOTSOCK) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                    "Socket closed");
-        } else {
-            NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
-        }
-        return -1;
-    }
-    return (int) ntohs((u_short)GET_PORT(&sa));
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    localAddress
- * Signature: (ILjava/net/InetAddressContainer;)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_localAddress
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
-    int port;
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-    jobject iaObj;
-    jclass iaContainerClass;
-    jfieldID iaFieldID;
-
-    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
-        return;
-    }
-    iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
-    CHECK_NULL(iaObj);
-
-    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
-    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
-    CHECK_NULL(iaFieldID);
-    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
-}
-
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    listen0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_listen0
-  (JNIEnv *env, jclass clazz, jint fd, jint backlog) {
-    if (listen(fd, backlog) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "listen failed");
-    }
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    accept0
- * Signature: (I[Ljava/net/InetSocketAddress;)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_accept0
-  (JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) {
-    int newfd, port=0;
-    jobject isa;
-    jobject ia;
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-
-    memset((char *)&sa, 0, len);
-    newfd = accept(fd, &sa.sa, &len);
-
-    if (newfd == INVALID_SOCKET) {
-        if (WSAGetLastError() == -2) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-        } else {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "socket closed");
-        }
-        return -1;
-    }
-
-    SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
-
-    ia = NET_SockaddrToInetAddress(env, &sa, &port);
-    isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
-    (*env)->SetObjectArrayElement(env, isaa, 0, isa);
-
-    return newfd;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    waitForNewConnection
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_waitForNewConnection
-  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
-    int rv;
-
-    rv = NET_Timeout(fd, timeout);
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                        "Accept timed out");
-    } else if (rv == -1) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
-    } else if (rv == -2) {
-        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                        "operation interrupted");
-    }
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    available0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_available0
-  (JNIEnv *env, jclass clazz, jint fd) {
-    jint available = -1;
-
-    if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "socket available");
-    }
-
-    return available;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    close0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_close0
-  (JNIEnv *env, jclass clazz, jint fd) {
-     NET_SocketClose(fd);
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    shutdown0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_shutdown0
-  (JNIEnv *env, jclass clazz, jint fd, jint howto) {
-    shutdown(fd, howto);
-}
-
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    setIntOption
- * Signature: (III)V
- */
-JNIEXPORT void JNICALL
-Java_java_net_DualStackPlainSocketImpl_setIntOption
-  (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
-{
-    int level = 0, opt = 0;
-    struct linger linger = {0, 0};
-    char *parg;
-    int arglen;
-
-    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        parg = (char *)&linger;
-        arglen = sizeof(linger);
-        if (value >= 0) {
-            linger.l_onoff = 1;
-            linger.l_linger = (unsigned short)value;
-        } else {
-            linger.l_onoff = 0;
-            linger.l_linger = 0;
-        }
-    } else {
-        parg = (char *)&value;
-        arglen = sizeof(value);
-    }
-
-    if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
-        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
-    }
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    getIntOption
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption
-  (JNIEnv *env, jclass clazz, jint fd, jint cmd)
-{
-    int level = 0, opt = 0;
-    int result=0;
-    struct linger linger = {0, 0};
-    char *arg;
-    int arglen;
-
-    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        arg = (char *)&linger;
-        arglen = sizeof(linger);
-    } else {
-        arg = (char *)&result;
-        arglen = sizeof(result);
-    }
-
-    if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
-        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER)
-        return linger.l_onoff ? linger.l_linger : -1;
-    else
-        return result;
-}
-
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    sendOOB
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_sendOOB
-  (JNIEnv *env, jclass clazz, jint fd, jint data) {
-    jint n;
-    unsigned char d = (unsigned char) data & 0xff;
-
-    n = send(fd, (char *)&data, 1, MSG_OOB);
-    if (n == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "send");
-    }
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
- * Method:    configureBlocking
- * Signature: (IZ)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_configureBlocking
-  (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
-    u_long arg;
-    int result;
-
-    if (blocking == JNI_TRUE) {
-        arg = SET_BLOCKING;    // 0
-    } else {
-        arg = SET_NONBLOCKING;   // 1
-    }
-
-    result = ioctlsocket(fd, FIONBIO, &arg);
-    if (result == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/windows/native/libnet/PlainSocketImpl.c	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 "net_util.h"
+
+#include "java_net_PlainSocketImpl.h"
+#include "java_net_SocketOptions.h"
+
+#define SET_BLOCKING     0
+#define SET_NONBLOCKING  1
+
+static jclass isa_class;        /* java.net.InetSocketAddress */
+static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_initIDs
+  (JNIEnv *env, jclass clazz) {
+
+    jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+    CHECK_NULL(cls);
+    isa_class = (*env)->NewGlobalRef(env, cls);
+    CHECK_NULL(isa_class);
+    isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
+                                     "(Ljava/net/InetAddress;I)V");
+    CHECK_NULL(isa_ctorID);
+    initInetAddressIDs(env);
+
+    // implement read timeout with select.
+    isRcvTimeoutSupported = JNI_FALSE;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    socket0
+ * Signature: (ZZ)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_socket0
+  (JNIEnv *env, jclass clazz, jboolean stream) {
+    int fd, rv, opt = 0;
+    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+    int domain = ipv6_available() ? AF_INET6 : AF_INET;
+
+    fd = NET_Socket(domain, type, 0);
+
+    if (fd == INVALID_SOCKET) {
+        NET_ThrowNew(env, WSAGetLastError(), "create");
+        return -1;
+    }
+
+    if (domain == AF_INET6) {
+        rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt,
+                        sizeof(opt));
+        if (rv == SOCKET_ERROR) {
+            NET_ThrowNew(env, WSAGetLastError(), "create");
+            closesocket(fd);
+            return -1;
+        }
+    }
+
+    return fd;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    bind0
+ * Signature: (ILjava/net/InetAddress;I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_bind0
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port,
+   jboolean exclBind)
+{
+    SOCKETADDRESS sa;
+    int rv, sa_len = 0;
+    jboolean v4MappedAddress = ipv6_available() ? JNI_TRUE : JNI_FALSE;
+
+    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+                                  &sa_len, v4MappedAddress) != 0) {
+        return;
+    }
+
+    rv = NET_WinBind(fd, &sa, sa_len, exclBind);
+
+    if (rv == SOCKET_ERROR)
+        NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    connect0
+ * Signature: (ILjava/net/InetAddress;I)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_connect0
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
+    SOCKETADDRESS sa;
+    int rv, sa_len = 0;
+    jboolean v4MappedAddress = ipv6_available() ? JNI_TRUE : JNI_FALSE;
+
+    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
+                                  &sa_len, v4MappedAddress) != 0) {
+        return -1;
+    }
+
+    rv = connect(fd, &sa.sa, sa_len);
+    if (rv == SOCKET_ERROR) {
+        int err = WSAGetLastError();
+        if (err == WSAEWOULDBLOCK) {
+            return java_net_PlainSocketImpl_WOULDBLOCK;
+        } else if (err == WSAEADDRNOTAVAIL) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
+                "connect: Address is invalid on local machine,"
+                " or port is not valid on remote machine");
+        } else {
+            NET_ThrowNew(env, err, "connect");
+        }
+        // return value not important.
+    }
+    return rv;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    waitForConnect
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_waitForConnect
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
+    int rv, retry;
+    int optlen = sizeof(rv);
+    fd_set wr, ex;
+    struct timeval t;
+
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+    FD_SET(fd, &wr);
+    FD_SET(fd, &ex);
+    t.tv_sec = timeout / 1000;
+    t.tv_usec = (timeout % 1000) * 1000;
+
+    /*
+     * Wait for timeout, connection established or
+     * connection failed.
+     */
+    rv = select(fd+1, 0, &wr, &ex, &t);
+
+    /*
+     * Timeout before connection is established/failed so
+     * we throw exception and shutdown input/output to prevent
+     * socket from being used.
+     * The socket should be closed immediately by the caller.
+     */
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                        "connect timed out");
+        shutdown(fd, SD_BOTH);
+        return;
+    }
+
+    /*
+     * Socket is writable or error occurred. On some Windows editions
+     * the socket will appear writable when the connect fails so we
+     * check for error rather than writable.
+     */
+    if (!FD_ISSET(fd, &ex)) {
+        return;         /* connection established */
+    }
+
+    /*
+     * Connection failed. The logic here is designed to work around
+     * bug on Windows NT whereby using getsockopt to obtain the
+     * last error (SO_ERROR) indicates there is no error. The workaround
+     * on NT is to allow winsock to be scheduled and this is done by
+     * yielding and retrying. As yielding is problematic in heavy
+     * load conditions we attempt up to 3 times to get the error reason.
+     */
+    for (retry = 0; retry < 3; retry++) {
+        NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
+                       (char*)&rv, &optlen);
+        if (rv) {
+            break;
+        }
+        Sleep(0);
+    }
+
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Unable to establish connection");
+    } else if (!ipv6_available() && rv == WSAEADDRNOTAVAIL) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
+                        "connect: Address is invalid on local machine,"
+                        " or port is not valid on remote machine");
+    } else {
+        NET_ThrowNew(env, rv, "connect");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    localPort0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_localPort0
+  (JNIEnv *env, jclass clazz, jint fd) {
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
+
+    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
+        if (WSAGetLastError() == WSAENOTSOCK) {
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                    "Socket closed");
+        } else {
+            NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
+        }
+        return -1;
+    }
+    return (int) ntohs((u_short)GET_PORT(&sa));
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    localAddress
+ * Signature: (ILjava/net/InetAddressContainer;)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_localAddress
+  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
+    int port;
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
+    jobject iaObj;
+    jclass iaContainerClass;
+    jfieldID iaFieldID;
+
+    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
+        return;
+    }
+    iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
+    CHECK_NULL(iaObj);
+
+    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
+    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
+    CHECK_NULL(iaFieldID);
+    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    listen0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_listen0
+  (JNIEnv *env, jclass clazz, jint fd, jint backlog) {
+    if (listen(fd, backlog) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "listen failed");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    accept0
+ * Signature: (I[Ljava/net/InetSocketAddress;)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_accept0
+  (JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) {
+    int newfd, port = 0;
+    jobject isa;
+    jobject ia;
+    SOCKETADDRESS sa;
+    int len = sizeof(sa);
+
+    memset((char *)&sa, 0, len);
+    newfd = accept(fd, &sa.sa, &len);
+
+    if (newfd == INVALID_SOCKET) {
+        NET_ThrowNew(env, WSAGetLastError(), "accept failed");
+        return -1;
+    }
+
+    SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
+
+    ia = NET_SockaddrToInetAddress(env, &sa, &port);
+    isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
+    if (isa == NULL) {
+        closesocket(newfd);
+        return -1;
+    }
+    (*env)->SetObjectArrayElement(env, isaa, 0, isa);
+
+    return newfd;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    waitForNewConnection
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_waitForNewConnection
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
+    int rv;
+
+    rv = NET_Timeout(fd, timeout);
+    if (rv == 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                        "Accept timed out");
+    } else if (rv == -1) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+    } else if (rv == -2) {
+        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+                        "operation interrupted");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    available0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_available0
+  (JNIEnv *env, jclass clazz, jint fd) {
+    jint available = -1;
+
+    if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "socket available");
+    }
+
+    return available;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    close0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_close0
+  (JNIEnv *env, jclass clazz, jint fd) {
+     NET_SocketClose(fd);
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    shutdown0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_shutdown0
+  (JNIEnv *env, jclass clazz, jint fd, jint howto) {
+    shutdown(fd, howto);
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    setIntOption
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_setIntOption
+  (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
+{
+    int level = 0, opt = 0;
+    struct linger linger = {0, 0};
+    char *parg;
+    int arglen;
+
+    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
+        return;
+    }
+
+    if (opt == java_net_SocketOptions_SO_LINGER) {
+        parg = (char *)&linger;
+        arglen = sizeof(linger);
+        if (value >= 0) {
+            linger.l_onoff = 1;
+            linger.l_linger = (unsigned short)value;
+        } else {
+            linger.l_onoff = 0;
+            linger.l_linger = 0;
+        }
+    } else {
+        parg = (char *)&value;
+        arglen = sizeof(value);
+    }
+
+    if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    setSoTimeout0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_PlainSocketImpl_setSoTimeout0
+  (JNIEnv *env, jclass clazz, jint fd, jint timeout)
+{
+    /*
+     * SO_TIMEOUT is the socket option used to specify the timeout
+     * for ServerSocket.accept and Socket.getInputStream().read.
+     * It does not typically map to a native level socket option.
+     * For Windows we special-case this and use the SOL_SOCKET/SO_RCVTIMEO
+     * socket option to specify a receive timeout on the socket. This
+     * receive timeout is applicable to Socket only and the socket
+     * option should not be set on ServerSocket.
+     */
+
+    /*
+     * SO_RCVTIMEO is only supported on Microsoft's implementation
+     * of Windows Sockets so if WSAENOPROTOOPT returned then
+     * reset flag and timeout will be implemented using
+     * select() -- see SocketInputStream.socketRead.
+     */
+    if (isRcvTimeoutSupported) {
+        /*
+         * Disable SO_RCVTIMEO if timeout is <= 5 second.
+         */
+        if (timeout <= 5000) {
+            timeout = 0;
+        }
+
+        if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
+            sizeof(timeout)) < 0) {
+            int err = WSAGetLastError();
+            if (err == WSAENOPROTOOPT) {
+                isRcvTimeoutSupported = JNI_FALSE;
+            } else {
+                NET_ThrowNew(env, err, "setsockopt SO_RCVTIMEO");
+            }
+        }
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    getIntOption
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_java_net_PlainSocketImpl_getIntOption
+  (JNIEnv *env, jclass clazz, jint fd, jint cmd)
+{
+    int level = 0, opt = 0;
+    int result = 0;
+    struct linger linger = {0, 0};
+    char *arg;
+    int arglen;
+
+    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
+        return -1;
+    }
+
+    if (opt == java_net_SocketOptions_SO_LINGER) {
+        arg = (char *)&linger;
+        arglen = sizeof(linger);
+    } else {
+        arg = (char *)&result;
+        arglen = sizeof(result);
+    }
+
+    if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
+        return -1;
+    }
+
+    if (opt == java_net_SocketOptions_SO_LINGER)
+        return linger.l_onoff ? linger.l_linger : -1;
+    else
+        return result;
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    sendOOB
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_sendOOB
+  (JNIEnv *env, jclass clazz, jint fd, jint data) {
+    jint n;
+    unsigned char d = (unsigned char) data & 0xff;
+
+    n = send(fd, (char *)&data, 1, MSG_OOB);
+    if (n == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "send");
+    }
+}
+
+/*
+ * Class:     java_net_PlainSocketImpl
+ * Method:    configureBlocking
+ * Signature: (IZ)V
+ */
+JNIEXPORT void JNICALL Java_java_net_PlainSocketImpl_configureBlocking
+  (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
+    u_long arg;
+    int result;
+
+    if (blocking == JNI_TRUE) {
+        arg = SET_BLOCKING;      // 0
+    } else {
+        arg = SET_NONBLOCKING;   // 1
+    }
+
+    result = ioctlsocket(fd, FIONBIO, &arg);
+    if (result == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
+    }
+}
--- a/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,550 +0,0 @@
-/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 "net_util.h"
-
-#include "java_net_TwoStacksPlainSocketImpl.h"
-#include "java_net_SocketOptions.h"
-#include "java_net_InetAddress.h"
-
-#define SET_BLOCKING 0
-#define SET_NONBLOCKING 1
-
-static jclass isa_class;        /* java.net.InetSocketAddress */
-static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
-
-/************************************************************************
- * TwoStacksPlainSocketImpl
- */
-
-/*
- * The initIDs function is called whenever TwoStacksPlainSocketImpl is
- * loaded, to cache fieldIds for efficiency. This is called everytime
- * the Java class is loaded.
- *
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_initIDs
-  (JNIEnv *env, jclass clazz) {
-
-    jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-    CHECK_NULL(cls);
-    isa_class = (*env)->NewGlobalRef(env, cls);
-    CHECK_NULL(isa_class);
-    isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
-                                     "(Ljava/net/InetAddress;I)V");
-    CHECK_NULL(isa_ctorID);
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    socket0
- * Signature: (ZZ)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_socket0
-  (JNIEnv *env, jclass clazz, jboolean stream, jboolean v6Only /*unused*/) {
-    int fd;
-
-    fd = socket(AF_INET, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
-    if (fd == INVALID_SOCKET) {
-        NET_ThrowNew(env, WSAGetLastError(), "create");
-        return -1;
-    }
-
-    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
-
-    return fd;
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    bind0
- * Signature: (ILjava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_bind0
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port,
-   jboolean exclBind)
-{
-    SOCKETADDRESS sa;
-    int rv, sa_len = 0;
-    /* family is an int field of iaObj */
-    int family;
-
-    family = getInetAddress_family(env, iaObj);
-    if (family != java_net_InetAddress_IPv4) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Protocol family not supported");
-        return;
-    }
-
-    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
-                                  &sa_len, JNI_FALSE) != 0) {
-        return;
-    }
-
-    rv = NET_WinBind(fd, &sa, sa_len, exclBind);
-
-    if (rv == SOCKET_ERROR)
-        NET_ThrowNew(env, WSAGetLastError(), "NET_Bind");
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    connect0
- * Signature: (ILjava/net/InetAddress;I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_connect0
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
-    SOCKETADDRESS sa;
-    int rv, sa_len = 0;
-    int family;
-
-    if (NET_InetAddressToSockaddr(env, iaObj, port, &sa,
-                                  &sa_len, JNI_FALSE) != 0) {
-        return -1;
-    }
-
-    family = sa.sa.sa_family;
-    if (family != AF_INET) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Protocol family not supported");
-        return -1;
-    }
-
-    rv = connect(fd, &sa.sa, sa_len);
-    if (rv == SOCKET_ERROR) {
-        int err = WSAGetLastError();
-        if (err == WSAEWOULDBLOCK) {
-            return java_net_TwoStacksPlainSocketImpl_WOULDBLOCK;
-        } else if (err == WSAEADDRNOTAVAIL) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
-                "connect: Address is invalid on local machine, or port is not valid on remote machine");
-        } else {
-            NET_ThrowNew(env, err, "connect");
-        }
-        return -1;  // return value not important.
-    }
-    return rv;
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    waitForConnect
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_waitForConnect
-  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
-    int rv, retry;
-    int optlen = sizeof(rv);
-    fd_set wr, ex;
-    struct timeval t;
-
-    FD_ZERO(&wr);
-    FD_ZERO(&ex);
-    FD_SET(fd, &wr);
-    FD_SET(fd, &ex);
-    t.tv_sec = timeout / 1000;
-    t.tv_usec = (timeout % 1000) * 1000;
-
-    /*
-     * Wait for timeout, connection established or
-     * connection failed.
-     */
-    rv = select(fd+1, 0, &wr, &ex, &t);
-
-    /*
-     * Timeout before connection is established/failed so
-     * we throw exception and shutdown input/output to prevent
-     * socket from being used.
-     * The socket should be closed immediately by the caller.
-     */
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                        "connect timed out");
-        shutdown( fd, SD_BOTH );
-        return;
-    }
-    /*
-     * Socket is writable or error occurred. On some Windows editions
-     * the socket will appear writable when the connect fails so we
-     * check for error rather than writable.
-     */
-    if (!FD_ISSET(fd, &ex)) {
-        return;         /* connection established */
-    }
-
-    /*
-     * Connection failed. The logic here is designed to work around
-     * bug on Windows NT whereby using getsockopt to obtain the
-     * last error (SO_ERROR) indicates there is no error. The workaround
-     * on NT is to allow winsock to be scheduled and this is done by
-     * yielding and retrying. As yielding is problematic in heavy
-     * load conditions we attempt up to 3 times to get the error reason.
-     */
-    for (retry=0; retry<3; retry++) {
-        NET_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
-                       (char*)&rv, &optlen);
-        if (rv) {
-            break;
-        }
-        Sleep(0);
-    }
-
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Unable to establish connection");
-    } else if (rv == WSAEADDRNOTAVAIL) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "ConnectException",
-                        "connect: Address is invalid on local machine,"
-                        " or port is not valid on remote machine");
-    } else {
-        NET_ThrowNew(env, rv, "connect");
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    localPort0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_localPort0
-  (JNIEnv *env, jclass clazz, jint fd) {
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-
-    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
-        if (WSAGetLastError() == WSAENOTSOCK) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                    "Socket closed");
-        } else {
-            NET_ThrowNew(env, WSAGetLastError(), "getsockname failed");
-        }
-        return -1;
-    }
-    return (int) ntohs((u_short)GET_PORT(&sa));
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    localAddress
- * Signature: (ILjava/net/InetAddressContainer;)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_localAddress
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
-    int port;
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-    jobject iaObj;
-    jclass iaContainerClass;
-    jfieldID iaFieldID;
-
-    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
-        return;
-    }
-    iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
-    CHECK_NULL(iaObj);
-
-    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
-    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
-    CHECK_NULL(iaFieldID);
-    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
-}
-
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    listen0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_listen0
-  (JNIEnv *env, jclass clazz, jint fd, jint backlog) {
-    if (listen(fd, backlog) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "listen failed");
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    accept0
- * Signature: (I[Ljava/net/InetSocketAddress;)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_accept0
-  (JNIEnv *env, jclass clazz, jint fd, jobjectArray isaa) {
-    int newfd, port=0;
-    jobject isa;
-    jobject ia;
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-
-    memset((char *)&sa, 0, len);
-    newfd = accept(fd, &sa.sa, &len);
-
-    if (newfd < 0) {
-        if (newfd == -2) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-        } else {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "socket closed");
-        }
-        return -1;
-    }
-
-    SetHandleInformation((HANDLE)(UINT_PTR)newfd, HANDLE_FLAG_INHERIT, 0);
-
-    if (sa.sa.sa_family != AF_INET) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Protocol family not supported");
-        NET_SocketClose(newfd);
-        return -1;
-    }
-
-    ia = NET_SockaddrToInetAddress(env, &sa, &port);
-    isa = (*env)->NewObject(env, isa_class, isa_ctorID, ia, port);
-    (*env)->SetObjectArrayElement(env, isaa, 0, isa);
-
-    return newfd;
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    waitForNewConnection
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_waitForNewConnection
-  (JNIEnv *env, jclass clazz, jint fd, jint timeout) {
-    int rv;
-
-    rv = NET_Timeout(fd, timeout);
-    if (rv == 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                        "Accept timed out");
-    } else if (rv == -1) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
-    } else if (rv == -2) {
-        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                        "operation interrupted");
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    available0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_available0
-  (JNIEnv *env, jclass clazz, jint fd) {
-    jint available = -1;
-
-    if ((ioctlsocket(fd, FIONREAD, &available)) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "socket available");
-    }
-
-    return available;
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    close0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_close0
-  (JNIEnv *env, jclass clazz, jint fd) {
-     NET_SocketClose(fd);
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    shutdown0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_shutdown0
-  (JNIEnv *env, jclass clazz, jint fd, jint howto) {
-    shutdown(fd, howto);
-}
-
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    setIntOption
- * Signature: (III)V
- */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_setIntOption
-  (JNIEnv *env, jclass clazz, jint fd, jint cmd, jint value)
-{
-    int level = 0, opt = 0;
-    struct linger linger = {0, 0};
-    char *parg;
-    int arglen;
-
-    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        parg = (char *)&linger;
-        arglen = sizeof(linger);
-        if (value >= 0) {
-            linger.l_onoff = 1;
-            linger.l_linger = (unsigned short)value;
-        } else {
-            linger.l_onoff = 0;
-            linger.l_linger = 0;
-        }
-    } else {
-        parg = (char *)&value;
-        arglen = sizeof(value);
-    }
-
-    if (NET_SetSockOpt(fd, level, opt, parg, arglen) < 0) {
-        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    setSoTimeout0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL
-Java_java_net_TwoStacksPlainSocketImpl_setSoTimeout0
-  (JNIEnv *env, jclass clazz, jint fd, jint timeout)
-{
-    /*
-     * SO_TIMEOUT is the socket option used to specify the timeout
-     * for ServerSocket.accept and Socket.getInputStream().read.
-     * It does not typically map to a native level socket option.
-     * For Windows we special-case this and use the SOL_SOCKET/SO_RCVTIMEO
-     * socket option to specify a receive timeout on the socket. This
-     * receive timeout is applicable to Socket only and the socket
-     * option should not be set on ServerSocket.
-     */
-
-    /*
-     * SO_RCVTIMEO is only supported on Microsoft's implementation
-     * of Windows Sockets so if WSAENOPROTOOPT returned then
-     * reset flag and timeout will be implemented using
-     * select() -- see SocketInputStream.socketRead.
-     */
-    if (isRcvTimeoutSupported) {
-        /*
-         * Disable SO_RCVTIMEO if timeout is <= 5 second.
-         */
-        if (timeout <= 5000) {
-            timeout = 0;
-        }
-
-        if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
-            sizeof(timeout)) < 0) {
-            int err = WSAGetLastError();
-            if (err == WSAENOPROTOOPT) {
-                isRcvTimeoutSupported = JNI_FALSE;
-            } else {
-                NET_ThrowNew(env, err, "setsockopt SO_RCVTIMEO");
-            }
-        }
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    getIntOption
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainSocketImpl_getIntOption
-  (JNIEnv *env, jclass clazz, jint fd, jint cmd)
-{
-    int level = 0, opt = 0;
-    int result=0;
-    struct linger linger = {0, 0};
-    char *arg;
-    int arglen;
-
-    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        arg = (char *)&linger;
-        arglen = sizeof(linger);
-    } else {
-        arg = (char *)&result;
-        arglen = sizeof(result);
-    }
-
-    if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
-        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER)
-        return linger.l_onoff ? linger.l_linger : -1;
-    else
-        return result;
-}
-
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    sendOOB
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_sendOOB
-  (JNIEnv *env, jclass clazz, jint fd, jint data) {
-    jint n;
-    unsigned char d = (unsigned char) data & 0xff;
-
-    n = send(fd, (char *)&data, 1, MSG_OOB);
-    if (n == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "send");
-    }
-}
-
-/*
- * Class:     java_net_TwoStacksPlainSocketImpl
- * Method:    configureBlocking
- * Signature: (IZ)V
- */
-JNIEXPORT void JNICALL Java_java_net_TwoStacksPlainSocketImpl_configureBlocking
-  (JNIEnv *env, jclass clazz, jint fd, jboolean blocking) {
-    u_long arg;
-    int result;
-
-    if (blocking == JNI_TRUE) {
-        arg = SET_BLOCKING;    // 0
-    } else {
-        arg = SET_NONBLOCKING;   // 1
-    }
-
-    result = ioctlsocket(fd, FIONBIO, &arg);
-    if (result == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "configureBlocking");
-    }
-}
--- a/src/java.desktop/share/native/common/awt/medialib/mlib_ImageCreate.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/common/awt/medialib/mlib_ImageCreate.c	Tue Apr 24 10:20:22 2018 +0100
@@ -227,7 +227,7 @@
 }
 
 /***************************************************************/
-mlib_image *mlib_ImageCreateStruct(mlib_type  type,
+JNIEXPORT mlib_image* JNICALL mlib_ImageCreateStruct(mlib_type  type,
                                    mlib_s32   channels,
                                    mlib_s32   width,
                                    mlib_s32   height,
@@ -253,7 +253,7 @@
 }
 
 /***************************************************************/
-mlib_image *mlib_ImageCreate(mlib_type type,
+JNIEXPORT mlib_image* JNICALL mlib_ImageCreate(mlib_type type,
                              mlib_s32  channels,
                              mlib_s32  width,
                              mlib_s32  height)
@@ -352,7 +352,7 @@
 }
 
 /***************************************************************/
-void mlib_ImageDelete(mlib_image *img)
+JNIEXPORT void JNICALL mlib_ImageDelete(mlib_image *img)
 {
   if (img == NULL) return;
   if ((img -> flags & MLIB_IMAGE_USERALLOCATED) == 0) {
--- a/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.c	Tue Apr 24 10:20:22 2018 +0100
@@ -299,7 +299,7 @@
 }
 
 /***************************************************************/
-mlib_status mlib_ImageAffine(mlib_image       *dst,
+JNIEXPORT mlib_status JNICALL mlib_ImageAffine(mlib_image       *dst,
                              const mlib_image *src,
                              const mlib_d64   *mtx,
                              mlib_filter      filter,
--- a/src/java.desktop/share/native/libmlib_image/mlib_ImageConvKernelConvert.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/libmlib_image/mlib_ImageConvKernelConvert.c	Tue Apr 24 10:20:22 2018 +0100
@@ -78,7 +78,7 @@
 #endif /* __sparc */
 
 /***************************************************************/
-mlib_status mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
+JNIEXPORT mlib_status JNICALL mlib_ImageConvKernelConvert(mlib_s32       *ikernel,
                                         mlib_s32       *iscale,
                                         const mlib_d64 *fkernel,
                                         mlib_s32       m,
--- a/src/java.desktop/share/native/libmlib_image/mlib_ImageConvMxN.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/libmlib_image/mlib_ImageConvMxN.c	Tue Apr 24 10:20:22 2018 +0100
@@ -90,7 +90,7 @@
 #include "mlib_ImageConvEdge.h"
 
 /***************************************************************/
-mlib_status mlib_ImageConvMxN(mlib_image       *dst,
+JNIEXPORT mlib_status JNICALL mlib_ImageConvMxN(mlib_image       *dst,
                               const mlib_image *src,
                               const mlib_s32   *kernel,
                               mlib_s32         m,
--- a/src/java.desktop/share/native/libmlib_image/mlib_c_ImageLookUp.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/libmlib_image/mlib_c_ImageLookUp.c	Tue Apr 24 10:20:22 2018 +0100
@@ -78,7 +78,7 @@
 #include "mlib_c_ImageLookUp.h"
 
 /***************************************************************/
-mlib_status mlib_ImageLookUp(mlib_image       *dst,
+JNIEXPORT mlib_status JNICALL mlib_ImageLookUp(mlib_image       *dst,
                              const mlib_image *src,
                              const void       **table)
 {
--- a/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Tue Apr 24 10:20:22 2018 +0100
@@ -132,9 +132,6 @@
 
 unsigned SplashTime();
 char* SplashConvertStringAlloc(const char* in, int *size);
-jboolean SplashGetScaledImageName(const char* jarName,
-                 const char* fileName, float *scaleFactor,
-                 char *scaleImageName, const size_t scaledImageNameLength);
 void SplashLock(Splash * splash);
 void SplashUnlock(Splash * splash);
 
@@ -157,8 +154,7 @@
 void SplashUpdateScreenData(Splash * splash);
 
 void SplashCleanup(Splash * splash);
-void SplashSetScaleFactor(float scaleFactor);
-int  SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
+
 void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor);
 jboolean GetScaledImageName(const char *fileName, char *scaledImgName,
                   float *scaleFactor, const size_t scaledImageLength);
--- a/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Tue Apr 24 10:20:22 2018 +0100
@@ -574,7 +574,7 @@
     PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
 }
 
-jboolean
+JNIEXPORT jboolean JNICALL
 SplashGetScaledImageName(const char* jarName, const char* fileName,
                            float *scaleFactor, char *scaleImageName,
                            const size_t scaledImageLength)
--- a/src/java.scripting/share/classes/javax/script/AbstractScriptEngine.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.scripting/share/classes/javax/script/AbstractScriptEngine.java	Tue Apr 24 10:20:22 2018 +0100
@@ -287,7 +287,7 @@
      */
     protected ScriptContext getScriptContext(Bindings nn) {
 
-        SimpleScriptContext ctxt = new SimpleScriptContext();
+        SimpleScriptContext ctxt = new SimpleScriptContext(context.getReader(), context.getWriter(), context.getErrorWriter());
         Bindings gs = getBindings(ScriptContext.GLOBAL_SCOPE);
 
         if (gs != null) {
@@ -301,10 +301,6 @@
             throw new NullPointerException("Engine scope Bindings may not be null.");
         }
 
-        ctxt.setReader(context.getReader());
-        ctxt.setWriter(context.getWriter());
-        ctxt.setErrorWriter(context.getErrorWriter());
-
         return ctxt;
 
     }
--- a/src/java.scripting/share/classes/javax/script/CompiledScript.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.scripting/share/classes/javax/script/CompiledScript.java	Tue Apr 24 10:20:22 2018 +0100
@@ -79,13 +79,10 @@
         ScriptContext ctxt = getEngine().getContext();
 
         if (bindings != null) {
-            SimpleScriptContext tempctxt = new SimpleScriptContext();
+            SimpleScriptContext tempctxt = new SimpleScriptContext(ctxt.getReader(), ctxt.getWriter(), ctxt.getErrorWriter());
             tempctxt.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
             tempctxt.setBindings(ctxt.getBindings(ScriptContext.GLOBAL_SCOPE),
                     ScriptContext.GLOBAL_SCOPE);
-            tempctxt.setWriter(ctxt.getWriter());
-            tempctxt.setReader(ctxt.getReader());
-            tempctxt.setErrorWriter(ctxt.getErrorWriter());
             ctxt = tempctxt;
         }
 
--- a/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java	Tue Apr 24 10:20:22 2018 +0100
@@ -86,11 +86,25 @@
      * Create a {@code SimpleScriptContext}.
      */
     public SimpleScriptContext() {
+        this(new InputStreamReader(System.in),
+             new PrintWriter(System.out , true),
+             new PrintWriter(System.err, true));
         engineScope = new SimpleBindings();
         globalScope = null;
-        reader = new InputStreamReader(System.in);
-        writer = new PrintWriter(System.out , true);
-        errorWriter = new PrintWriter(System.err, true);
+    }
+
+    /**
+     * Package-private constructor to avoid needless creation of reader and writers.
+     * It is the caller's responsability to initialize the engine scope.
+     *
+     * @param reader the reader
+     * @param writer the writer
+     * @param errorWriter the error writer
+     */
+    SimpleScriptContext(Reader reader, Writer writer, Writer errorWriter) {
+        this.reader = reader;
+        this.writer = writer;
+        this.errorWriter = errorWriter;
     }
 
     /**
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/SchemaContentHandler.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/SchemaContentHandler.java	Tue Apr 24 10:20:22 2018 +0100
@@ -26,6 +26,7 @@
 import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
+import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
 import com.sun.org.apache.xerces.internal.xni.QName;
@@ -78,6 +79,7 @@
     private final QName fAttributeQName = new QName();
     private final XMLAttributesImpl fAttributes = new XMLAttributesImpl();
     private final XMLString fTempString = new XMLString();
+    private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();
 
     /**
      * <p>Constructs an SchemaContentHandler.</p>
@@ -103,6 +105,7 @@
      */
     public void startDocument() throws SAXException {
         fNeedPushNSContext = true;
+        fNamespaceContext.reset();
         try {
             fSchemaDOMParser.startDocument(fSAXLocatorWrapper, null, fNamespaceContext, null);
         }
@@ -326,7 +329,11 @@
             if (nsPrefix.length() > 0) {
                 prefix = XMLSymbols.PREFIX_XMLNS;
                 localpart = nsPrefix;
-                rawname = fSymbolTable.addSymbol(prefix + ":" + localpart);
+                fStringBuffer.clear();
+                fStringBuffer.append(prefix);
+                fStringBuffer.append(':');
+                fStringBuffer.append(localpart);
+                rawname = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
             }
             else {
                 prefix = XMLSymbols.EMPTY_STRING;
@@ -334,7 +341,8 @@
                 rawname = XMLSymbols.PREFIX_XMLNS;
             }
             fAttributeQName.setValues(prefix, localpart, rawname, NamespaceContext.XMLNS_URI);
-            fAttributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, nsURI);
+            fAttributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol,
+                    (nsURI != null) ? nsURI : XMLSymbols.EMPTY_STRING);
         }
     }
 
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java	Tue Apr 24 10:20:22 2018 +0100
@@ -2266,6 +2266,8 @@
                             fSecurityManager.isSecureProcessing());
 
                     try {
+                        parser.setFeature(NAMESPACE_PREFIXES, true);
+                        namespacePrefixes = true;
                         // If this is a Xerces SAX parser set the security manager if there is one
                         if (parser instanceof SAXParser) {
                             if (fSecurityManager != null) {
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Tue Apr 24 10:20:22 2018 +0100
@@ -230,6 +230,8 @@
 
         {"JVMCIRuntime::monitorenter", "_aot_jvmci_runtime_monitorenter"},
         {"JVMCIRuntime::monitorexit", "_aot_jvmci_runtime_monitorexit"},
+        {"JVMCIRuntime::object_notify", "_aot_object_notify"},
+        {"JVMCIRuntime::object_notifyAll", "_aot_object_notifyAll"},
         {"JVMCIRuntime::log_object", "_aot_jvmci_runtime_log_object"},
         {"JVMCIRuntime::log_printf", "_aot_jvmci_runtime_log_printf"},
         {"JVMCIRuntime::vm_message", "_aot_jvmci_runtime_vm_message"},
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM942C.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.nio.cs.ext;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.util.Arrays;
-import sun.nio.cs.DoubleByte;
-import sun.nio.cs.HistoricallyNamedCharset;
-import static sun.nio.cs.CharsetMapping.*;
-
-public class IBM942C extends Charset implements HistoricallyNamedCharset
-{
-    public IBM942C() {
-        super("x-IBM942C", ExtendedCharsets.aliasesFor("x-IBM942C"));
-    }
-
-    public String historicalName() {
-        return "Cp942C";
-    }
-
-    public boolean contains(Charset cs) {
-        return ((cs.name().equals("US-ASCII"))
-                || (cs instanceof IBM942C));
-    }
-
-    public CharsetDecoder newDecoder() {
-        return new DoubleByte.Decoder(this,
-                                      IBM942.b2c,
-                                      b2cSB,
-                                      0x40,
-                                      0xfc);
-    }
-
-    public CharsetEncoder newEncoder() {
-        return new DoubleByte.Encoder(this, c2b, c2bIndex);
-    }
-
-    final static char[] b2cSB;
-    final static char[] c2b;
-    final static char[] c2bIndex;
-
-    static {
-        IBM942.initb2c();
-
-        // the mappings need udpate are
-        //    u+001a  <-> 0x1a
-        //    u+001c  <-> 0x1c
-        //    u+005c  <-> 0x5c
-        //    u+007e  <-> 0x7e
-        //    u+007f  <-> 0x7f
-
-        b2cSB = Arrays.copyOf(IBM942.b2cSB, IBM942.b2cSB.length);
-        b2cSB[0x1a] = 0x1a;
-        b2cSB[0x1c] = 0x1c;
-        b2cSB[0x5c] = 0x5c;
-        b2cSB[0x7e] = 0x7e;
-        b2cSB[0x7f] = 0x7f;
-
-        IBM942.initc2b();
-        c2b = Arrays.copyOf(IBM942.c2b, IBM942.c2b.length);
-        c2bIndex = Arrays.copyOf(IBM942.c2bIndex, IBM942.c2bIndex.length);
-        c2b[c2bIndex[0] + 0x1a] = 0x1a;
-        c2b[c2bIndex[0] + 0x1c] = 0x1c;
-        c2b[c2bIndex[0] + 0x5c] = 0x5c;
-        c2b[c2bIndex[0] + 0x7e] = 0x7e;
-        c2b[c2bIndex[0] + 0x7f] = 0x7f;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM942C.java.template	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 $PACKAGE$;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.Arrays;
+import sun.nio.cs.DoubleByte;
+import sun.nio.cs.HistoricallyNamedCharset;
+import static sun.nio.cs.CharsetMapping.*;
+
+public class IBM942C extends Charset implements HistoricallyNamedCharset
+{
+    public IBM942C() {
+        super("x-IBM942C", $ALIASES$);
+    }
+
+    public String historicalName() {
+        return "Cp942C";
+    }
+
+    public boolean contains(Charset cs) {
+        return ((cs.name().equals("US-ASCII"))
+                || (cs instanceof IBM942C));
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new DoubleByte.Decoder(this,
+                                      IBM942.b2c,
+                                      b2cSB,
+                                      0x40,
+                                      0xfc);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new DoubleByte.Encoder(this, c2b, c2bIndex);
+    }
+
+    final static char[] b2cSB;
+    final static char[] c2b;
+    final static char[] c2bIndex;
+
+    static {
+        IBM942.initb2c();
+
+        // the mappings need udpate are
+        //    u+001a  <-> 0x1a
+        //    u+001c  <-> 0x1c
+        //    u+005c  <-> 0x5c
+        //    u+007e  <-> 0x7e
+        //    u+007f  <-> 0x7f
+
+        b2cSB = Arrays.copyOf(IBM942.b2cSB, IBM942.b2cSB.length);
+        b2cSB[0x1a] = 0x1a;
+        b2cSB[0x1c] = 0x1c;
+        b2cSB[0x5c] = 0x5c;
+        b2cSB[0x7e] = 0x7e;
+        b2cSB[0x7f] = 0x7f;
+
+        IBM942.initc2b();
+        c2b = Arrays.copyOf(IBM942.c2b, IBM942.c2b.length);
+        c2bIndex = Arrays.copyOf(IBM942.c2bIndex, IBM942.c2bIndex.length);
+        c2b[c2bIndex[0] + 0x1a] = 0x1a;
+        c2b[c2bIndex[0] + 0x1c] = 0x1c;
+        c2b[c2bIndex[0] + 0x5c] = 0x5c;
+        c2b[c2bIndex[0] + 0x7e] = 0x7e;
+        c2b[c2bIndex[0] + 0x7f] = 0x7f;
+    }
+}
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM943C.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * 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.nio.cs.ext;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.util.Arrays;
-import sun.nio.cs.DoubleByte;
-import sun.nio.cs.HistoricallyNamedCharset;
-
-public class IBM943C extends Charset implements HistoricallyNamedCharset
-{
-
-    public IBM943C() {
-        super("x-IBM943C", ExtendedCharsets.aliasesFor("x-IBM943C"));
-    }
-
-    public String historicalName() {
-        return "Cp943C";
-    }
-
-    public boolean contains(Charset cs) {
-        return ((cs.name().equals("US-ASCII"))
-                || (cs instanceof IBM943C));
-    }
-
-    public CharsetDecoder newDecoder() {
-        return new DoubleByte.Decoder(this,
-                                      IBM943.b2c,
-                                      b2cSB,
-                                      0x40,
-                                      0xfc);
-    }
-
-    public CharsetEncoder newEncoder() {
-        return new DoubleByte.Encoder(this, c2b, c2bIndex);
-    }
-
-    final static char[] b2cSB;
-    final static char[] c2b;
-    final static char[] c2bIndex;
-
-    static {
-        IBM943.initb2c();
-        b2cSB = new char[0x100];
-        for (int i = 0; i < 0x80; i++) {
-            b2cSB[i] = (char)i;
-        }
-        for (int i = 0x80; i < 0x100; i++) {
-            b2cSB[i] = IBM943.b2cSB[i];
-        }
-
-        IBM943.initc2b();
-        c2b = Arrays.copyOf(IBM943.c2b, IBM943.c2b.length);
-        c2bIndex = Arrays.copyOf(IBM943.c2bIndex, IBM943.c2bIndex.length);
-        for (char c = '\0'; c < '\u0080'; ++c) {
-            int index = c2bIndex[c >> 8];
-            c2b[index + (c & 0xff)] = c;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM943C.java.template	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 $PACKAGE$;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.Arrays;
+import sun.nio.cs.DoubleByte;
+import sun.nio.cs.HistoricallyNamedCharset;
+
+public class IBM943C extends Charset implements HistoricallyNamedCharset
+{
+
+    public IBM943C() {
+        super("x-IBM943C", $ALIASES$);
+    }
+
+    public String historicalName() {
+        return "Cp943C";
+    }
+
+    public boolean contains(Charset cs) {
+        return ((cs.name().equals("US-ASCII"))
+                || (cs instanceof IBM943C));
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new DoubleByte.Decoder(this,
+                                      IBM943.b2c,
+                                      b2cSB,
+                                      0x40,
+                                      0xfc);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new DoubleByte.Encoder(this, c2b, c2bIndex);
+    }
+
+    final static char[] b2cSB;
+    final static char[] c2b;
+    final static char[] c2bIndex;
+
+    static {
+        IBM943.initb2c();
+        b2cSB = new char[0x100];
+        for (int i = 0; i < 0x80; i++) {
+            b2cSB[i] = (char)i;
+        }
+        for (int i = 0x80; i < 0x100; i++) {
+            b2cSB[i] = IBM943.b2cSB[i];
+        }
+
+        IBM943.initc2b();
+        c2b = Arrays.copyOf(IBM943.c2b, IBM943.c2b.length);
+        c2bIndex = Arrays.copyOf(IBM943.c2bIndex, IBM943.c2bIndex.length);
+        for (char c = '\0'; c < '\u0080'; ++c) {
+            int index = c2bIndex[c >> 8];
+            c2b[index + (c & 0xff)] = c;
+        }
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -172,7 +172,7 @@
             if (compiler == null || compiler.errorCount() == 0
                     || Options.instance(context).isSet("dev")) {
                 Log log = Log.instance(context);
-                log.printLines(PrefixKind.JAVAC, "msg.bug", JavaCompiler.version());
+                log.printLines("msg.bug", JavaCompiler.version());
                 ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
             }
             return abnormalErrorResult;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Tue Apr 24 10:20:22 2018 +0100
@@ -54,7 +54,6 @@
 import com.sun.tools.doclint.DocLint;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.code.Source.Feature;
 import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.jvm.Profile;
@@ -66,6 +65,7 @@
 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
@@ -295,7 +295,7 @@
         String platformString = options.get(Option.RELEASE);
 
         checkOptionAllowed(platformString == null,
-                option -> error("err.release.bootclasspath.conflict", option.getPrimaryName()),
+                option -> reportDiag(Errors.ReleaseBootclasspathConflict(option)),
                 Option.BOOT_CLASS_PATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
                 Option.XBOOTCLASSPATH_PREPEND,
                 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
@@ -308,7 +308,7 @@
                     PlatformUtils.lookupPlatformDescription(platformString);
 
             if (platformDescription == null) {
-                error("err.unsupported.release.version", platformString);
+                reportDiag(Errors.UnsupportedReleaseVersion(platformString));
                 return false;
             }
 
@@ -363,7 +363,7 @@
         while (argIter.hasNext()) {
             String arg = argIter.next();
             if (arg.isEmpty()) {
-                error("err.invalid.flag", arg);
+                reportDiag(Errors.InvalidFlag(arg));
                 return false;
             }
 
@@ -392,7 +392,7 @@
             }
 
             // none of the above
-            error("err.invalid.flag", arg);
+            reportDiag(Errors.InvalidFlag(arg));
             return false;
         }
 
@@ -457,9 +457,9 @@
             if (!emptyAllowed) {
                 if (!errors) {
                     if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
-                        error("err.no.source.files.classes");
+                        reportDiag(Errors.NoSourceFilesClasses);
                     } else {
-                        error("err.no.source.files");
+                        reportDiag(Errors.NoSourceFiles);
                     }
                 }
                 return false;
@@ -520,13 +520,9 @@
             if (target.compareTo(source.requiredTarget()) < 0) {
                 if (targetString != null) {
                     if (sourceString == null) {
-                        error("warn.target.default.source.conflict",
-                                targetString,
-                                source.requiredTarget().name);
+                        reportDiag(Warnings.TargetDefaultSourceConflict(targetString, source.requiredTarget()));
                     } else {
-                        error("warn.source.target.conflict",
-                                sourceString,
-                                source.requiredTarget().name);
+                        reportDiag(Warnings.SourceTargetConflict(sourceString, source.requiredTarget()));
                     }
                     return false;
                 } else {
@@ -539,13 +535,11 @@
         if (options.isSet(Option.PREVIEW)) {
             if (sourceString == null) {
                 //enable-preview must be used with explicit -source or --release
-                error("err.preview.without.source.or.release");
+                report(Errors.PreviewWithoutSourceOrRelease);
                 return false;
             } else if (source != Source.DEFAULT) {
                 //enable-preview must be used with latest source version
-                error("err.preview.not.latest",
-                        sourceString,
-                        Source.DEFAULT.name);
+                report(Errors.PreviewNotLatest(sourceString, Source.DEFAULT));
                 return false;
             }
         }
@@ -554,18 +548,18 @@
         if (profileString != null) {
             Profile profile = Profile.lookup(profileString);
             if (!profile.isValid(target)) {
-                error("warn.profile.target.conflict", profileString, target.name);
+                reportDiag(Warnings.ProfileTargetConflict(profile, target));
             }
 
             // This check is only effective in command line mode,
             // where the file manager options are added to options
             if (options.get(Option.BOOT_CLASS_PATH) != null) {
-                error("err.profile.bootclasspath.conflict");
+                reportDiag(Errors.ProfileBootclasspathConflict);
             }
         }
 
         if (options.isSet(Option.SOURCE_PATH) && options.isSet(Option.MODULE_SOURCE_PATH)) {
-            error("err.sourcepath.modulesourcepath.conflict");
+            reportDiag(Errors.SourcepathModulesourcepathConflict);
         }
 
         boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
@@ -586,15 +580,15 @@
         }
 
         if (target.compareTo(Target.MIN) < 0) {
-            log.error(Errors.OptionRemovedTarget(target.name, Target.MIN.name));
+            log.error(Errors.OptionRemovedTarget(target, Target.MIN));
         } else if (target == Target.MIN && lintOptions) {
-            log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteTarget(target.name));
+            log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteTarget(target));
             obsoleteOptionFound = true;
         }
 
         final Target t = target;
         checkOptionAllowed(t.compareTo(Target.JDK1_8) <= 0,
-                option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
+                option -> reportDiag(Errors.OptionNotAllowedWithTarget(option, t)),
                 Option.BOOT_CLASS_PATH,
                 Option.XBOOTCLASSPATH_PREPEND, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
                 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
@@ -602,7 +596,7 @@
                 Option.PROFILE);
 
         checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
-                option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
+                option -> reportDiag(Errors.OptionNotAllowedWithTarget(option, t)),
                 Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH,
                 Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES,
                 Option.ADD_EXPORTS, Option.ADD_OPENS, Option.ADD_READS,
@@ -610,7 +604,7 @@
                 Option.PATCH_MODULE);
 
         if (lintOptions && options.isSet(Option.PARAMETERS) && !target.hasMethodParameters()) {
-            log.warning(Warnings.OptionParametersUnsupported(target.name, Target.JDK1_8.name));
+            log.warning(Warnings.OptionParametersUnsupported(target, Target.JDK1_8));
         }
 
         if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
@@ -871,7 +865,7 @@
         }
         Path file = Paths.get(value);
         if (Files.exists(file) && !Files.isDirectory(file)) {
-            error("err.file.not.directory", value);
+            reportDiag(Errors.FileNotDirectory(value));
             return false;
         }
         return true;
@@ -889,35 +883,19 @@
         }
     }
 
-    void error(JCDiagnostic.Error error) {
+    void reportDiag(DiagnosticInfo diag) {
         errors = true;
         switch (errorMode) {
             case ILLEGAL_ARGUMENT: {
-                String msg = log.localize(error);
+                String msg = log.localize(diag);
                 throw new PropagatedException(new IllegalArgumentException(msg));
             }
             case ILLEGAL_STATE: {
-                String msg = log.localize(error);
+                String msg = log.localize(diag);
                 throw new PropagatedException(new IllegalStateException(msg));
             }
             case LOG:
-                report(error);
-        }
-    }
-
-    void error(String key, Object... args) {
-        errors = true;
-        switch (errorMode) {
-            case ILLEGAL_ARGUMENT: {
-                String msg = log.localize(PrefixKind.JAVAC, key, args);
-                throw new PropagatedException(new IllegalArgumentException(msg));
-            }
-            case ILLEGAL_STATE: {
-                String msg = log.localize(PrefixKind.JAVAC, key, args);
-                throw new PropagatedException(new IllegalStateException(msg));
-            }
-            case LOG:
-                report(key, args);
+                report(diag);
         }
     }
 
@@ -932,22 +910,17 @@
                 throw new PropagatedException(new IllegalStateException(msg, f.getCause()));
             }
             case LOG:
-                log.printRawLines(ownName + ": " + msg);
+                log.printRawLines(msg);
         }
     }
 
-    void warning(String key, Object... args) {
-        report(key, args);
-    }
-
-    private void report(String key, Object... args) {
+    private void report(DiagnosticInfo diag) {
         // Would be good to have support for -XDrawDiagnostics here
-        log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
-    }
-
-    private void report(JCDiagnostic.Error error) {
-        // Would be good to have support for -XDrawDiagnostics here
-        log.printRawLines(ownName + ": " + log.localize(error));
+        if (diag instanceof JCDiagnostic.Error) {
+            log.error((JCDiagnostic.Error)diag);
+        } else if (diag instanceof JCDiagnostic.Warning){
+            log.warning((JCDiagnostic.Warning)diag);
+        }
     }
 
     private JavaFileManager getFileManager() {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,9 @@
 import com.sun.tools.javac.main.CommandLine.UnmatchedQuote;
 import com.sun.tools.javac.platform.PlatformDescription;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
 import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.util.Log.WriterKind;
 
@@ -138,19 +140,22 @@
 
     /** Report a usage error.
      */
-    void error(String key, Object... args) {
+    void reportDiag(DiagnosticInfo diag) {
         if (apiMode) {
-            String msg = log.localize(PrefixKind.JAVAC, key, args);
+            String msg = log.localize(diag);
             throw new PropagatedException(new IllegalStateException(msg));
         }
-        warning(key, args);
+        reportHelper(diag);
         log.printLines(PrefixKind.JAVAC, "msg.usage", ownName);
     }
 
-    /** Report a warning.
+    /** Report helper.
      */
-    void warning(String key, Object... args) {
-        log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
+    void reportHelper(DiagnosticInfo diag) {
+        String msg = log.localize(diag);
+        String errorPrefix = log.localize(Errors.Error);
+        msg = msg.startsWith(errorPrefix) ? msg : errorPrefix + msg;
+        log.printRawLines(msg);
     }
 
 
@@ -209,10 +214,10 @@
         try {
             argv = CommandLine.parse(ENV_OPT_NAME, argv);
         } catch (UnmatchedQuote ex) {
-            error("err.unmatched.quote", ex.variableName);
+            reportDiag(Errors.UnmatchedQuote(ex.variableName));
             return Result.CMDERR;
         } catch (FileNotFoundException | NoSuchFileException e) {
-            warning("err.file.not.found", e.getMessage());
+            reportHelper(Errors.FileNotFound(e.getMessage()));
             return Result.SYSERR;
         } catch (IOException ex) {
             log.printLines(PrefixKind.JAVAC, "msg.io");
@@ -366,11 +371,10 @@
                     CodeSource otherClassCodeSource = otherClass.getProtectionDomain().getCodeSource();
                     CodeSource javacCodeSource = this.getClass().getProtectionDomain().getCodeSource();
                     if (otherClassCodeSource != null && javacCodeSource != null) {
-                        log.printLines(PrefixKind.JAVAC, "err.two.class.loaders.2",
-                                otherClassCodeSource.getLocation(),
-                                javacCodeSource.getLocation());
+                        log.printLines(Errors.TwoClassLoaders2(otherClassCodeSource.getLocation(),
+                                javacCodeSource.getLocation()));
                     } else {
-                        log.printLines(PrefixKind.JAVAC, "err.two.class.loaders.1");
+                        log.printLines(Errors.TwoClassLoaders1);
                     }
                     return true;
                 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Tue Apr 24 10:20:22 2018 +0100
@@ -59,6 +59,7 @@
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.platform.PlatformProvider;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Log.PrefixKind;
@@ -197,7 +198,7 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(PATCH_MODULE);
                 if (prev == null) {
@@ -209,13 +210,13 @@
                             .collect(Collectors.toSet())
                             .contains(argModulePackage);
                     if (isRepeated) {
-                        throw helper.newInvalidValueException("err.repeated.value.for.patch.module", argModulePackage);
+                        throw helper.newInvalidValueException(Errors.RepeatedValueForPatchModule(argModulePackage));
                     } else {
                         super.process(helper, option, prev + '\0' + arg);
                     }
                 }
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -290,7 +291,7 @@
         public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Source source = Source.lookup(operand);
             if (source == null) {
-                throw helper.newInvalidValueException("err.invalid.source", operand);
+                throw helper.newInvalidValueException(Errors.InvalidSource(operand));
             }
             super.process(helper, option, operand);
         }
@@ -301,7 +302,7 @@
         public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Target target = Target.lookup(operand);
             if (target == null) {
-                throw helper.newInvalidValueException("err.invalid.target", operand);
+                throw helper.newInvalidValueException(Errors.InvalidTarget(operand));
             }
             super.process(helper, option, operand);
         }
@@ -337,7 +338,7 @@
         public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Profile profile = Profile.lookup(operand);
             if (profile == null) {
-                throw helper.newInvalidValueException("err.invalid.profile", operand);
+                throw helper.newInvalidValueException(Errors.InvalidProfile(operand));
             }
             super.process(helper, option, operand);
         }
@@ -392,12 +393,12 @@
         public void process(OptionHelper helper, String option) throws InvalidValueException {
             int argLength = option.length();
             if (argLength == 2) {
-                throw helper.newInvalidValueException("err.empty.A.argument");
+                throw helper.newInvalidValueException(Errors.EmptyAArgument);
             }
             int sepIndex = option.indexOf('=');
             String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
             if (!JavacProcessingEnvironment.isValidOptionName(key)) {
-                throw helper.newInvalidValueException("err.invalid.A.key", option);
+                throw helper.newInvalidValueException(Errors.InvalidAKey(option));
             }
             helper.put(option, option);
         }
@@ -410,14 +411,13 @@
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             String prev = helper.get(DEFAULT_MODULE_FOR_CREATED_FILES);
             if (prev != null) {
-                throw helper.newInvalidValueException("err.option.too.many",
-                                                      DEFAULT_MODULE_FOR_CREATED_FILES.primaryName);
+                throw helper.newInvalidValueException(Errors.OptionTooMany(DEFAULT_MODULE_FOR_CREATED_FILES.primaryName));
             } else if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 helper.put(DEFAULT_MODULE_FOR_CREATED_FILES.primaryName, arg);
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -487,7 +487,7 @@
                 Log log = helper.getLog();
                 log.setWriters(new PrintWriter(new FileWriter(arg), true));
             } catch (java.io.IOException e) {
-                throw helper.newInvalidValueException("err.error.writing.file", arg, e);
+                throw helper.newInvalidValueException(Errors.ErrorWritingFile(arg, e.getMessage()));
             }
             super.process(helper, option, arg);
         }
@@ -570,12 +570,12 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_EXPORTS);
                 helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -591,12 +591,12 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_READS);
                 helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -612,14 +612,14 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_MODULES);
                 // since the individual values are simple names, we can simply join the
                 // values of multiple --add-modules options with ','
                 helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg);
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -633,11 +633,11 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else if (getPattern().matcher(arg).matches()) {
                 helper.put(LIMIT_MODULES.primaryName, arg); // last one wins
             } else {
-                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
             }
         }
 
@@ -651,13 +651,13 @@
         @Override
         public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                throw helper.newInvalidValueException("err.no.value.for.option", option);
+                throw helper.newInvalidValueException(Errors.NoValueForOption(option));
             } else {
                 // use official parser if available
                 try {
                     ModuleDescriptor.Version.parse(arg);
                 } catch (IllegalArgumentException e) {
-                    throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
+                    throw helper.newInvalidValueException(Errors.BadValueForOption(option, arg));
                 }
             }
             super.process(helper, option, arg);
@@ -692,10 +692,10 @@
             if (option.endsWith(".java") ) {
                 Path p = Paths.get(option);
                 if (!Files.exists(p)) {
-                    throw helper.newInvalidValueException("err.file.not.found", p);
+                    throw helper.newInvalidValueException(Errors.FileNotFound(p.toString()));
                 }
                 if (!Files.isRegularFile(p)) {
-                    throw helper.newInvalidValueException("err.file.not.file", p);
+                    throw helper.newInvalidValueException(Errors.FileNotFile(p));
                 }
                 helper.addFile(p);
             } else {
@@ -1078,7 +1078,7 @@
                 operand = arg.substring(sep + 1);
             } else {
                 if (!rest.hasNext()) {
-                    throw helper.newInvalidValueException("err.req.arg", arg);
+                    throw helper.newInvalidValueException(Errors.ReqArg(this.primaryName));
                 }
                 option = arg;
                 operand = rest.next();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,9 @@
 
 import java.nio.file.Path;
 
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.Error;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Log.PrefixKind;
 
@@ -89,8 +91,8 @@
      * @param args the arguments, if any, for the resource string
      * @return the InvalidValueException
      */
-    Option.InvalidValueException newInvalidValueException(String key, Object... args) {
-        return new Option.InvalidValueException(getLog().localize(PrefixKind.JAVAC, key, args));
+    Option.InvalidValueException newInvalidValueException(Error error) {
+        return new Option.InvalidValueException(getLog().localize(error));
     }
 
     /** Record a file to be compiled. */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Apr 24 10:20:22 2018 +0100
@@ -39,13 +39,18 @@
 # name              a name, typically a Java identifier
 # number            an integer
 # option name       the name of a command line option
-# source version    a source version number, such as 1.5, 1.6, 1.7
+# path              a path
+# profile           a profile name
+# source            a source version number, such as 1.5, 1.6, 1.7, taken from a com.sun.tools.javac.code.Source
+# source version    a source version number, such as 1.5, 1.6, 1.7, taken from a javax.lang.model.SourceVersion
 # string            a general string
 # symbol            the name of a declared type
 # symbol kind       the kind of a symbol (i.e. method, variable)
 # kind name         an informative description of the kind of a declaration; see compiler.misc.kindname.*
+# target            a target version number, such as 1.5, 1.6, 1.7, taken from a com.sun.tools.javac.jvm.Target
 # token             the name of a non-terminal in source code; see compiler.misc.token.*
 # type              a Java type; e.g. int, X, X<T>
+# url               a URL
 # object            a Java object (unspecified)
 # unused            the value is not used in this message
 #
@@ -1779,7 +1784,7 @@
 compiler.warn.option.obsolete.source=\
     source value {0} is obsolete and will be removed in a future release
 
-# 0: string
+# 0: target
 compiler.warn.option.obsolete.target=\
     target value {0} is obsolete and will be removed in a future release
 
@@ -1787,12 +1792,12 @@
 compiler.err.option.removed.source=\
     Source option {0} is no longer supported. Use {1} or later.
 
-# 0: string, 1: string
+# 0: target, 1: target
 compiler.err.option.removed.target=\
     Target option {0} is no longer supported. Use {1} or later.
 
 
-# 0: string, 1: string
+# 0: target, 1: target
 compiler.warn.option.parameters.unsupported=\
     -parameters is not supported for target value {0}. Use {1} or later.
 
@@ -3257,3 +3262,123 @@
 # 0: string, 1: string
 compiler.err.illegal.argument.for.option=\
     illegal argument for {0}: {1}
+
+
+############################################
+# messages previouly at javac.properties
+
+compiler.err.empty.A.argument=\
+    -A requires an argument; use ''-Akey'' or ''-Akey=value''
+
+# 0: string
+compiler.err.invalid.A.key=\
+    key in annotation processor option ''{0}'' is not a dot-separated sequence of identifiers
+
+# 0: string
+compiler.err.invalid.flag=\
+    invalid flag: {0}
+
+compiler.err.profile.bootclasspath.conflict=\
+    profile and bootclasspath options cannot be used together
+
+# 0: string
+compiler.err.invalid.profile=\
+    invalid profile: {0}
+
+# 0: string
+compiler.err.invalid.target=\
+    invalid target release: {0}
+
+# 0: option name, 1: target
+compiler.err.option.not.allowed.with.target=\
+    option {0} not allowed with target {1}
+
+# 0: string
+compiler.err.option.too.many=\
+    option {0} can only be specified once
+
+compiler.err.no.source.files=\
+    no source files
+
+compiler.err.no.source.files.classes=\
+    no source files or class names
+
+# 0: string
+compiler.err.req.arg=\
+    {0} requires an argument
+
+# 0: string
+compiler.err.invalid.source=\
+    invalid source release: {0}
+
+# 0: string, 1: string
+compiler.err.error.writing.file=\
+    error writing {0}; {1}
+
+compiler.err.sourcepath.modulesourcepath.conflict=\
+    cannot specify both --source-path and --module-source-path
+
+# 0: string, 1: target
+compiler.warn.source.target.conflict=\
+    source release {0} requires target release {1}
+
+# 0: string, 1: target
+compiler.warn.target.default.source.conflict=\
+    target release {0} conflicts with default source release {1}
+
+# 0: profile, 1: target
+compiler.warn.profile.target.conflict=\
+    profile {0} is not valid for target release {1}
+
+# 0: string
+compiler.err.file.not.directory=\
+    not a directory: {0}
+
+# 0: object
+compiler.err.file.not.file=\
+    not a file: {0}
+
+compiler.err.two.class.loaders.1=\
+    javac is split between multiple class loaders: check your configuration
+
+# 0: url, 1: url
+compiler.err.two.class.loaders.2=\
+    javac is split between multiple class loaders:\n\
+    one class comes from file: {0}\n\
+    while javac comes from {1}
+
+# 0: string, 1: string
+compiler.err.bad.value.for.option=\
+    bad value for {0} option: ''{1}''
+
+# 0: string
+compiler.err.no.value.for.option=\
+    no value for {0} option
+
+# 0: string
+compiler.err.repeated.value.for.patch.module=\
+    --patch-module specified more than once for {0}
+
+# 0: string
+compiler.err.unmatched.quote=\
+    unmatched quote in environment variable {0}
+
+# 0: option name
+compiler.err.release.bootclasspath.conflict=\
+    option {0} cannot be used together with --release
+
+# 0: string
+compiler.err.unsupported.release.version=\
+    release version {0} not supported
+
+# 0: string
+compiler.err.file.not.found=\
+    file not found: {0}
+
+# 0: string, 1: source
+compiler.err.preview.not.latest=\
+    invalid source release {0} with --enable-preview\n\
+    (preview language features are only supported for release {1})
+
+compiler.err.preview.without.source.or.release=\
+    --enable-preview must be used with either -source or --release
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Tue Apr 24 10:20:22 2018 +0100
@@ -335,71 +335,6 @@
 javac.opt.default.module.for.created.files=\
     Fallback target module for files created by annotation processors, if none specified or inferred.
 
-## errors
-
-javac.err.empty.A.argument=\
-    -A requires an argument; use ''-Akey'' or ''-Akey=value''
-javac.err.invalid.arg=\
-    invalid argument: {0}
-javac.err.invalid.A.key=\
-     key in annotation processor option ''{0}'' is not a dot-separated sequence of identifiers
-javac.err.invalid.flag=\
-    invalid flag: {0}
-javac.err.profile.bootclasspath.conflict=\
-    profile and bootclasspath options cannot be used together
-javac.err.invalid.profile=\
-    invalid profile: {0}
-javac.err.invalid.target=\
-    invalid target release: {0}
-javac.err.option.not.allowed.with.target=\
-    option {0} not allowed with target {1}
-javac.err.option.too.many=\
-    option {0} can only be specified once
-javac.err.no.source.files=\
-    no source files
-javac.err.no.source.files.classes=\
-    no source files or class names
-javac.err.req.arg=\
-    {0} requires an argument
-javac.err.invalid.source=\
-    invalid source release: {0}
-javac.err.error.writing.file=\
-    error writing {0}; {1}
-javac.err.sourcepath.modulesourcepath.conflict=\
-    cannot specify both --source-path and --module-source-path
-javac.warn.source.target.conflict=\
-    source release {0} requires target release {1}
-javac.warn.target.default.source.conflict=\
-    target release {0} conflicts with default source release {1}
-javac.warn.profile.target.conflict=\
-    profile {0} is not valid for target release {1}
-javac.err.preview.not.latest=\
-    invalid source release {0} with --enable-preview\n\
-    (preview language features are only supported for release {1})
-javac.err.preview.without.source.or.release=\
-    --enable-preview must be used with either -source or --release
-javac.err.file.not.found=\
-    file not found: {0}
-javac.err.file.not.directory=\
-    not a directory: {0}
-javac.err.file.not.file=\
-    not a file: {0}
-javac.err.two.class.loaders.1=\
-    javac is split between multiple class loaders: check your configuration
-javac.err.two.class.loaders.2=\
-    javac is split between multiple class loaders:\n\
-    one class comes from file: {0}\n\
-    while javac comes from {1}
-javac.err.bad.value.for.option=\
-    bad value for {0} option: ''{1}''
-javac.err.no.value.for.option=\
-    no value for {0} option
-javac.err.repeated.value.for.patch.module=\
-    --patch-module specified more than once for {0}
-
-javac.err.unmatched.quote=\
-    unmatched quote in environment variable %s
-
 ## messages
 
 javac.msg.usage.header=\
@@ -437,9 +372,3 @@
 
 javac.version={0} {1}
 javac.fullVersion={0} full version "{1}"
-
-javac.err.release.bootclasspath.conflict=\
-    option {0} cannot be used together with --release
-
-javac.err.unsupported.release.version=\
-    release version {0} not supported
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,11 +43,13 @@
 import com.sun.tools.javac.api.Formattable;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Printer;
+import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Type.CapturedType;
 import com.sun.tools.javac.file.PathFileObject;
 import com.sun.tools.javac.jvm.Profile;
+import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.Pretty;
@@ -211,6 +213,12 @@
         else if (arg instanceof Formattable) {
             return ((Formattable)arg).toString(l, messages);
         }
+        else if (arg instanceof Target) {
+            return ((Target)arg).name;
+        }
+        else if (arg instanceof Source) {
+            return ((Source)arg).name;
+        }
         else {
             return String.valueOf(arg);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.util;
 
 import com.sun.tools.javac.api.Messages;
+
 import java.lang.ref.SoftReference;
 import java.util.ResourceBundle;
 import java.util.MissingResourceException;
@@ -34,6 +35,10 @@
 import java.util.Locale;
 import java.util.Map;
 
+import com.sun.tools.javac.api.DiagnosticFormatter;
+import com.sun.tools.javac.util.JCDiagnostic.Factory;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
+
 /**
  *  Support for formatted localized messages.
  *
@@ -61,6 +66,9 @@
     private Locale currentLocale;
     private List<ResourceBundle> currentBundles;
 
+    private DiagnosticFormatter<JCDiagnostic> diagFormatter;
+    private JCDiagnostic.Factory diagFactory;
+
     public Locale getCurrentLocale() {
         return currentLocale;
     }
@@ -73,11 +81,18 @@
         this.currentLocale = locale;
     }
 
+    Context context;
+
     /** Creates a JavacMessages object.
      */
     public JavacMessages(Context context) {
         this(defaultBundleName, context.get(Locale.class));
+        this.context = context;
         context.put(messagesKey, this);
+        Options options = Options.instance(context);
+        boolean rawDiagnostics = options.isSet("rawDiagnostics");
+        this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
+                                                  new BasicDiagnosticFormatter(options, this);
     }
 
     /** Creates a JavacMessages object.
@@ -140,6 +155,10 @@
         return getLocalizedString(currentLocale, key, args);
     }
 
+    public String getLocalizedString(JCDiagnostic.DiagnosticInfo diagInfo) {
+        return getLocalizedString(currentLocale, diagInfo);
+    }
+
     @Override
     public String getLocalizedString(Locale l, String key, Object... args) {
         if (l == null)
@@ -147,6 +166,12 @@
         return getLocalizedString(getBundles(l), key, args);
     }
 
+    public String getLocalizedString(Locale l, JCDiagnostic.DiagnosticInfo diagInfo) {
+        if (l == null)
+            l = getCurrentLocale();
+        return getLocalizedString(getBundles(l), diagInfo);
+    }
+
     /* Static access:
      * javac has a firmly entrenched notion of a default message bundle
      * which it can access from any static context. This is used to get
@@ -185,7 +210,7 @@
         }
     }
 
-    private static String getLocalizedString(List<ResourceBundle> bundles,
+    static private String getLocalizedString(List<ResourceBundle> bundles,
                                              String key,
                                              Object... args) {
        String msg = null;
@@ -205,6 +230,36 @@
        return MessageFormat.format(msg, args);
     }
 
+    private String getLocalizedString(List<ResourceBundle> bundles, JCDiagnostic.DiagnosticInfo diagInfo) {
+        String msg = null;
+        for (List<ResourceBundle> l = bundles; l.nonEmpty() && msg == null; l = l.tail) {
+            ResourceBundle rb = l.head;
+            try {
+                msg = rb.getString(diagInfo.key());
+            }
+            catch (MissingResourceException e) {
+                // ignore, try other bundles in list
+            }
+        }
+        if (msg == null) {
+            msg = "compiler message file broken: key=" + diagInfo.key() +
+                " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}";
+        }
+        if (diagInfo == Errors.Error) {
+            return MessageFormat.format(msg, new Object[0]);
+        } else {
+            return diagFormatter.format(getDiagFactory().create(DiagnosticSource.NO_SOURCE, null, diagInfo),
+                    getCurrentLocale());
+        }
+    }
+
+    JCDiagnostic.Factory getDiagFactory() {
+        if (diagFactory == null) {
+            this.diagFactory = JCDiagnostic.Factory.instance(context);
+        }
+        return diagFactory;
+    }
+
     /**
      * This provides a way for the JavacMessager to retrieve a
      * ResourceBundle from another module such as jdk.javadoc.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.tree.EndPosTable;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
@@ -597,6 +598,11 @@
         printRawLines(noticeWriter, localize(key, args));
     }
 
+    public void printLines(DiagnosticInfo diag) {
+        PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
+        printRawLines(noticeWriter, localize(diag));
+    }
+
     public void printLines(PrefixKind pk, String key, Object... args) {
         PrintWriter noticeWriter = writers.get(WriterKind.NOTICE);
         printRawLines(noticeWriter, localize(pk, key, args));
@@ -789,7 +795,7 @@
         if (useRawMessages) {
             return diagInfo.key();
         } else {
-            return messages.getLocalizedString(diagInfo.key(), diagInfo.args);
+            return messages.getLocalizedString(diagInfo);
         }
     }
 
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,14 +42,14 @@
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type      = db.lookupType("ClassLoaderData");
-    classLoaderField = type.getOopField("_class_loader");
+    classLoaderField = type.getAddressField("_class_loader");
     nextField = type.getAddressField("_next");
     klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
     isAnonymousField = new CIntField(type.getCIntegerField("_is_anonymous"), 0);
     dictionaryField = type.getAddressField("_dictionary");
   }
 
-  private static sun.jvm.hotspot.types.OopField classLoaderField;
+  private static AddressField   classLoaderField;
   private static AddressField nextField;
   private static MetadataField  klassesField;
   private static CIntField isAnonymousField;
@@ -72,7 +72,13 @@
   }
 
   public Oop getClassLoader() {
-    return VM.getVM().getObjectHeap().newOop(classLoaderField.getValue(getAddress()));
+    Address handle = classLoaderField.getValue(getAddress());
+    if (handle != null) {
+      // Load through the handle
+      OopHandle refs = handle.getOopHandleAt(0);
+      return (Instance)VM.getVM().getObjectHeap().newOop(refs);
+    }
+    return null;
   }
 
   public boolean getIsAnonymous() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot.management;
+
+/**
+ * Placeholder until next Graal update.
+ */
+public final class HotSpotGraalManagement  {
+}
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Tue Apr 24 10:20:22 2018 +0100
@@ -209,6 +209,7 @@
     static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
 
     private boolean debug = false;
+    private int debugFlags = 0;
     public boolean testPrompt = false;
     private Startup startup = null;
     private boolean isCurrentlyRunningStartup = false;
@@ -261,25 +262,28 @@
         MODULE_PATH("--module-path", true),
         ADD_MODULES("--add-modules", false),
         ADD_EXPORTS("--add-exports", false),
-        TO_COMPILER("-C", false, false, true, false),
-        TO_REMOTE_VM("-R", false, false, false, true),;
+        ENABLE_PREVIEW("--enable-preview", true),
+        SOURCE_RELEASE("-source", true, true, true, false, false),  // virtual option, generated by --enable-preview
+        TO_COMPILER("-C", false, false, true, false, false),
+        TO_REMOTE_VM("-R", false, false, false, true, false),;
         final String optionFlag;
         final boolean onlyOne;
         final boolean passFlag;
         final boolean toCompiler;
         final boolean toRemoteVm;
+        final boolean showOption;
 
         private OptionKind(String optionFlag, boolean onlyOne) {
-            this(optionFlag, onlyOne, true, true, true);
+            this(optionFlag, onlyOne, true, true, true, true);
         }
 
-        private OptionKind(String optionFlag, boolean onlyOne, boolean passFlag,
-                boolean toCompiler, boolean toRemoteVm) {
+        private OptionKind(String optionFlag, boolean onlyOne, boolean passFlag, boolean toCompiler, boolean toRemoteVm, boolean showOption) {
             this.optionFlag = optionFlag;
             this.onlyOne = onlyOne;
             this.passFlag = passFlag;
             this.toCompiler = toCompiler;
             this.toRemoteVm = toRemoteVm;
+            this.showOption= showOption;
         }
 
     }
@@ -314,8 +318,8 @@
             return selectOptions(e -> e.getKey().toCompiler);
         }
 
-        String[] commonOptions() {
-            return selectOptions(e -> e.getKey().passFlag);
+        String[] shownOptions() {
+            return selectOptions(e -> e.getKey().showOption);
         }
 
         void addAll(OptionKind kind, Collection<String> vals) {
@@ -348,6 +352,7 @@
         private final OptionSpec<String> argModulePath = parser.accepts("module-path").withRequiredArg();
         private final OptionSpec<String> argAddModules = parser.accepts("add-modules").withRequiredArg();
         private final OptionSpec<String> argAddExports = parser.accepts("add-exports").withRequiredArg();
+        private final OptionSpecBuilder  argEnablePreview = parser.accepts("enable-preview");
         private final NonOptionArgumentSpec<String> argNonOptions = parser.nonOptions();
 
         private Options opts = new Options();
@@ -449,6 +454,13 @@
                     .map(mp -> mp.contains("=") ? mp : mp + "=ALL-UNNAMED")
                     .collect(toList())
             );
+            if (options.has(argEnablePreview)) {
+                opts.addAll(OptionKind.ENABLE_PREVIEW, List.of(
+                        OptionKind.ENABLE_PREVIEW.optionFlag));
+                opts.addAll(OptionKind.SOURCE_RELEASE, List.of(
+                        OptionKind.SOURCE_RELEASE.optionFlag,
+                        System.getProperty("java.specification.version")));
+            }
 
             if (failed) {
                 exitCode = 1;
@@ -1062,6 +1074,7 @@
             builder.executionEngine(executionControlSpec);
         }
         state = builder.build();
+        InternalDebugControl.setDebugFlags(state, debugFlags);
         shutdownSubscription = state.onShutdown((JShell deadState) -> {
             if (deadState == state) {
                 hardmsg("jshell.msg.terminated");
@@ -2234,11 +2247,10 @@
             InternalDebugControl.setDebugFlags(state, debug ? DBG_GEN : 0);
             fluff("Debugging %s", debug ? "on" : "off");
         } else {
-            int flags = 0;
             for (char ch : arg.toCharArray()) {
                 switch (ch) {
                     case '0':
-                        flags = 0;
+                        debugFlags = 0;
                         debug = false;
                         fluff("Debugging off");
                         break;
@@ -2247,36 +2259,41 @@
                         fluff("REPL tool debugging on");
                         break;
                     case 'g':
-                        flags |= DBG_GEN;
+                        debugFlags |= DBG_GEN;
                         fluff("General debugging on");
                         break;
                     case 'f':
-                        flags |= DBG_FMGR;
+                        debugFlags |= DBG_FMGR;
                         fluff("File manager debugging on");
                         break;
                     case 'c':
-                        flags |= DBG_COMPA;
+                        debugFlags |= DBG_COMPA;
                         fluff("Completion analysis debugging on");
                         break;
                     case 'd':
-                        flags |= DBG_DEP;
+                        debugFlags |= DBG_DEP;
                         fluff("Dependency debugging on");
                         break;
                     case 'e':
-                        flags |= DBG_EVNT;
+                        debugFlags |= DBG_EVNT;
                         fluff("Event debugging on");
                         break;
                     case 'w':
-                        flags |= DBG_WRAP;
+                        debugFlags |= DBG_WRAP;
                         fluff("Wrap debugging on");
                         break;
+                    case 'b':
+                        cmdout.printf("RemoteVM Options: %s\nCompiler options: %s\n",
+                                Arrays.toString(options.remoteVmOptions()),
+                                Arrays.toString(options.compilerOptions()));
+                        break;
                     default:
                         error("Unknown debugging option: %c", ch);
-                        fluff("Use: 0 r g f c d e w");
+                        fluff("Use: 0 r g f c d e w b");
                         return false;
                 }
             }
-            InternalDebugControl.setDebugFlags(state, flags);
+            InternalDebugControl.setDebugFlags(state, debugFlags);
         }
         return true;
     }
@@ -3112,7 +3129,7 @@
         if (rawargs.trim().isEmpty()) {
             // No arguments, display current settings (as option flags)
             StringBuilder sb = new StringBuilder();
-            for (String a : options.commonOptions()) {
+            for (String a : options.shownOptions()) {
                 sb.append(
                         a.startsWith("-")
                             ? sb.length() > 0
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Tue Apr 24 10:20:22 2018 +0100
@@ -205,6 +205,7 @@
 \    --add-modules <module>(,<module>)*\n\
 \                          Specify modules to resolve, or all modules on the\n\
 \                            module path if <module> is ALL-MODULE-PATHs\n\
+\    --enable-preview      Allow code to depend on preview features of this release\n\
 \    --startup <file>      One run replacement for the startup definitions\n\
 \    --no-startup          Do not run the startup definitions\n\
 \    --feedback <mode>     Specify the initial feedback mode. The mode may be\n\
--- a/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Tue Apr 24 10:20:22 2018 +0100
@@ -82,7 +82,6 @@
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.parser.Parser;
 import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@@ -91,6 +90,7 @@
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
 import com.sun.tools.javac.util.Names;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_FMGR;
 import jdk.jshell.Snippet.Status;
 
 /**
@@ -202,6 +202,7 @@
                             .map(in -> sh.sourceToFileObject(fileManager, in))
                             .collect(Collectors.toList());
             DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+            state.debug(DBG_FMGR, "Task (%s %s) Options: %s\n", this, compilationUnits, allOptions);
             return javacTaskPool.getTask(null, fileManager, diagnostics, allOptions, null,
                                          compilationUnits, task -> {
                  JavacTaskImpl jti = (JavacTaskImpl) task;
--- a/src/jdk.pack/share/native/common-unpack/utils.h	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.pack/share/native/common-unpack/utils.h	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,16 +33,16 @@
 #endif
 
 // overflow management
-#define OVERFLOW ((uint)-1)
-#define PSIZE_MAX (OVERFLOW/2)  /* normal size limit */
+#define POVERFLOW ((uint)-1)
+#define PSIZE_MAX (POVERFLOW/2)  /* normal size limit */
 
 inline size_t scale_size(size_t size, size_t scale) {
-  return (size > PSIZE_MAX / scale) ? OVERFLOW : size * scale;
+  return (size > PSIZE_MAX / scale) ? POVERFLOW : size * scale;
 }
 
 inline size_t add_size(size_t size1, size_t size2) {
   return ((size1 | size2 | (size1 + size2)) > PSIZE_MAX)
-    ? OVERFLOW
+    ? POVERFLOW
     : size1 + size2;
 }
 
--- a/src/jdk.pack/share/native/unpack200/main.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.pack/share/native/unpack200/main.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -59,7 +59,7 @@
 #include "unpack.h"
 
 
-JNIEXPORT int JNICALL
+JNIEXPORT int
 main(int argc, char **argv) {
     return unpacker::run(argc, argv);
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Apr 24 10:20:22 2018 +0100
@@ -2969,7 +2969,7 @@
     }
 
     private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final int callSiteFlags) {
-        if (getMap().containsArrayKeys()) {
+        if (hasDefinedArrayProperties()) {
             final String       key  = JSType.toString(longIndex);
             final FindProperty find = findProperty(key, true);
             if (find != null) {
@@ -2981,7 +2981,7 @@
     }
 
     private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final int callSiteFlags) {
-         if (getMap().containsArrayKeys()) {
+         if (hasDefinedArrayProperties()) {
             final String       key  = JSType.toString(longIndex);
             final FindProperty find = findProperty(key, true);
             if (find != null) {
@@ -2993,7 +2993,7 @@
     }
 
     private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final int callSiteFlags) {
-        if (getMap().containsArrayKeys()) {
+        if (hasDefinedArrayProperties()) {
             final String       key  = JSType.toString(longIndex);
             final FindProperty find = findProperty(key, true);
             if (find != null) {
@@ -3004,6 +3004,15 @@
         return false;
     }
 
+    private boolean hasDefinedArrayProperties() {
+        for (ScriptObject obj = this; obj != null; obj = obj.getProto()) {
+            if (obj.getMap().containsArrayKeys()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     //value agnostic
     private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) {
         if (longIndex >= oldLength) {
--- a/test/hotspot/gtest/memory/test_metaspace_allocation.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/gtest/memory/test_metaspace_allocation.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -26,6 +26,7 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/metaspace.hpp"
 #include "runtime/mutex.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
@@ -104,7 +105,12 @@
     // Let every ~10th space be an anonymous one to test different allocation patterns.
     const Metaspace::MetaspaceType msType = (os::random() % 100 < 10) ?
       Metaspace::AnonymousMetaspaceType : Metaspace::StandardMetaspaceType;
-    _spaces[i].space = new ClassLoaderMetaspace(_spaces[i].lock, msType);
+    {
+      // Pull lock during space creation, since this is what happens in the VM too
+      // (see ClassLoaderData::metaspace_non_null(), which we mimick here).
+      MutexLockerEx ml(_spaces[i].lock,  Mutex::_no_safepoint_check_flag);
+      _spaces[i].space = new ClassLoaderMetaspace(_spaces[i].lock, msType);
+    }
     _spaces[i].allocated = 0;
     ASSERT_TRUE(_spaces[i].space != NULL);
   }
@@ -171,6 +177,7 @@
             } else {
               size = os::random() % 64;
             }
+            // Note: In contrast to space creation, no need to lock here. ClassLoaderMetaspace::allocate() will lock itself.
             MetaWord* const p = _spaces[index].space->allocate(size, mdType);
             if (p == NULL) {
               // We very probably did hit the metaspace "until-gc" limit.
@@ -196,6 +203,7 @@
           force_switch = true;
         } else {
           assert(_spaces[index].space != NULL && _spaces[index].allocated > 0, "Sanity");
+          // Note: do not lock here. In the "wild" (the VM), we do not so either (see ~ClassLoaderData()).
           delete _spaces[index].space;
           _spaces[index].space = NULL;
           _spaces[index].allocated = 0;
--- a/test/hotspot/gtest/utilities/test_globalCounter.cpp	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/gtest/utilities/test_globalCounter.cpp	Tue Apr 24 10:20:22 2018 +0100
@@ -29,8 +29,8 @@
 #include "utilities/globalCounter.inline.hpp"
 #include "utilitiesHelper.inline.hpp"
 
-#define GOOD 1337
-#define BAD  4711
+#define GOOD_VALUE 1337
+#define BAD_VALUE  4711
 
 struct TestData {
   long test_value;
@@ -50,13 +50,13 @@
       GlobalCounter::critical_section_begin(this);
       volatile TestData* test = OrderAccess::load_acquire(_test);
       long value = OrderAccess::load_acquire(&test->test_value);
-      ASSERT_EQ(value, GOOD);
+      ASSERT_EQ(value, GOOD_VALUE);
       GlobalCounter::critical_section_end(this);
       {
         GlobalCounter::CriticalSection cs(this);
         volatile TestData* test = OrderAccess::load_acquire(_test);
         long value = OrderAccess::load_acquire(&test->test_value);
-        ASSERT_EQ(value, GOOD);
+        ASSERT_EQ(value, GOOD_VALUE);
       }
     }
   }
@@ -81,7 +81,7 @@
     RCUReaderThread* reader4 = new RCUReaderThread(&post, &test, &wrt_start);
 
     TestData* tmp = new TestData();
-    tmp->test_value = GOOD;
+    tmp->test_value = GOOD_VALUE;
     OrderAccess::release_store_fence(&test, tmp);
 
     reader1->doit();
@@ -98,10 +98,10 @@
     for (int i = 0; i < 100000 && stop_ms > os::javaTimeMillis(); i++) {
       volatile TestData* free_tmp = test;
       tmp = new TestData();
-      tmp->test_value = GOOD;
+      tmp->test_value = GOOD_VALUE;
       OrderAccess::release_store(&test, tmp);
       GlobalCounter::write_synchronize();
-      free_tmp->test_value = BAD;
+      free_tmp->test_value = BAD_VALUE;
       delete free_tmp;
     }
     RCUReaderThread::_exit = true;
--- a/test/hotspot/jtreg/TEST.groups	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/TEST.groups	Tue Apr 24 10:20:22 2018 +0100
@@ -70,7 +70,13 @@
 
 hotspot_not_fast_compiler = \
   :hotspot_compiler \
-  -:tier1_compiler
+  -:tier1_compiler \
+  -:hotspot_slow_compiler
+
+hotspot_slow_compiler = \
+  compiler/codegen/aes \
+  compiler/codecache/stress \
+  compiler/gcbarriers/PreserveFPRegistersTest.java
 
 tier1_compiler_1 = \
   compiler/arraycopy/ \
@@ -102,9 +108,7 @@
   compiler/integerArithmetic/ \
   compiler/interpreter/ \
   compiler/jvmci/ \
-  -compiler/codegen/aes \
-  -compiler/codecache/stress \
-  -compiler/gcbarriers/PreserveFPRegistersTest.java
+  -:hotspot_slow_compiler
 
 tier1_compiler_3 = \
   compiler/intrinsics/ \
@@ -133,12 +137,21 @@
 
 ctw_1 = \
   applications/ctw/modules/ \
-  -:ctw_2
+  -:ctw_2 \
+  -:ctw_3
 
 ctw_2 = \
   applications/ctw/modules/java_base.java \
   applications/ctw/modules/java_desktop.java
 
+ctw_3 = \
+  applications/ctw/modules/javafx_graphics.java \
+  applications/ctw/modules/java_xml.java \
+  applications/ctw/modules/jdk_compiler.java \
+  applications/ctw/modules/jdk_internal_vm_compiler.java \
+  applications/ctw/modules/jdk_localedata.java \
+  applications/ctw/modules/jdk_scripting_nashorn.java \
+
 tier1_gc = \
   :tier1_gc_1 \
   :tier1_gc_2 \
--- a/test/hotspot/jtreg/compiler/aot/fingerprint/CDSDumper.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/compiler/aot/fingerprint/CDSDumper.java	Tue Apr 24 10:20:22 2018 +0100
@@ -31,18 +31,19 @@
 import jdk.test.lib.process.ProcessTools;
 
 // Usage:
-// java CDSDumper <classpath> <classlist> <archive> <class1> <class2> ...
+// java CDSDumper <classpath> <classlist> <archive> <heapsize> <class1> <class2> ...
 public class CDSDumper {
     public static void main(String[] args) throws Exception {
         String classpath = args[0];
         String classlist = args[1];
         String archive = args[2];
+        String heapsize = args[3];
 
         // Prepare the classlist
         FileOutputStream fos = new FileOutputStream(classlist);
         PrintStream ps = new PrintStream(fos);
 
-        for (int i=3; i<args.length; i++) {
+        for (int i=4; i<args.length; i++) {
             ps.println(args[i].replace('.', '/'));
         }
         ps.close();
@@ -50,6 +51,7 @@
 
         // Dump the archive
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            heapsize,
             "-XX:+IgnoreUnrecognizedVMOptions",
             "-XX:+UnlockCommercialFeatures",
             "-XX:+UseAppCDS",
@@ -58,9 +60,12 @@
             "-XX:ExtraSharedClassListFile=" + classlist,
             "-XX:SharedArchiveFile=" + archive,
             "-Xshare:dump",
+            "-Xlog:gc+heap+coops",
             "-Xlog:cds");
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        System.out.println("[stdout = " + output.getStdout() + "]");
+        System.out.println("[stderr = " + output.getStderr() + "]");
         output.shouldContain("Loading classes to share");
         output.shouldHaveExitValue(0);
     }
--- a/test/hotspot/jtreg/compiler/aot/fingerprint/SelfChangedCDS.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/compiler/aot/fingerprint/SelfChangedCDS.java	Tue Apr 24 10:20:22 2018 +0100
@@ -36,7 +36,7 @@
  *      -class compiler.aot.fingerprint.Blah
  *
  * @run driver ClassFileInstaller -jar SelfChangedCDS.jar compiler.aot.fingerprint.Blah
- * @run main compiler.aot.fingerprint.CDSDumper SelfChangedCDS.jar SelfChangedCDS.classlist SelfChangedCDS.jsa
+ * @run main compiler.aot.fingerprint.CDSDumper SelfChangedCDS.jar SelfChangedCDS.classlist SelfChangedCDS.jsa -showversion
  *      compiler.aot.fingerprint.Blah
  *
  * @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
@@ -46,6 +46,7 @@
  *      -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
  *      -XX:+IgnoreUnrecognizedVMOptions
  *      -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
+ *      -Xlog:cds -Xlog:gc+heap+coops
  *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
  *      compiler.aot.fingerprint.Blah TEST-UNMODIFIED
  *
@@ -61,6 +62,26 @@
  *      -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
  *      -XX:+IgnoreUnrecognizedVMOptions
  *      -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
+ *      -Xlog:cds -Xlog:gc+heap+coops
  *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
  *      compiler.aot.fingerprint.Blah TEST-MODIFIED
+ *
+ *
+ * @run driver compiler.aot.AotCompiler -libname libSelfChanged.so
+ *      -class compiler.aot.fingerprint.Blah
+ *      -extraopt -Xmx512m
+ *
+ * @run main compiler.aot.fingerprint.CDSDumper SelfChangedCDS.jar SelfChangedCDS.classlist SelfChangedCDS.jsa -Xmx512m
+ *      compiler.aot.fingerprint.Blah
+ *
+ * @run main compiler.aot.fingerprint.CDSRunner -Xmx512m -cp SelfChangedCDS.jar
+ *      compiler.aot.fingerprint.Blah TEST-UNMODIFIED
+ * @run main compiler.aot.fingerprint.CDSRunner -Xmx512m -cp SelfChangedCDS.jar
+ *      -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
+ *      -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
+ *      -XX:+IgnoreUnrecognizedVMOptions
+ *      -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
+ *      -Xlog:cds -Xlog:gc+heap+coops
+ *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
+ *      compiler.aot.fingerprint.Blah TEST-UNMODIFIED
  */
--- a/test/hotspot/jtreg/runtime/CDSCompressedKPtrs/XShareAuto.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/runtime/CDSCompressedKPtrs/XShareAuto.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @requires vm.cds
  * @bug 8005933
- * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server.
+ * @summary -Xshare:auto is the default when -Xshare is not specified
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -45,34 +45,30 @@
         output.shouldContain("Loading classes to share");
         output.shouldHaveExitValue(0);
 
-        pb = ProcessTools.createJavaProcessBuilder(
-            "-server", "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./XShareAuto.jsa", "-version");
-        output = new OutputAnalyzer(pb.start());
-        String outputString = output.getOutput();
-        // We asked for server but it could be aliased to something else
-        if (outputString.contains("Server VM") && !outputString.contains("emulated-client")) {
-            // In server case we don't expect to see sharing flag
-            output.shouldNotContain("sharing");
+
+        // We have 2 test cases:
+        String cases[] = {
+            "-Xshare:auto",    // case [1]: -Xshare:auto is explicitly specified.
+            "-showversion"     // case [2]: -Xshare:auto is not explicitly specified,
+                               //           but VM should still use it by default.
+        };
+
+        for (String x : cases) {
+            pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:SharedArchiveFile=./XShareAuto.jsa",
+                "-Xlog:cds",
+                x,
+                "-version");
+            output = new OutputAnalyzer(pb.start());
+            String outputString = output.getOutput();
+
+            if (!outputString.contains("Unable to map")) {
+                // sharing may not be enabled if XShareAuto.jsa cannot be mapped due to
+                // ASLR.
+                output.shouldContain("sharing");
+            }
             output.shouldHaveExitValue(0);
         }
-        else {
-            System.out.println("Skipping test - no Server VM available");
-            return;
-        }
-
-        pb = ProcessTools.createJavaProcessBuilder(
-            "-server", "-Xshare:auto", "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=./XShareAuto.jsa", "-Xlog:cds", "-version");
-        output = new OutputAnalyzer(pb.start());
-        try {
-            output.shouldContain("sharing");
-        } catch (RuntimeException e) {
-            // if sharing failed due to ASLR or similar reasons,
-            // check whether sharing was attempted at all (UseSharedSpaces)
-            output.shouldContain("UseSharedSpaces:");
-            output.shouldNotContain("Unable to map %s");
-        }
-        output.shouldHaveExitValue(0);
     }
 }
--- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,8 @@
             "-XX:SharedBaseAddress=8g",
             "-Xmx128m",
             "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Narrow klass base: 0x0000000000000000");
@@ -54,6 +56,8 @@
             "-XX:CompressedClassSpaceSize=3g",
             "-Xmx128m",
             "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Narrow klass base: 0x0000000000000000, Narrow klass shift: 3");
@@ -66,6 +70,8 @@
             "-Xmx30g",
             "-XX:-UseAOT", // AOT explicitly set klass shift to 3.
             "-Xlog:gc+metaspace=trace",
+            "-Xshare:off",
+            "-Xlog:cds=trace",
             "-XX:+VerifyBeforeGC", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Narrow klass base: 0x0000000000000000");
--- a/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("ResolvedMethod entry added for MemberNameLeak$Leak.callMe()V");
         output.shouldContain("ResolvedMethod entry found for MemberNameLeak$Leak.callMe()V");
-        output.shouldContain("ResolvedMethod entry removed for MemberNameLeak$Leak.callMe()V");
+        output.shouldContain("ResolvedMethod entry removed");
         output.shouldHaveExitValue(0);
     }
 
--- a/test/hotspot/jtreg/runtime/whitebox/WBStackSize.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/hotspot/jtreg/runtime/whitebox/WBStackSize.java	Tue Apr 24 10:20:22 2018 +0100
@@ -82,7 +82,9 @@
     }
 
     public static void main(String[] args) {
-        long configStackSize = wb.getIntxVMFlag("ThreadStackSize") * K;
+        boolean isCompilerThread = Thread.currentThread().getName().indexOf(" CompilerThread") > 0;
+        long configStackSize = isCompilerThread ? wb.getIntxVMFlag("CompilerThreadStackSize") * K
+                                                : wb.getIntxVMFlag("ThreadStackSize") * K;
         System.out.println("ThreadStackSize VM option: " + configStackSize);
 
         long stackProtectionSize = wb.getIntxVMFlag("StackShadowPages") * wb.getVMPageSize();
--- a/test/jdk/ProblemList.txt	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/ProblemList.txt	Tue Apr 24 10:20:22 2018 +0100
@@ -586,6 +586,7 @@
 
 javax/net/ssl/DTLS/PacketLossRetransmission.java                8169086 macosx-x64
 javax/net/ssl/DTLS/RespondToRetransmit.java                     8169086 macosx-x64
+javax/net/ssl/DTLS/CipherSuite.java                             8202059 macosx-x64
 
 sun/security/krb5/auto/UnboundSSL.java                          8180265 windows-all
 sun/security/provider/KeyStore/DKSTest.sh                       8180266 windows-all
@@ -738,6 +739,8 @@
 
 com/sun/jdi/RedefineImplementor.sh                              8004127 generic-all
 
+com/sun/jdi/JdbExprTest.sh                                      8185803 generic-all
+
 com/sun/jdi/JdbMethodExitTest.sh                                8171483 generic-all
 
 com/sun/jdi/RepStep.java                                        8043571 generic-all
--- a/test/jdk/TEST.groups	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/TEST.groups	Tue Apr 24 10:20:22 2018 +0100
@@ -1,4 +1,4 @@
-#  Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+#  Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
 #  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 #  This code is free software; you can redistribute it and/or modify it
@@ -34,12 +34,14 @@
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
     :jdk_math \
-    tools/pack200
+    tools/pack200 \
+    -java/util/Arrays/TimSortStackSize2.java
 
 tier2 = \
     :tier2_part1 \
     :tier2_part2 \
-    :tier2_part3
+    :tier2_part3 \
+    java/util/Arrays/TimSortStackSize2.java
 
 # com/sun/crypto/provider/Cipher is in tier1 because of JDK-8132855
 tier2_part1 = \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/Socket/RejectIPv6.java	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8201510
+ * @summary Make sure IPv6 addresses are rejected when the System option
+ *          java.net.preferIPv4Stack is set to true
+ * @run main/othervm -Djava.net.preferIPv4Stack=true RejectIPv6
+ */
+
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+public class RejectIPv6 {
+
+    public static void main(String [] argv) throws Throwable {
+        ServerSocket serverSocket = new ServerSocket(0);
+        serverSocket.setSoTimeout(1000);
+        int serverPort = serverSocket.getLocalPort();
+        Socket clientSocket = new Socket();
+
+        test("bind", () -> clientSocket.bind(
+                new InetSocketAddress("::1", 0)));
+
+        test("connect", () -> clientSocket.connect(
+                new InetSocketAddress("::1", serverPort), 1000));
+    }
+
+    static void test(String msg, CodeToTest codeToTest) throws Throwable {
+        Thread client = new Thread(() ->
+            {
+                try {
+                    codeToTest.run();
+                    throw new RuntimeException(msg +
+                            " failed to reject IPv6 address");
+                } catch (SocketException ok) {
+                } catch (Exception exc) {
+                    throw new RuntimeException("unexpected", exc);
+                }
+            });
+        client.start();
+        client.join();
+    }
+
+    interface CodeToTest {
+        void run() throws Exception;
+    }
+}
--- a/test/jdk/java/net/Socket/setReuseAddress/Basic.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/net/Socket/setReuseAddress/Basic.java	Tue Apr 24 10:20:22 2018 +0100
@@ -25,11 +25,15 @@
  * @test
  * @bug 4476378
  * @summary Check the specific behaviour of the setReuseAddress(boolean)
- * method.
+ *          method.
  * @run main Basic
  * @run main/othervm -Dsun.net.useExclusiveBind Basic
+ * @run main/othervm -Dsun.net.useExclusiveBind=true Basic
  * @run main/othervm -Djava.net.preferIPv4Stack=true Basic
- * @run main/othervm -Dsun.net.useExclusiveBind -Djava.net.preferIPv4Stack=true Basic
+ * @run main/othervm -Dsun.net.useExclusiveBind
+ *                   -Djava.net.preferIPv4Stack=true Basic
+ * @run main/othervm -Dsun.net.useExclusiveBind=true
+ *                   -Djava.net.preferIPv4Stack=true Basic
  */
 import java.net.*;
 
--- a/test/jdk/java/net/Socket/setReuseAddress/Restart.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/net/Socket/setReuseAddress/Restart.java	Tue Apr 24 10:20:22 2018 +0100
@@ -28,8 +28,12 @@
  *          after a crash.
  * @run main Restart
  * @run main/othervm -Dsun.net.useExclusiveBind Restart
+ * @run main/othervm -Dsun.net.useExclusiveBind=true Restart
  * @run main/othervm -Djava.net.preferIPv4Stack=true Restart
- * @run main/othervm -Dsun.net.useExclusiveBind -Djava.net.preferIPv4Stack=true Restart
+ * @run main/othervm -Dsun.net.useExclusiveBind
+ *                   -Djava.net.preferIPv4Stack=true Restart
+ * @run main/othervm -Dsun.net.useExclusiveBind=true
+ *                   -Djava.net.preferIPv4Stack=true Restart
  */
 import java.net.*;
 
--- a/test/jdk/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
  * @bug 4607272 6842687 6878369 6944810 7023403
  * @summary Unit test for AsynchronousSocketChannel(use -Dseed=X to set PRNG seed)
  * @library /test/lib
- * @build jdk.test.lib.RandomFactory
- * @run main Basic -skipSlowConnectTest
+ * @build jdk.test.lib.RandomFactory jdk.test.lib.Utils
+ * @run main/othervm/timeout=600 Basic -skipSlowConnectTest
  * @key randomness intermittent
  */
 
@@ -79,11 +79,16 @@
         private final InetSocketAddress address;
 
         Server() throws IOException {
-            ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
+            this(0);
+        }
 
-            InetAddress lh = InetAddress.getLocalHost();
-            int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
-            address = new InetSocketAddress(lh, port);
+        Server(int recvBufSize) throws IOException {
+            ssc = ServerSocketChannel.open();
+            if (recvBufSize > 0) {
+                ssc.setOption(SO_RCVBUF, recvBufSize);
+            }
+            ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+            address = (InetSocketAddress)ssc.getLocalAddress();
         }
 
         InetSocketAddress address() {
@@ -293,7 +298,7 @@
 
         System.out.println("-- asynchronous close when reading --");
 
-        try (Server server = new Server()) {
+        try (Server server = new Server(1)) {
             ch = AsynchronousSocketChannel.open();
             ch.connect(server.address()).get();
 
@@ -325,6 +330,8 @@
 
             ch = AsynchronousSocketChannel.open();
             ch.connect(server.address()).get();
+            SocketChannel peer = server.accept();
+            peer.setOption(SO_RCVBUF, 1);
 
             final AtomicReference<Throwable> writeException =
                 new AtomicReference<Throwable>();
@@ -333,10 +340,13 @@
             final AtomicInteger numCompleted = new AtomicInteger();
             ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
                 public void completed(Integer result, AsynchronousSocketChannel ch) {
+                    System.out.println("completed write to async channel: " + result);
                     numCompleted.incrementAndGet();
                     ch.write(genBuffer(), ch, this);
+                    System.out.println("started another write to async channel: " + result);
                 }
                 public void failed(Throwable x, AsynchronousSocketChannel ch) {
+                    System.out.println("failed write to async channel");
                     writeException.set(x);
                 }
             });
@@ -347,7 +357,8 @@
             // the internal channel state indicates it is writing
             int prevNumCompleted = numCompleted.get();
             do {
-                Thread.sleep(1000);
+                Thread.sleep((long)(1000 * jdk.test.lib.Utils.TIMEOUT_FACTOR));
+                System.out.println("check if buffer is filled up");
                 if (numCompleted.get() == prevNumCompleted) {
                     break;
                 }
@@ -357,14 +368,19 @@
             // attempt a concurrent write -
             // should fail with WritePendingException
             try {
+                System.out.println("concurrent write to async channel");
                 ch.write(genBuffer());
+                System.out.format("prevNumCompleted: %d, numCompleted: %d%n",
+                                  prevNumCompleted, numCompleted.get());
                 throw new RuntimeException("WritePendingException expected");
             } catch (WritePendingException x) {
             }
 
             // close channel - should cause initial write to complete
+            System.out.println("closing async channel...");
             ch.close();
-            server.accept().close();
+            System.out.println("closed async channel");
+            peer.close();
 
             // wait for exception
             while (writeException.get() == null) {
--- a/test/jdk/java/util/Arrays/TimSortStackSize2.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/Arrays/TimSortStackSize2.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *     -XX:+WhiteBoxAPI TimSortStackSize2
  * @summary Test TimSort stack size on big arrays
+ * @key intermittent
  */
 import java.util.ArrayList;
 import java.util.Arrays;
--- a/test/jdk/java/util/Optional/Basic.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/Optional/Basic.java	Tue Apr 24 10:20:22 2018 +0100
@@ -52,6 +52,7 @@
         assertFalse(empty.equals("unexpected"));
 
         assertFalse(empty.isPresent());
+        assertTrue(empty.isEmpty());
         assertEquals(empty.hashCode(), 0);
         assertEquals(empty.orElse("x"), "x");
         assertEquals(empty.orElseGet(() -> "y"), "y");
@@ -87,6 +88,7 @@
         assertFalse(opt.equals("unexpected"));
 
         assertTrue(opt.isPresent());
+        assertFalse(opt.isEmpty());
         assertEquals(opt.hashCode(), expected.hashCode());
         assertEquals(opt.orElse("unexpected"), expected);
         assertEquals(opt.orElseGet(() -> "unexpected"), expected);
--- a/test/jdk/java/util/Optional/BasicDouble.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/Optional/BasicDouble.java	Tue Apr 24 10:20:22 2018 +0100
@@ -51,6 +51,7 @@
         assertFalse(empty.equals("unexpected"));
 
         assertFalse(empty.isPresent());
+        assertTrue(empty.isEmpty());
         assertEquals(empty.hashCode(), 0);
         assertEquals(empty.orElse(UNEXPECTED), UNEXPECTED);
         assertEquals(empty.orElseGet(() -> UNEXPECTED), UNEXPECTED);
@@ -86,6 +87,7 @@
         assertFalse(opt.equals("unexpected"));
 
         assertTrue(opt.isPresent());
+        assertFalse(opt.isEmpty());
         assertEquals(opt.hashCode(), Double.hashCode(expected));
         assertEquals(opt.orElse(UNEXPECTED), expected);
         assertEquals(opt.orElseGet(() -> UNEXPECTED), expected);
--- a/test/jdk/java/util/Optional/BasicInt.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/Optional/BasicInt.java	Tue Apr 24 10:20:22 2018 +0100
@@ -52,6 +52,7 @@
         assertFalse(empty.equals("unexpected"));
 
         assertFalse(empty.isPresent());
+        assertTrue(empty.isEmpty());
         assertEquals(empty.hashCode(), 0);
         assertEquals(empty.orElse(UNEXPECTED), UNEXPECTED);
         assertEquals(empty.orElseGet(() -> UNEXPECTED), UNEXPECTED);
@@ -87,6 +88,7 @@
         assertFalse(opt.equals("unexpected"));
 
         assertTrue(opt.isPresent());
+        assertFalse(opt.isEmpty());
         assertEquals(opt.hashCode(), Integer.hashCode(expected));
         assertEquals(opt.orElse(UNEXPECTED), expected);
         assertEquals(opt.orElseGet(() -> UNEXPECTED), expected);
--- a/test/jdk/java/util/Optional/BasicLong.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/Optional/BasicLong.java	Tue Apr 24 10:20:22 2018 +0100
@@ -51,6 +51,7 @@
         assertFalse(empty.equals("unexpected"));
 
         assertFalse(empty.isPresent());
+        assertTrue(empty.isEmpty());
         assertEquals(empty.hashCode(), 0);
         assertEquals(empty.orElse(UNEXPECTED), UNEXPECTED);
         assertEquals(empty.orElseGet(() -> UNEXPECTED), UNEXPECTED);
@@ -86,6 +87,7 @@
         assertFalse(opt.equals("unexpected"));
 
         assertTrue(opt.isPresent());
+        assertFalse(opt.isEmpty());
         assertEquals(opt.hashCode(), Long.hashCode(expected));
         assertEquals(opt.orElse(UNEXPECTED), expected);
         assertEquals(opt.orElseGet(() -> UNEXPECTED), expected);
--- a/test/jdk/java/util/zip/DeInflate.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/zip/DeInflate.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,23 @@
 
 /**
  * @test
- * @bug 7110149 8184306
+ * @bug 7110149 8184306 6341887
  * @summary Test basic deflater & inflater functionality
  * @key randomness
  */
 
 import java.io.*;
+import java.nio.*;
 import java.util.*;
 import java.util.zip.*;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 public class DeInflate {
 
+    private static Random rnd = new Random();
+
+
     static void checkStream(Deflater def, byte[] in, int len,
                             byte[] out1, byte[] out2, boolean nowrap)
         throws Throwable
@@ -61,6 +67,57 @@
         }
     }
 
+    static void checkByteBuffer(Deflater def, Inflater inf,
+                                ByteBuffer in, ByteBuffer out1, ByteBuffer out2,
+                                byte[] expected, int len, byte[] result,
+                                boolean out1ReadOnlyWhenInflate)
+            throws Throwable {
+        def.reset();
+        inf.reset();
+
+        def.setInput(in);
+        def.finish();
+        int m = def.deflate(out1);
+
+        out1.flip();
+        if (out1ReadOnlyWhenInflate)
+            out1 = out1.asReadOnlyBuffer();
+        inf.setInput(out1);
+        int n = inf.inflate(out2);
+
+        out2.flip();
+        out2.get(result, 0, n);
+
+        if (n != len || out2.position() != len ||
+            !Arrays.equals(Arrays.copyOf(expected, len), Arrays.copyOf(result, len)) ||
+            inf.inflate(result) != 0) {
+            throw new RuntimeException("De/inflater(buffer) failed:" + def);
+        }
+    }
+
+    static void checkByteBufferReadonly(Deflater def, Inflater inf,
+                                        ByteBuffer in, ByteBuffer out1, ByteBuffer out2)
+            throws Throwable {
+        def.reset();
+        inf.reset();
+        def.setInput(in);
+        def.finish();
+        int m = -1;
+        if (!out2.isReadOnly())
+            out2 = out2.asReadOnlyBuffer();
+        try {
+            m = def.deflate(out2);
+            throw new RuntimeException("deflater: ReadOnlyBufferException: failed");
+        } catch (ReadOnlyBufferException robe) {}
+        m = def.deflate(out1);
+        out1.flip();
+        inf.setInput(out1);
+        try {
+            inf.inflate(out2);
+            throw new RuntimeException("inflater: ReadOnlyBufferException: failed");
+        } catch (ReadOnlyBufferException robe) {}
+    }
+
     static void check(Deflater def, byte[] in, int len,
                       byte[] out1, byte[] out2, boolean nowrap)
         throws Throwable
@@ -83,6 +140,107 @@
                               m, n, len, Arrays.equals(in, out2));
             throw new RuntimeException("De/inflater failed:" + def);
         }
+
+        // readable
+        Arrays.fill(out1, (byte)0);
+        Arrays.fill(out2, (byte)0);
+        ByteBuffer bbIn = ByteBuffer.wrap(in, 0, len);
+        ByteBuffer bbOut1 = ByteBuffer.wrap(out1);
+        ByteBuffer bbOut2 = ByteBuffer.wrap(out2);
+        checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
+        checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
+
+        // readonly in
+        Arrays.fill(out1, (byte)0);
+        Arrays.fill(out2, (byte)0);
+        bbIn = ByteBuffer.wrap(in, 0, len).asReadOnlyBuffer();
+        bbOut1 = ByteBuffer.wrap(out1);
+        bbOut2 = ByteBuffer.wrap(out2);
+        checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
+        checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
+
+        // readonly out1 when inflate
+        Arrays.fill(out1, (byte)0);
+        Arrays.fill(out2, (byte)0);
+        bbIn = ByteBuffer.wrap(in, 0, len);
+        bbOut1 = ByteBuffer.wrap(out1);
+        bbOut2 = ByteBuffer.wrap(out2);
+        checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, true);
+        checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
+
+        // direct
+        bbIn = ByteBuffer.allocateDirect(in.length);
+        bbIn.put(in, 0, n).flip();
+        bbOut1 = ByteBuffer.allocateDirect(out1.length);
+        bbOut2 = ByteBuffer.allocateDirect(out2.length);
+        checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
+        checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
+    }
+
+    static void checkDict(Deflater def, Inflater inf, byte[] src,
+                          byte[] dstDef, byte[] dstInf,
+                          ByteBuffer dictDef,  ByteBuffer dictInf) throws Throwable {
+        def.reset();
+        inf.reset();
+
+        def.setDictionary(dictDef);
+        def.setInput(src);
+        def.finish();
+        int n = def.deflate(dstDef);
+
+        inf.setInput(dstDef, 0, n);
+        n = inf.inflate(dstInf);
+        if (n != 0 || !inf.needsDictionary()) {
+            throw new RuntimeException("checkDict failed: need dict to continue");
+        }
+        inf.setDictionary(dictInf);
+        n = inf.inflate(dstInf);
+        // System.out.println("result: " + new String(dstInf, 0, n));
+        if (n != src.length || !Arrays.equals(Arrays.copyOf(dstInf, n), src)) {
+            throw new RuntimeException("checkDict failed: inflate result");
+        }
+    }
+
+    static void checkDict(int level, int strategy) throws Throwable {
+
+        Deflater def = newDeflater(level, strategy, false, new byte[0]);
+        Inflater inf = new Inflater();
+
+        byte[] src = "hello world, hello world, hello sherman".getBytes();
+        byte[] dict = "hello".getBytes();
+
+        byte[] dstDef = new byte[1024];
+        byte[] dstInf = new byte[1024];
+
+        def.setDictionary(dict);
+        def.setInput(src);
+        def.finish();
+        int n = def.deflate(dstDef);
+
+        inf.setInput(dstDef, 0, n);
+        n = inf.inflate(dstInf);
+        if (n != 0 || !inf.needsDictionary()) {
+            throw new RuntimeException("checkDict failed: need dict to continue");
+        }
+        inf.setDictionary(dict);
+        n = inf.inflate(dstInf);
+        //System.out.println("result: " + new String(dstInf, 0, n));
+        if (n != src.length || !Arrays.equals(Arrays.copyOf(dstInf, n), src)) {
+            throw new RuntimeException("checkDict failed: inflate result");
+        }
+
+        ByteBuffer dictDef = ByteBuffer.wrap(dict);
+        ByteBuffer dictInf = ByteBuffer.wrap(dict);
+        checkDict(def, inf, src, dstDef, dstInf, dictDef, dictInf);
+
+        dictDef = ByteBuffer.allocateDirect(dict.length);
+        dictInf = ByteBuffer.allocateDirect(dict.length);
+        dictDef.put(dict).flip();
+        dictInf.put(dict).flip();
+        checkDict(def, inf, src, dstDef, dstInf, dictDef, dictInf);
+
+        def.end();
+        inf.end();
     }
 
     private static Deflater newDeflater(int level, int strategy, boolean dowrap, byte[] tmp) {
@@ -109,7 +267,7 @@
     public static void main(String[] args) throws Throwable {
 
         byte[] dataIn = new byte[1024 * 512];
-        new Random().nextBytes(dataIn);
+        rnd.nextBytes(dataIn);
         byte[] dataOut1 = new byte[dataIn.length + 1024];
         byte[] dataOut2 = new byte[dataIn.length];
 
@@ -130,6 +288,7 @@
                         // use a new deflater
                         Deflater def = newDeflater(level, strategy, dowrap, dataOut2);
                         check(def, dataIn, len, dataOut1, dataOut2, dowrap);
+                        def.end();
 
                         // reuse the deflater (with reset) and test on stream, which
                         // uses a "smaller" buffer (smaller than the overall data)
@@ -137,6 +296,8 @@
                         checkStream(def, dataIn, len, dataOut1, dataOut2, dowrap);
                     }
                 }
+                // test setDictionary()
+                checkDict(level, strategy);
             }
         }
     }
--- a/test/jdk/java/util/zip/FlaterTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/java/util/zip/FlaterTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,12 @@
 
 /**
  * @test
- * @bug 6348045
+ * @bug 6348045 6341887
  * @summary GZipOutputStream/InputStream goes critical(calls JNI_Get*Critical)
  * and causes slowness.  This test uses Deflater and Inflater directly.
  * @key randomness
  */
 
-import java.io.*;
 import java.nio.*;
 import java.util.*;
 import java.util.zip.*;
@@ -41,35 +40,37 @@
  */
 public class FlaterTest extends Thread {
     private static final int DATA_LEN = 1024 * 128;
-    private static byte[] data;
+
+    private static ByteBuffer dataDirect;
+    private static ByteBuffer dataHeap;
 
     // If true, print extra info.
     private static final boolean debug = false;
 
     // Set of Flater threads running.
-    private static Set flaters =
-        Collections.synchronizedSet(new HashSet());
+    private static Set<Flater> flaters =
+        Collections.synchronizedSet(new HashSet<>());
 
     /** Fill in {@code data} with random values. */
     static void createData() {
-        ByteBuffer bb = ByteBuffer.allocate(8);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        for (int i = 0; i < DATA_LEN; i++) {
-            bb.putDouble(0, Math.random());
-            baos.write(bb.array(), 0, 8);
+        ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8);
+        for (int i = 0; i < DATA_LEN * 8; i += 8) {
+            bb.putDouble(i, Math.random());
         }
-        data = baos.toByteArray();
-        if (debug) System.out.println("data length is " + data.length);
+        dataDirect = bb;
+        final ByteBuffer hb = ByteBuffer.allocate(bb.capacity());
+        hb.duplicate().put(bb.duplicate());
+        dataHeap = hb;
+        if (debug) System.out.println("data length is " + bb.capacity());
     }
 
     /** @return the length of the deflated {@code data}. */
-    private static int getDeflatedLength() throws Throwable {
-        int rc = 0;
+    private static int getDeflatedLength() {
         Deflater deflater = new Deflater();
-        deflater.setInput(data);
+        deflater.setInput(dataDirect.duplicate());
         deflater.finish();
-        byte[] out = new byte[data.length];
-        rc = deflater.deflate(out);
+        byte[] out = new byte[dataDirect.capacity()];
+        int rc = deflater.deflate(out);
         deflater.end();
         if (debug) System.out.println("deflatedLength is " + rc);
         return rc;
@@ -78,70 +79,98 @@
     /** Compares given bytes with those in {@code data}.
      * @throws Exception if given bytes don't match {@code data}.
      */
-    private static void validate(byte[] buf, int offset, int len) throws Exception {
+    private static void validate(ByteBuffer buf, int offset, int len) throws Exception {
         for (int i = 0; i < len; i++ ) {
-            if (buf[i] != data[offset+i]) {
+            if (buf.get(i) != dataDirect.get(offset+i)) {
                 throw new Exception("mismatch at " + (offset + i));
             }
         }
     }
 
-    public static void realMain(String[] args) throws Throwable {
+    public static void realMain(String[] args) {
+        int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5;
         createData();
-        int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5;
-        new FlaterTest().go(numThreads);
+        for (int srcMode = 0; srcMode <= 2; srcMode ++) {
+            for (int dstMode = 0; dstMode <= 2; dstMode ++) {
+                new FlaterTest().go(numThreads, srcMode, dstMode);
+            }
+        }
     }
 
-    private synchronized void go(int numThreads) throws Throwable {
+    private synchronized void go(int numThreads, int srcMode, int dstMode) {
         int deflatedLength = getDeflatedLength();
 
         long time = System.currentTimeMillis();
         for (int i = 0; i < numThreads; i++) {
-            Flater f = new Flater(deflatedLength);
+            Flater f = new Flater(deflatedLength, srcMode, dstMode);
             flaters.add(f);
             f.start();
         }
-        while (flaters.size() != 0) {
-            try {
-                Thread.currentThread().sleep(10);
-            } catch (InterruptedException ex) {
-                unexpected(ex);
+        synchronized (flaters) {
+            while (flaters.size() != 0) {
+                try {
+                    flaters.wait();
+                } catch (InterruptedException ex) {
+                    unexpected(ex);
+                }
             }
         }
         time = System.currentTimeMillis() - time;
         System.out.println("Time needed for " + numThreads
-                           + " threads to deflate/inflate: " + time + " ms.");
+                           + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")");
     }
 
     /** Deflates and inflates data. */
     static class Flater extends Thread {
         private final int deflatedLength;
+        private final int srcMode, dstMode;
 
-        private Flater(int length) {
+        private Flater(int length, int srcMode, int dstMode) {
             this.deflatedLength = length;
+            this.srcMode = srcMode;
+            this.dstMode = dstMode;
         }
 
         /** Deflates and inflates {@code data}. */
         public void run() {
             if (debug) System.out.println(getName() + " starting run()");
             try {
-                byte[] deflated = DeflateData(deflatedLength);
+                ByteBuffer deflated = DeflateData(deflatedLength);
                 InflateData(deflated);
             } catch (Throwable t) {
                 t.printStackTrace();
                 fail(getName() + " failed");
             } finally {
-                flaters.remove(this);
+                synchronized (flaters) {
+                    flaters.remove(this);
+                    if (flaters.isEmpty()) {
+                        flaters.notifyAll();
+                    }
+                }
             }
         }
 
         /** Returns a copy of {@code data} in deflated form. */
-        private byte[] DeflateData(int length) throws Throwable {
+        private ByteBuffer DeflateData(int length) {
             Deflater deflater = new Deflater();
-            deflater.setInput(data);
+            if (srcMode == 0) {
+                deflater.setInput(dataHeap.array());
+            } else if (srcMode == 1) {
+                deflater.setInput(dataHeap.duplicate());
+            } else {
+                assert srcMode == 2;
+                deflater.setInput(dataDirect.duplicate());
+            }
             deflater.finish();
-            byte[] out = new byte[length];
-            deflater.deflate(out);
+            ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length);
+            int deflated;
+            if (dstMode == 0) {
+                deflated = deflater.deflate(out.array(), 0, length);
+                out.position(deflated);
+            } else {
+                deflater.deflate(out);
+            }
+            out.flip();
             return out;
         }
 
@@ -149,14 +178,30 @@
          * inflation.
          * @throws Exception if inflated bytes don't match {@code data}.
          */
-        private void InflateData(byte[] bytes) throws Throwable {
+        private void InflateData(ByteBuffer bytes) throws Throwable {
             Inflater inflater = new Inflater();
-            inflater.setInput(bytes, 0, bytes.length);
+            if (dstMode == 0) {
+                inflater.setInput(bytes.array(), 0, bytes.remaining());
+            } else {
+                inflater.setInput(bytes);
+            }
+            if (inflater.getRemaining() == 0) {
+                throw new Exception("Nothing to inflate (bytes=" + bytes + ")");
+            }
             int len = 1024 * 8;
             int offset = 0;
+            ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len);
             while (inflater.getRemaining() > 0) {
-                byte[] buf = new byte[len];
-                int inflated = inflater.inflate(buf, 0, len);
+                buf.clear();
+                int inflated;
+                if (srcMode == 0) {
+                    inflated = inflater.inflate(buf.array(), 0, buf.remaining());
+                } else {
+                    inflated = inflater.inflate(buf);
+                }
+                if (inflated == 0) {
+                    throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")");
+                }
                 validate(buf, offset, inflated);
                 offset += inflated;
             }
--- a/test/jdk/jdk/modules/etc/UpgradeableModules.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/jdk/jdk/modules/etc/UpgradeableModules.java	Tue Apr 24 10:20:22 2018 +0100
@@ -46,6 +46,7 @@
         List.of("java.compiler",
                 "java.jnlp",
                 "jdk.internal.vm.compiler",
+                "jdk.internal.vm.compiler.management",
                 "jdk.deploy",
                 "jdk.javaws",
                 "jdk.plugin",
--- a/test/langtools/jdk/javadoc/tool/BadOptionsTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/jdk/javadoc/tool/BadOptionsTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - no value for --add-modules option");
+                "javadoc: error - error: no value for --add-modules option");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
@@ -104,7 +104,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - no value for --add-exports option");
+                "javadoc: error - error: no value for --add-exports option");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
@@ -116,7 +116,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - bad value for --add-exports option");
+                "javadoc: error - error: bad value for --add-exports option: 'm/p'");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
@@ -146,7 +146,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: cannot specify both --source-path and --module-source-path");
+                "error: cannot specify both --source-path and --module-source-path");
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
                 "1 error");
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/jshell/ToolEnablePreviewTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8199193
+ * @summary Tests for the --enable-preview option
+ * @run testng ToolEnablePreviewTest
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+public class ToolEnablePreviewTest extends ReplToolTesting {
+
+    @Test
+    public void testOptionDebug() {
+        String release = System.getProperty("java.specification.version");
+        test(
+                (a) -> assertCommand(a, "/debug b",
+                        "RemoteVM Options: []\n"
+                        + "Compiler options: []"),
+                (a) -> assertCommand(a, "/env --enable-preview",
+                        "|  Setting new options and restoring state."),
+                (a) -> assertCommandCheckOutput(a, "/debug b", s -> {
+                    assertTrue(s.contains("RemoteVM Options: [--enable-preview]"));
+                    assertTrue(s.contains("Compiler options: [-source, " + release + ", --enable-preview]")
+                            || s.contains("Compiler options: [--enable-preview, -source, " + release + "]"),
+                            "\nExpected -- " + "Compiler options: [-source, " + release + ", --enable-preview]"
+                            + "\nOr -- " + "Compiler options: [--enable-preview, -source, " + release + "]"
+                            + "\nBut got -- " + s);
+                })
+        );
+    }
+
+    @Test
+    public void testCommandLineFlag() {
+        String release = System.getProperty("java.specification.version");
+        test(new String[] {"--enable-preview"},
+                (a) -> assertCommandCheckOutput(a, "/debug b", s -> {
+                    assertTrue(s.contains("RemoteVM Options: [--enable-preview]"));
+                    assertTrue(s.contains("Compiler options: [-source, " + release + ", --enable-preview]")
+                            || s.contains("Compiler options: [--enable-preview, -source, " + release + "]"),
+                            "\nExpected -- " + "Compiler options: [-source, " + release + ", --enable-preview]"
+                            + "\nOr -- " + "Compiler options: [--enable-preview, -source, " + release + "]"
+                            + "\nBut got -- " + s);
+                })
+        );
+    }
+
+    @Test
+    public void testCompilerTestFlagEnv() {
+        test(new String[] {"-C", "-XDforcePreview"},
+                (a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
+                        "Error", "preview feature"),
+                (a) -> assertCommand(a, "/env --enable-preview",
+                        "|  Setting new options and restoring state."),
+                (a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
+                        "f ==> ")
+        );
+    }
+
+    @Test
+    public void testCompilerTestFlag() {
+        test(new String[] {"-C", "-XDforcePreview", "--enable-preview"},
+                (a) -> assertCommandOutputContains(a, "Function<Integer,Integer> f = i -> i + i",
+                        "f ==> "),
+                (a) -> assertCommandOutputContains(a, "f.apply(2)", "==> 4")
+        );
+    }
+
+}
--- a/test/langtools/tools/javac/6410653/T6410653.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2006, 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     6410653 6401277
- * @summary REGRESSION: javac crashes if -d or -s argument is a file
- * @author  Peter von der Ah\u00e9
- * @modules java.compiler
- *          jdk.compiler/com.sun.tools.javac.util:open
- */
-
-import java.lang.reflect.Field;
-import java.io.File;
-import java.io.ByteArrayOutputStream;
-import javax.tools.*;
-
-public class T6410653 {
-    public static void main(String... args) throws Exception {
-        File testSrc = new File(System.getProperty("test.src"));
-        String source = new File(testSrc, "T6410653.java").getPath();
-        Tool compiler = ToolProvider.getSystemJavaCompiler();
-        Module compilerModule = compiler.getClass().getModule();
-        Class<?> log = Class.forName(compilerModule, "com.sun.tools.javac.util.Log");
-        Field useRawMessages = log.getDeclaredField("useRawMessages");
-        useRawMessages.setAccessible(true);
-        useRawMessages.setBoolean(null, true);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        compiler.run(null, null, out, "-d", source, source);
-        System.err.println(">>>" + out + "<<<");
-        useRawMessages.setBoolean(null, false);
-        if (!out.toString().equals(String.format("%s%n",
-                                                 "javac: javac.err.file.not.directory"))) {
-            throw new AssertionError(out);
-        }
-        System.out.println("Test PASSED.  Running javac again to see localized output:");
-        compiler.run(null, null, System.out, "-d", source, source);
-    }
-}
--- a/test/langtools/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8009640
- * @summary -profile <compact> does not work when -bootclasspath specified
- * @library /tools/lib
- * @modules jdk.compiler/com.sun.tools.javac.api
- *          jdk.compiler/com.sun.tools.javac.main
- *          jdk.compiler/com.sun.tools.javac.util
- *          jdk.jdeps/com.sun.tools.javap
- * @build toolbox.ToolBox toolbox.JavacTask
- * @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest
- */
-
-import java.nio.file.Paths;
-
-import com.sun.tools.javac.util.Assert;
-
-import toolbox.JavacTask;
-import toolbox.Task;
-import toolbox.ToolBox;
-
-public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
-
-    private static final String TestSrc =
-        "public class Test {\n" +
-        "    javax.swing.JButton b;\n" +
-        "}";
-
-    public static void main(String args[]) throws Exception {
-        ToolBox tb = new ToolBox();
-        tb.writeFile("Test.java", TestSrc);
-
-        Task.Result result = new JavacTask(tb, Task.Mode.CMDLINE)
-                .options("-profile", "compact1",
-                        "-bootclasspath", Paths.get(ToolBox.testJDK, "jre/lib/rt.jar").toString())
-                .files("Test.java")
-                .run(Task.Expect.FAIL)
-                .writeAll();
-
-        String out = result.getOutput(Task.OutputKind.DIRECT);
-        Assert.check(out.startsWith(
-                "javac: profile and bootclasspath options cannot be used together"),
-                "Incorrect javac error output");
-    }
-
-}
--- a/test/langtools/tools/javac/diags/CheckResourceKeys.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/diags/CheckResourceKeys.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -233,7 +233,6 @@
         "compiler.misc.non.denotable.type",                 // UNUSED
         "compiler.misc.unnamed.package",                    // should be required, CR 6964147
         "compiler.warn.proc.type.already.exists",           // TODO in JavacFiler
-        "javac.err.invalid.arg",                            // UNUSED ??
         "javac.opt.arg.class",                              // UNUSED ??
         "javac.opt.arg.pathname",                           // UNUSED ??
         "javac.opt.moreinfo",                               // option commented out
--- a/test/langtools/tools/javac/diags/examples.not-yet.txt	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/diags/examples.not-yet.txt	Tue Apr 24 10:20:22 2018 +0100
@@ -157,3 +157,35 @@
 compiler.err.locn.module-info.not.allowed.on.patch.path
 compiler.misc.cant.resolve.modules
 compiler.misc.file.does.not.contain.module
+
+# these keys were in javac.properties and examples are hard to be produced for them
+# basically because in most cases the compilation ends with an exception
+compiler.err.bad.value.for.option
+compiler.err.empty.A.argument
+compiler.err.error.writing.file
+compiler.err.file.not.directory
+compiler.err.file.not.file
+compiler.err.file.not.found
+compiler.err.invalid.A.key
+compiler.err.invalid.flag
+compiler.err.invalid.profile
+compiler.err.invalid.source
+compiler.err.invalid.target
+compiler.err.no.source.files.classes
+compiler.err.no.value.for.option
+compiler.err.option.not.allowed.with.target
+compiler.err.option.too.many
+compiler.err.profile.bootclasspath.conflict
+compiler.err.release.bootclasspath.conflict
+compiler.err.repeated.value.for.patch.module
+compiler.err.req.arg
+compiler.err.sourcepath.modulesourcepath.conflict
+compiler.err.two.class.loaders.1
+compiler.err.two.class.loaders.2
+compiler.err.unmatched.quote
+compiler.err.unsupported.release.version
+compiler.warn.profile.target.conflict
+compiler.warn.source.target.conflict
+compiler.warn.target.default.source.conflict
+compiler.err.preview.not.latest
+compiler.err.preview.without.source.or.release
\ No newline at end of file
--- a/test/langtools/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,5 +22,6 @@
  */
 
 // key: compiler.warn.dir.path.element.not.directory
+// key: compiler.err.no.source.files
 // options: -Xlint:path
 // run: simple
--- a/test/langtools/tools/javac/doclint/DocLintTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/doclint/DocLintTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,7 +84,7 @@
         DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"),
         DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"),
 
-        OPT_BADARG(ERROR, "invalid flag: -Xdoclint:badarg");
+        OPT_BADARG(ERROR, "error: invalid flag: -Xdoclint:badarg");
 
         final Diagnostic.Kind kind;
         final String text;
--- a/test/langtools/tools/javac/doclint/IncludePackagesTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/doclint/IncludePackagesTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
         p1sp1sp2T(ERROR, "p1sp1sp2T.java:2:12: compiler.err.proc.messager: malformed HTML"),
         p2T(ERROR, "p2T.java:2:12: compiler.err.proc.messager: malformed HTML"),
         Default(ERROR, "Default.java:1:12: compiler.err.proc.messager: malformed HTML"),
-        INVALID_PACKAGE_ERROR(ERROR, "invalid flag: -Xdoclint/package:wrong+package");
+        INVALID_PACKAGE_ERROR(ERROR, "error: invalid flag: -Xdoclint/package:wrong+package");
 
         final Diagnostic.Kind kind;
         final String text;
--- a/test/langtools/tools/javac/modules/AddExportsTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/AddExportsTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: no value for --add-exports option");
+            "error: no value for --add-exports option");
     }
 
     @Test
@@ -123,7 +123,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: bad value for --add-exports option: '" + option + "'");
+            "error: bad value for --add-exports option: '" + option + "'");
     }
 
     @Test
@@ -158,7 +158,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: bad value for --add-exports option: '" + option + "'");
+            "error: bad value for --add-exports option: '" + option + "'");
     }
 
     @Test
--- a/test/langtools/tools/javac/modules/AddLimitMods.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/AddLimitMods.java	Tue Apr 24 10:20:22 2018 +0100
@@ -264,7 +264,7 @@
                    .writeAll()
                    .getOutputLines(Task.OutputKind.DIRECT);
 
-        if (!actual.contains("javac: option --add-modules not allowed with target 1.8")) {
+        if (!actual.contains("- compiler.err.option.not.allowed.with.target: --add-modules, 1.8")) {
             throw new IllegalStateException("incorrect errors; actual=" + actual);
         }
 
--- a/test/langtools/tools/javac/modules/AddModulesTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/AddModulesTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: no value for --add-modules option");
+            "error: no value for --add-modules option");
     }
 
     @Test
@@ -120,7 +120,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: bad value for --add-modules option");
+            "error: bad value for --add-modules option");
     }
 
     @Test
--- a/test/langtools/tools/javac/modules/AddReadsTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/AddReadsTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -352,7 +352,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: no value for --add-reads option");
+            "error: no value for --add-reads option");
     }
 
     @Test
@@ -421,7 +421,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: bad value for --add-reads option: '" + option + "'");
+            "error: bad value for --add-reads option: '" + option + "'");
     }
 
     @Test
@@ -572,7 +572,7 @@
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "javac: bad value for --add-reads option: 'm1x:m2x'");
+            "error: bad value for --add-reads option: 'm1x:m2x'");
     }
 
     @Test
--- a/test/langtools/tools/javac/modules/LimitModulesTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/LimitModulesTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("javac: no value for --limit-modules option"))
+        if (!log.contains("error: no value for --limit-modules option"))
             throw new Exception("expected output not found");
 
         log = new JavacTask(tb, Task.Mode.CMDLINE)
@@ -70,7 +70,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("javac: no value for --limit-modules option"))
+        if (!log.contains("error: no value for --limit-modules option"))
             throw new Exception("expected output not found");
     }
 
@@ -127,7 +127,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("javac: bad value for --limit-modules option"))
+        if (!log.contains("error: bad value for --limit-modules option"))
             throw new Exception("expected output not found");
     }
 
--- a/test/langtools/tools/javac/modules/ModuleSourcePathTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/ModuleSourcePathTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,7 +76,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("cannot specify both --source-path and --module-source-path"))
+        if (!log.contains("compiler.err.sourcepath.modulesourcepath.conflict"))
             throw new Exception("expected diagnostic not found");
     }
 
--- a/test/langtools/tools/javac/modules/PatchModulesTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/modules/PatchModulesTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,19 +98,19 @@
     @Test
     public void testDuplicates(Path base) throws Exception {
         test(asList("java.base=a", "java.compiler=b", "java.base=c"),
-            false, "--patch-module specified more than once for java.base");
+            false, "error: --patch-module specified more than once for java.base");
     }
 
     @Test
     public void testEmpty(Path base) throws Exception {
         test(asList(""),
-            false, "no value for --patch-module option");
+            false, "error: no value for --patch-module option");
     }
 
     @Test
     public void testInvalid(Path base) throws Exception {
         test(asList("java.base/java.lang=."),
-            false, "bad value for --patch-module option: 'java.base/java.lang=.'");
+            false, "error: bad value for --patch-module option: 'java.base/java.lang=.'");
     }
 
     void test(List<String> patches, String expect) throws Exception {
--- a/test/langtools/tools/javac/options/release/ReleaseOptionClashes.java	Tue Apr 24 10:17:23 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8072480
- * @summary Verify option clash between --release and -source is reported correctly.
- * @modules jdk.compiler/com.sun.tools.javac.util:open
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.tools.Tool;
-import javax.tools.ToolProvider;
-
-public class ReleaseOptionClashes {
-    public static void main(String... args) throws Exception {
-        new ReleaseOptionClashes().run();
-    }
-
-    void run() throws Exception {
-        doRunTest("7", "-bootclasspath", "any");
-        doRunTest("7", "-Xbootclasspath:any");
-        doRunTest("7", "-Xbootclasspath/a:any");
-        doRunTest("7", "-Xbootclasspath/p:any");
-        doRunTest("7", "-endorseddirs", "any");
-        doRunTest("7", "-extdirs", "any");
-        doRunTest("7", "-source", "8");
-        doRunTest("7", "-target", "8");
-        doRunTest("9", "--system", "none");
-        doRunTest("9", "--upgrade-module-path", "any");
-    }
-
-    void doRunTest(String release, String... args) throws Exception {
-        System.out.println("Testing clashes for arguments: " + Arrays.asList(args));
-        Class<?> log = Class.forName("com.sun.tools.javac.util.Log", true, cl);
-        Field useRawMessages = log.getDeclaredField("useRawMessages");
-        useRawMessages.setAccessible(true);
-        useRawMessages.setBoolean(null, true);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        List<String> options = new ArrayList<>();
-        options.addAll(Arrays.asList("--release", release));
-        options.addAll(Arrays.asList(args));
-        options.add(System.getProperty("test.src") + File.separator + "ReleaseOptionClashes.java");
-        compiler.run(null, null, out, options.toArray(new String[0]));
-        useRawMessages.setBoolean(null, false);
-        if (!out.toString().equals(String.format("%s%n%s%n",
-                                                 "javac: javac.err.release.bootclasspath.conflict",
-                                                 "javac.msg.usage")) &&
-            //-Xbootclasspath:any produces two warnings: one for -bootclasspath and one for -Xbootclasspath:
-            !out.toString().equals(String.format("%s%n%s%n%s%n%s%n",
-                                                 "javac: javac.err.release.bootclasspath.conflict",
-                                                 "javac.msg.usage",
-                                                 "javac: javac.err.release.bootclasspath.conflict",
-                                                 "javac.msg.usage"))) {
-            throw new AssertionError(out);
-        }
-        System.out.println("Test PASSED.  Running javac again to see localized output:");
-        compiler.run(null, null, System.out, options.toArray(new String[0]));
-    }
-
-    Tool compiler = ToolProvider.getSystemJavaCompiler();
-    ClassLoader cl = compiler.getClass().getClassLoader();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/options/smokeTests/OptionSmokeTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8196433
+ * @summary use the new error diagnostic approach at javac.Main
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.util
+ *          jdk.jdeps/com.sun.tools.javap
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner
+ * @run main OptionSmokeTest
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import com.sun.tools.javac.util.Assert;
+
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+import toolbox.JavacTask;
+import toolbox.Task;
+
+public class OptionSmokeTest extends TestRunner {
+    ToolBox tb = new ToolBox();
+
+    public OptionSmokeTest() {
+        super(System.err);
+    }
+
+    protected void runTests() throws Exception {
+        runTests(m -> new Object[] { Paths.get(m.getName()) });
+    }
+
+    Path[] findJavaFiles(Path... paths) throws Exception {
+        return tb.findJavaFiles(paths);
+    }
+
+    public static void main(String... args) throws Exception {
+        new OptionSmokeTest().runTests();
+    }
+
+    @Test
+    public void optionA1(Path base) throws Exception {
+        doTest(base,
+                "error: -A requires an argument; use '-Akey' or '-Akey=value'",
+                "-A");
+    }
+
+    @Test
+    public void optionA2(Path base) throws Exception {
+        doTest(base,
+                "error: key in annotation processor option '-A1e=2' is not a dot-separated sequence of identifiers",
+                "-A1e=2");
+    }
+
+    @Test
+    public void noFlag(Path base) throws Exception {
+        doTest(base, "error: invalid flag: -noFlag", "-noFlag");
+    }
+
+    @Test
+    public void profileAndBSP(Path base) throws Exception {
+        doTest(base, "error: profile and bootclasspath options cannot be used together",
+                "-profile compact1 -bootclasspath . -target 8 -source 8");
+    }
+
+    @Test
+    public void invalidProfile(Path base) throws Exception {
+        doTest(base, "error: invalid profile: noProfile",
+                "-profile noProfile");
+    }
+
+    @Test
+    public void invalidTarget(Path base) throws Exception {
+        doTest(base, "error: invalid target release: 999999",
+                "-target 999999");
+    }
+
+    @Test
+    public void optionNotAvailableWithTarget(Path base) throws Exception {
+        doTest(base, "error: option -profile not allowed with target 11",
+                "-profile compact1 -target 11");
+    }
+
+    @Test
+    public void optionTooMany(Path base) throws Exception {
+        doTest(base, "error: option --default-module-for-created-files can only be specified once",
+                "--default-module-for-created-files=m1x --default-module-for-created-files=m1x");
+    }
+
+    @Test
+    public void noSrcFiles(Path base) throws Exception {
+        doTestNoSource(base, "error: no source files", "-target 11");
+    }
+
+    @Test
+    public void requiresArg(Path base) throws Exception {
+        doTestNoSource(base, "error: -target requires an argument", "-target");
+    }
+
+    @Test
+    public void invalidSource(Path base) throws Exception {
+        doTestNoSource(base, "error: invalid source release: 999999", "-source 999999");
+    }
+
+    @Test
+    public void sourceAndModuleSourceCantBeTogether(Path base) throws Exception {
+        doTest(base, "error: cannot specify both --source-path and --module-source-path",
+                "--source-path . --module-source-path .");
+    }
+
+    @Test
+    public void sourceAndTargetMismatch(Path base) throws Exception {
+        doTest(base, "warning: source release 11 requires target release 11",
+                "-source 11 -target 10");
+    }
+
+    @Test
+    public void targetConflictsWithDefaultSource(Path base) throws Exception {
+        doTest(base, "warning: target release 10 conflicts with default source release 11",
+                "-target 10");
+    }
+
+    @Test
+    public void profileNotValidForTarget(Path base) throws Exception {
+        doTest(base, "warning: profile compact2 is not valid for target release 1.7",
+                "-profile compact2 -target 7 -source 7");
+    }
+
+    @Test
+    public void fileNotFound(Path base) throws Exception {
+        String log = new JavacTask(tb, Task.Mode.CMDLINE)
+                .files("notExistent/T.java")
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        Assert.check(log.startsWith("error: file not found: notExistent" + fileSeparator + "T.java"),
+                "real value of log:" + log);
+    }
+
+    static final String fileSeparator = System.getProperty("file.separator");
+
+    @Test
+    public void notADirectory(Path base) throws Exception {
+        doTest(base, "error: not a directory: notADirectory" + fileSeparator + "src" + fileSeparator + "Dummy.java",
+                "-d notADirectory" + fileSeparator + "src" + fileSeparator + "Dummy.java");
+    }
+
+    @Test
+    public void notAFile(Path base) throws Exception {
+        // looks like a java file, it is a directory
+        Path dir = base.resolve("dir.java");
+        tb.createDirectories(dir);
+        String log = new JavacTask(tb, Task.Mode.CMDLINE)
+                .spaceSeparatedOptions("-XDsourcefile " + dir)
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        Assert.check(log.startsWith("error: not a file: notAFile" + fileSeparator + "dir.java"));
+    }
+
+    @Test
+    public void badValueForOption(Path base) throws Exception {
+        doTestNoSource(base, "error: bad value for --patch-module option: \'notExistent\'",
+                "--patch-module notExistent");
+    }
+
+    @Test
+    public void patchModuleMoreThanOnce(Path base) throws Exception {
+        doTestNoSource(base, "error: --patch-module specified more than once for m",
+                "--patch-module m=. --patch-module m=.");
+    }
+
+    @Test
+    public void unmatchedQuoteInEnvVar(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "class Dummy {}");
+        String log = new JavacTask(tb, Task.Mode.EXEC)
+                .envVar("JDK_JAVAC_OPTIONS", "--add-exports jdk.compiler" + fileSeparator + "com.sun.tools.javac.jvm=\"ALL-UNNAMED")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.STDERR);
+        Assert.check(log.startsWith("error: unmatched quote in environment variable JDK_JAVAC_OPTIONS"));
+    }
+
+    @Test
+    public void optionCantBeUsedWithRelease(Path base) throws Exception {
+        doTestNoSource(base, "error: option -source cannot be used together with --release",
+                "--release 7 -source 7");
+    }
+
+    @Test
+    public void releaseVersionNotSupported(Path base) throws Exception {
+        doTestNoSource(base, "error: release version 99999999 not supported",
+                "--release 99999999");
+    }
+
+    // taken from former test: tools/javac/options/release/ReleaseOptionClashes
+    @Test
+    public void releaseAndBootclasspath(Path base) throws Exception {
+        doTestNoSource(base, "error: option --boot-class-path cannot be used together with --release",
+                "--release 7 -bootclasspath any");
+        doTestNoSource(base, "error: option -Xbootclasspath: cannot be used together with --release",
+                "--release 7 -Xbootclasspath:any");
+        doTestNoSource(base, "error: option -Xbootclasspath/p: cannot be used together with --release",
+                "--release 7 -Xbootclasspath/p:any");
+        doTestNoSource(base, "error: option -endorseddirs cannot be used together with --release",
+                "--release 7 -endorseddirs any");
+        doTestNoSource(base, "error: option -extdirs cannot be used together with --release",
+                "--release 7 -extdirs any");
+        doTestNoSource(base, "error: option -source cannot be used together with --release",
+                "--release 7 -source 8");
+        doTestNoSource(base, "error: option -target cannot be used together with --release",
+                "--release 7 -target 8");
+        doTestNoSource(base, "error: option --system cannot be used together with --release",
+                "--release 9 --system none");
+        doTestNoSource(base, "error: option --upgrade-module-path cannot be used together with --release",
+                "--release 9 --upgrade-module-path any");
+    }
+
+    void doTest(Path base, String output, String options) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "class Dummy { }");
+        String log = new JavacTask(tb, Task.Mode.CMDLINE)
+                .spaceSeparatedOptions(options)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        Assert.check(log.startsWith(output), "expected:\n" + output + '\n' + "found:\n" + log);
+    }
+
+    void doTestNoSource(Path base, String output, String options) throws Exception {
+        String log = new JavacTask(tb, Task.Mode.CMDLINE)
+                .spaceSeparatedOptions(options)
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        Assert.check(log.startsWith(output), "expected:\n" + output + '\n' + "found:\n" + log);
+    }
+}
--- a/test/langtools/tools/javac/platform/PlatformProviderTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javac/platform/PlatformProviderTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -141,7 +141,7 @@
         List<String> expectedOutput =
                 Arrays.asList("getSupportedPlatformNames",
                               "getPlatform(fail, )",
-                              "javac: javac.err.unsupported.release.version",
+                              "error: release version fail not supported",
                               "javac.msg.usage");
         List<String> actualOutput = result.getOutputLines(Task.OutputKind.STDERR);
         result.writeAll();
--- a/test/langtools/tools/javadoc/BadOptionsTest.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/javadoc/BadOptionsTest.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - no value for --add-modules option");
+                "javadoc: error - error: no value for --add-modules option");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
@@ -122,7 +122,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - no value for --add-exports option");
+                "javadoc: error - error: no value for --add-exports option");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
@@ -135,7 +135,7 @@
                 .run(Task.Expect.FAIL)
                 .writeAll();
         checkFound(result.getOutput(Task.OutputKind.DIRECT),
-                "javadoc: error - bad value for --add-exports option");
+                "javadoc: error - error: bad value for --add-exports option: 'm/p'");
         checkNotFound(result, "Exception", "at jdk.javadoc/");
     }
 
--- a/test/langtools/tools/lib/toolbox/JavacTask.java	Tue Apr 24 10:17:23 2018 +0100
+++ b/test/langtools/tools/lib/toolbox/JavacTask.java	Tue Apr 24 10:20:22 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -179,6 +179,16 @@
 
     /**
      * Sets the options.
+     * @param spaceSeparatedOption the space separated options
+     * @return this task object
+     */
+    public JavacTask spaceSeparatedOptions(String spaceSeparatedOption) {
+        this.options = Arrays.asList(spaceSeparatedOption.split("\\s+"));
+        return this;
+    }
+
+    /**
+     * Sets the options.
      * @param options the options
      * @return this task object
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/nashorn/script/basic/JDK-8201466.js	Tue Apr 24 10:20:22 2018 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * 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-8201466: Nashorn: defineProperty setters/getters on prototype object ignored with numeric property names
+ *
+ * @test
+ * @run
+ */
+
+var z = {}, s = null, g = null;
+
+Object.defineProperty(z,'0', {
+    get:function(){ g = 2; return 1;},
+    set:function(v){ s = v;}
+});
+
+var x = Object.create(z);
+x[0] = 3;
+
+Assert.assertTrue(x[0] === 1);
+Assert.assertTrue(g === 2);
+Assert.assertTrue(s === 3);
+